> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crossmint.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Types and Utilities

> React functions, classes and types for React SDK reference for Crossmint offramp

## createCrossmintWalletSigner

```typescript theme={null}
function createCrossmintWalletSigner(wallet: Wallet<Chain>): EmbeddedOfframpPayer
```

Returns an `EmbeddedOfframpPayer` for a Crossmint wallet, such as the one `useWallet()` returns. It supports EVM and Solana wallets.
It throws a plain error when the deposit was prepared for another chain or another wallet. That error leaves the user on the confirming screen, so mount `CrossmintEmbeddedOfframp` only while this wallet has the same address and chain as the session's payer.

### Usage

```tsx theme={null}
import { createCrossmintWalletSigner, useWallet } from "@crossmint/client-sdk-react-ui";

export function useOfframpPayer() {
    const { wallet } = useWallet();
    return wallet != null ? createCrossmintWalletSigner(wallet) : null;
}
```

***

## OfframpSignatureRejectedError

```typescript theme={null}
class OfframpSignatureRejectedError extends Error
```

Throw it from a custom payer when the user declines the transaction and nothing was broadcast. The component reports `wallet-rejected` and lets the user confirm again.

### Usage

```typescript theme={null}
import { OfframpSignatureRejectedError, type EmbeddedOfframpPayer } from "@crossmint/client-sdk-react-ui";

// Your wallet code: sign and broadcast the transaction, and resolve with its transaction ID.
declare function sendWithYourWallet(tx: { serializedTransaction: string; chain: string; payerAddress: string }): Promise<string>;
// Your wallet code: true when the user declined the request in their wallet.
declare function isUserRejection(error: unknown): boolean;

export const payer: EmbeddedOfframpPayer = {
    async signAndSendTransaction(tx) {
        try {
            return await sendWithYourWallet(tx);
        } catch (error) {
            if (isUserRejection(error)) {
                throw new OfframpSignatureRejectedError("The user declined the transaction");
            }
            throw error;
        }
    },
};
```

> **Note:** A payer for an external wallet. Throw `OfframpSignatureRejectedError` only when the user declined and nothing was broadcast.

***

## EmbeddedOfframpCredentials

The `sessionId` and `clientSecret` that [Create Offramp Session](https://docs.crossmint.com/offramp/api-reference/create-offramp-session.md) returns. Create the session on your server.

***

## EmbeddedOfframpPayer

Signs and sends the deposit. Pass `createCrossmintWalletSigner(wallet)` for a Crossmint wallet, or your own object for an external wallet.

***

## OfframpStatus

```typescript theme={null}
type OfframpStatus =
    | "loading"
    | "entering-amount"
    | "selecting-bank"
    | "adding-bank"
    | "verifying-identity"
    | "identity-in-review"
    | "reviewing"
    | "awaiting-signature"
    | "confirming-deposit"
    | "completed"
    | "payout-completed"
    | "payout-failed"
    | "failed"
```

The step of the offramp flow, reported by `onStatusChange`. `orderId` can change during one withdrawal, so keep the latest.

***

## OfframpErrorReason

```typescript theme={null}
type OfframpErrorReason =
    | "invalid-credentials"
    | "invalid-configuration"
    | "session-spent"
    | "identity-verification-required"
    | "identity-verification-failed"
    | "wallet-ownership-required"
    | "bank-not-supported"
    | "bank-not-verified"
    | "bank-holder-mismatch"
    | "amount-too-low"
    | "amount-too-high"
    | "exact-payout-unsupported"
    | "insufficient-funds"
    | "wallet-rejected"
    | "payout-failed"
    | "provider-error"
    | "unknown"
```

Why `onError` fired. When `retriable` is `false`, the session cannot continue: unmount the component.
