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

# Crossmint

> Integrate RebelFi with Crossmint embedded wallets

This guide shows how to sign and submit RebelFi transactions using [Crossmint's Wallets SDK](https://docs.crossmint.com/wallets/quickstarts/client-side-wallets).

<Info>
  For Crossmint setup, API keys, and wallet creation, see the [Crossmint documentation](https://docs.crossmint.com/wallets/quickstarts/client-side-wallets).
</Info>

## Environment Requirements

Crossmint's SDK has different signer types with different environment requirements:

| Signer Type     | Environment                     | Use Case                    |
| --------------- | ------------------------------- | --------------------------- |
| Email / Passkey | Browser, React Native (WebView) | User-facing apps            |
| API Key         | Server (Node.js)                | Automated / custodial flows |
| External Wallet | Any                             | Delegated signing           |

<Warning>
  **Email and Passkey signers require a browser environment.** They use an iframe for TEE (Trusted Execution Environment) authentication. This won't work in Node.js tests or server-side code.
</Warning>

<Warning>
  **Important:** Never expose your RebelFi API key in client-side code. For React/browser integrations, proxy API calls through your backend server.
</Warning>

## Client-Side Flow (React / React Native)

For user-facing applications where users sign their own transactions:

```typescript theme={null}
import { RebelfiClient } from '@rebelfi/sdk';
import { SolanaWallet } from '@crossmint/wallets-sdk';
import type { Wallet } from '@crossmint/wallets-sdk';

const rebelfi = new RebelfiClient({ apiKey: process.env.REBELFI_API_KEY });

async function supplyWithCrossmint(
  walletAddress: string,
  strategyId: number,
  amount: string,
  tokenAddress: string,
  crossmintWallet: Wallet<'solana'>
) {
  // 1. Create supply operation (returns unsigned transaction)
  const operation = await rebelfi.operations.supply({
    walletAddress,
    strategyId,
    amount,
    tokenAddress,
  });

  // 2. Get the unsigned transaction (base64)
  const unsignedTx = operation.transactions[0].unsignedTransaction;

  // 3. Sign and broadcast via Crossmint
  const solanaWallet = SolanaWallet.from(crossmintWallet);
  const result = await solanaWallet.sendTransaction({
    serializedTransaction: unsignedTx,
  });

  // 4. Submit hash back to RebelFi
  await rebelfi.transactions.submitHash({
    operationId: operation.operationId,
    txHash: result.hash,
  });

  return {
    operationId: operation.operationId,
    txHash: result.hash,
  };
}
```

### React Native / Expo

Crossmint uses **WebView** to provide browser APIs in React Native. The SDK works the same way, but requires WebView-based components.

See [Crossmint's React Native SDK](https://docs.crossmint.com/wallets/quickstarts/react-native) for setup.

```typescript theme={null}
// The signing code is identical - WebView handles the browser environment
const result = await solanaWallet.sendTransaction({
  serializedTransaction: unsignedTx,
});
```

## Server-Side Flow (API Key Signer)

For automated or custodial flows where your server controls signing:

<Note>
  API Key signers are **custodial** — Crossmint signs transactions automatically without user interaction. Use this for treasury management or automated operations.
</Note>

```typescript theme={null}
import { RebelfiClient } from '@rebelfi/sdk';
import { CrossmintWallets, createCrossmint, SolanaWallet } from '@crossmint/wallets-sdk';

const rebelfi = new RebelfiClient({ apiKey: process.env.REBELFI_API_KEY });

// Initialize Crossmint with server API key
const crossmint = createCrossmint({
  apiKey: process.env.CROSSMINT_SERVER_API_KEY, // sk_...
});
const crossmintWallets = CrossmintWallets.from(crossmint);

async function automatedSupply(
  walletLocator: string, // e.g., "email:user@example.com:solana"
  strategyId: number,
  amount: string,
  tokenAddress: string
) {
  // 1. Get the Crossmint wallet
  const wallet = await crossmintWallets.getWallet(walletLocator, {
    chain: 'solana',
  });

  // 2. Create supply operation
  const operation = await rebelfi.operations.supply({
    walletAddress: wallet.address,
    strategyId,
    amount,
    tokenAddress,
  });

  // 3. Sign and broadcast (API key signer = automatic approval)
  const solanaWallet = SolanaWallet.from(wallet);
  const result = await solanaWallet.sendTransaction({
    serializedTransaction: operation.transactions[0].unsignedTransaction,
  });

  // 4. Submit hash back to RebelFi
  await rebelfi.transactions.submitHash({
    operationId: operation.operationId,
    txHash: result.hash,
  });

  return { operationId: operation.operationId, txHash: result.hash };
}
```

## Complete Example: Supply + Unwind

```typescript theme={null}
import { RebelfiClient } from '@rebelfi/sdk';
import { SolanaWallet } from '@crossmint/wallets-sdk';
import type { Wallet } from '@crossmint/wallets-sdk';

class CrossmintYieldService {
  constructor(
    private rebelfi: RebelfiClient,
    private crossmintWallet: Wallet<'solana'>
  ) {}

  private get solanaWallet() {
    return SolanaWallet.from(this.crossmintWallet);
  }

  private get walletAddress() {
    return this.crossmintWallet.address;
  }

  async supply(strategyId: number, amount: string, tokenAddress: string) {
    const operation = await this.rebelfi.operations.supply({
      walletAddress: this.walletAddress,
      strategyId,
      amount,
      tokenAddress,
    });

    const result = await this.solanaWallet.sendTransaction({
      serializedTransaction: operation.transactions[0].unsignedTransaction,
    });

    await this.rebelfi.transactions.submitHash({
      operationId: operation.operationId,
      txHash: result.hash,
    });

    return this.waitForConfirmation(operation.operationId);
  }

  async unwind(strategyId: number, amount: string) {
    const operation = await this.rebelfi.operations.unwind({
      walletAddress: this.walletAddress,
      strategyId,
      amount,
    });

    const result = await this.solanaWallet.sendTransaction({
      serializedTransaction: operation.transactions[0].unsignedTransaction,
    });

    await this.rebelfi.transactions.submitHash({
      operationId: operation.operationId,
      txHash: result.hash,
    });

    return this.waitForConfirmation(operation.operationId);
  }

  private async waitForConfirmation(operationId: number, timeoutMs = 60000) {
    const start = Date.now();
    while (Date.now() - start < timeoutMs) {
      const op = await this.rebelfi.operations.get(operationId);
      if (op.status === 'CONFIRMED') return op;
      if (op.status === 'FAILED') throw new Error(op.transactions[0]?.error);
      await new Promise((r) => setTimeout(r, 2000));
    }
    throw new Error('Timeout waiting for confirmation');
  }
}
```

<Info>
  Operation and transaction statuses are returned in UPPERCASE (e.g., `'CONFIRMED'`, `'FAILED'`).
</Info>

## Troubleshooting

<AccordionGroup>
  <Accordion title="window is not defined" icon="circle-exclamation">
    **Cause**: Using email/passkey signer in Node.js or server environment.

    **Solution**: Use API Key signer for server-side, or run in browser/WebView environment.
  </Accordion>

  <Accordion title="Transaction expired" icon="clock">
    **Cause**: Too much time between creating operation and signing.

    **Solution**: Sign and submit within 60 seconds of creating the operation.
  </Accordion>

  <Accordion title="Invalid signature" icon="key">
    **Cause**: Wrong wallet signing the transaction.

    **Solution**: Ensure the Crossmint wallet address matches the `walletAddress` passed to the operation.
  </Accordion>
</AccordionGroup>

## Resources

* [Crossmint Wallets SDK](https://docs.crossmint.com/wallets/quickstarts/client-side-wallets)
* [Crossmint React Native SDK](https://docs.crossmint.com/wallets/quickstarts/react-native)
* [Crossmint Signers & Custody](https://docs.crossmint.com/wallets/signers-and-custody)
* [RebelFi SDK Reference](/sdk/reference/client)
