> ## 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.

# Quickstart

> Install the SDK and make your first supply operation

## Prerequisites

* Node.js 18+ or Bun
* A RebelFi API key ([get one here](https://api.rebelfi.io/login))
* A wallet for testing (Ethereum, Polygon, Base, or Solana)

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install @rebelfi/sdk
  ```

  ```bash yarn theme={null}
  yarn add @rebelfi/sdk
  ```

  ```bash pnpm theme={null}
  pnpm add @rebelfi/sdk
  ```

  ```bash bun theme={null}
  bun add @rebelfi/sdk
  ```
</CodeGroup>

## Initialize the Client

<Tabs>
  <Tab title="Sandbox (Recommended for Testing)">
    ```typescript theme={null}
    import { RebelfiClient } from '@rebelfi/sdk';

    const client = new RebelfiClient({
      apiKey: 'rfk_sandbox_xxxxxxxxxxxxx',
      sandbox: true
    });
    ```
  </Tab>

  <Tab title="Production">
    ```typescript theme={null}
    import { RebelfiClient } from '@rebelfi/sdk';

    const client = new RebelfiClient({
      apiKey: process.env.REBELFI_API_KEY
    });
    ```
  </Tab>
</Tabs>

<Info>
  Store your API key securely. Never commit it to version control or expose it in client-side code. See the [Sandbox guide](/guides/sandbox) for testing setup.
</Info>

## Register a Wallet

Before supplying, register the user's wallet:

```typescript theme={null}
const wallet = await client.wallets.register({
  walletAddress: '0xYourEthereumAddress', // or Solana address
  blockchain: 'ethereum',                 // 'ethereum', 'polygon', 'base', or 'solana'
  userId: 'your-internal-user-id'          // optional
});

console.log('Wallet ID:', wallet.walletId);
```

Registration is idempotent — calling it again returns the existing wallet.

## List Available Venues

Query available yield venues and their strategies:

```typescript theme={null}
const { venues } = await client.venues.list({
  blockchain: 'ethereum', // or 'polygon', 'base', 'solana'
  token: 'USDC'
});

console.log(`Found ${venues.length} venues`);

for (const venue of venues) {
  console.log(`\n${venue.name} (${venue.protocol})`);
  for (const strategy of venue.strategies) {
    console.log(`  ${strategy.name}: ${(strategy.apy * 100).toFixed(2)}% APY`);
  }
}
```

Example output:

```
Found 4 venues

AAVE V3 (aave-v3)
  USDC Lending: 5.20% APY

Morpho (morpho)
  USDC Vault: 6.80% APY

Kamino (kamino)
  USDC Vault: 8.50% APY

Drift (drift)
  USDC Lending: 7.20% APY
```

## Plan a Supply Operation

Select a strategy and plan a supply operation:

```typescript theme={null}
// Pick a strategy
const venue = venues[0];
const strategy = venue.strategies[0];

// Plan the supply operation
const operation = await client.operations.supply({
  walletAddress: wallet.walletAddress,
  strategyId: strategy.strategyId,
  amount: '1000000',  // 1 USDC (6 decimals)
  tokenAddress: strategy.tokenAddress
});

console.log('Operation ID:', operation.operationId);
console.log('Status:', operation.status);
console.log('Expires at:', operation.expiresAt);

// Get the unsigned transaction
const tx = operation.transactions[0];
console.log('Transaction to sign:', tx.unsignedTransaction);
```

<Warning>
  Operations expire after a short time (typically 5 minutes). Make sure to sign and submit promptly.
</Warning>

## Sign and Submit

After the user signs the transaction:

```typescript theme={null}
// Option 1: You broadcast the transaction and submit the hash
// broadcastTransaction is your own function (e.g., using @solana/web3.js or ethers.js)
const txHash = await broadcastTransaction(signedTx);

await client.transactions.submitHash({
  operationId: operation.operationId,
  txHash
});

// Option 2: Let RebelFi broadcast for you
await client.transactions.submitSigned({
  operationId: operation.operationId,
  signedTransaction: signedTxBase64
});
```

## Check Operation Status

Poll for confirmation:

```typescript theme={null}
const checkStatus = async (operationId: number) => {
  const op = await client.operations.get(operationId);
  console.log(`Status: ${op.status}`);

  if (op.status === 'CONFIRMED') {
    console.log('Supply confirmed!');
    return true;
  }

  if (op.status === 'FAILED') {
    const tx = op.transactions[0];
    console.error('Failed:', tx.error);
    return false;
  }

  if (op.status === 'CANCELLED') {
    console.log('Operation was cancelled');
    return false;
  }

  return null; // Still pending
};

// Poll every 2 seconds
const pollInterval = setInterval(async () => {
  const result = await checkStatus(operation.operationId);
  if (result !== null) {
    clearInterval(pollInterval);
  }
}, 2000);
```

## View Allocations

After supply is confirmed, check the allocation:

```typescript theme={null}
const { allocations, totalValue, totalYieldEarned } = await client.allocations.list({
  walletAddress: wallet.walletAddress
});

console.log(`Total value: ${totalValue}`);
console.log(`Total yield earned: ${totalYieldEarned}`);

for (const allocation of allocations) {
  console.log(`\n${allocation.venueName} - ${allocation.strategyName}`);
  console.log(`  Principal: ${allocation.principal}`);
  console.log(`  Current value: ${allocation.currentValue}`);
  console.log(`  Yield earned: ${allocation.yieldEarned}`);
}
```

## Complete Example

```typescript theme={null}
import { RebelfiClient, RebelfiError, ErrorCode } from '@rebelfi/sdk';

async function supplyToYield(walletAddress: string, amount: string) {
  const client = new RebelfiClient({
    apiKey: process.env.REBELFI_API_KEY
  });

  try {
    // 1. Find a strategy
    const { venues } = await client.venues.list({
      blockchain: 'ethereum', // or 'polygon', 'base', 'solana'
      token: 'USDC'
    });

    if (venues.length === 0) {
      throw new Error('No venues available');
    }

    const strategy = venues[0].strategies[0];
    console.log(`Using ${venues[0].name} - ${strategy.name}`);

    // 2. Register wallet & plan supply
    const wallet = await client.wallets.register({
      walletAddress,
      blockchain: 'ethereum' // or 'polygon', 'base', 'solana'
    });

    const operation = await client.operations.supply({
      walletAddress,
      strategyId: strategy.strategyId,
      amount,
      tokenAddress: strategy.tokenAddress
    });

    console.log(`Operation ${operation.operationId} created`);

    // 3. Return unsigned transaction for signing
    return {
      operationId: operation.operationId,
      unsignedTransaction: operation.transactions[0].unsignedTransaction,
      expiresAt: operation.expiresAt
    };
  } catch (error) {
    if (error instanceof RebelfiError) {
      if (error.is(ErrorCode.INSUFFICIENT_BALANCE)) {
        console.error('Wallet has insufficient balance');
      } else if (error.is(ErrorCode.STRATEGY_NOT_ACTIVE)) {
        console.error('Strategy is currently paused');
      } else {
        console.error(`API error: ${error.message} (${error.code})`);
      }
    }
    throw error;
  }
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Full Walkthrough" icon="route" href="/sdk/walkthrough">
    Complete integration walkthrough
  </Card>

  <Card title="Error Handling" icon="triangle-exclamation" href="/sdk/error-handling">
    Handle errors gracefully
  </Card>
</CardGroup>
