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

# Stake2Earn TypeScript SDK Getting Started

> Learn how to install @meteora-ag/m3m3, create a Stake2Earn client, read vault state, build staking transactions, and handle claim and unstake flows.

The Stake2Earn TypeScript SDK is published as `@meteora-ag/m3m3`. It wraps the `stake_for_fee`, DAMM v1, and Dynamic Vault account bundles needed to build Stake2Earn transactions.

<Note>
  The SDK builds unsigned transactions. Your app is responsible for setting any wallet-specific signing flow, simulating, signing, and submitting the returned transaction.
</Note>

<CardGroup cols={2}>
  <Card title="SDK Repository" icon="node-js" iconType="solid" href="https://github.com/MeteoraAg/stake-for-fee-sdk/tree/main/ts-client">
    Source for `@meteora-ag/m3m3`, examples, tests, IDLs, helpers, and build scripts.
  </Card>

  <Card title="NPM Package" icon="npm" iconType="solid" href="https://www.npmjs.com/package/@meteora-ag/m3m3">
    Published Stake2Earn TypeScript SDK package.
  </Card>
</CardGroup>

## Installation

Install the SDK and the packages you commonly import directly in app code:

<Tabs>
  <Tab title="npm">
    ```bash theme={"system"}
    npm install @meteora-ag/m3m3 @solana/web3.js @solana/spl-token bn.js
    ```
  </Tab>

  <Tab title="pnpm">
    ```bash theme={"system"}
    pnpm install @meteora-ag/m3m3 @solana/web3.js @solana/spl-token bn.js
    ```
  </Tab>

  <Tab title="yarn">
    ```bash theme={"system"}
    yarn add @meteora-ag/m3m3 @solana/web3.js @solana/spl-token bn.js
    ```
  </Tab>
</Tabs>

## Create A Client

Create a `StakeForFee` instance from a DAMM v1 pool address. The SDK derives the Stake2Earn vault PDA, top staker list, full balance list, lock escrow, and related Dynamic Vault state.

```typescript theme={"system"}
import StakeForFee from "@meteora-ag/m3m3";
import { Connection, PublicKey } from "@solana/web3.js";

const connection = new Connection(process.env.RPC_URL!, "confirmed");

const poolAddress = new PublicKey(
  "G2MRSjNjCbFUmMf32Z1aXYhy6pc1ihLyYg6orKedyjJG",
);

const stakeForFee = await StakeForFee.create(connection, poolAddress);

console.log(stakeForFee.feeVaultKey.toBase58());
console.log(stakeForFee.accountStates.feeVault.configuration);
```

## Build Transactions

### Stake

`stake` creates the stake escrow first when it does not exist, estimates compute units, and adds replacement top-list accounts from the current cached state.

```typescript theme={"system"}
import BN from "bn.js";

const amount = new BN("1000000000");
const tx = await stakeForFee.stake(amount, wallet.publicKey);
```

### Claim Fees

`claimFee` transfers only the quote token side to the user. The stake/base token side is automatically restaked by the program.

```typescript theme={"system"}
import { U64_MAX } from "@meteora-ag/m3m3";

const tx = await stakeForFee.claimFee(wallet.publicKey, U64_MAX);
```

### Request Unstake

`unstake` initializes a new `Unstake` account. The new keypair must sign the final transaction.

```typescript theme={"system"}
import { Keypair } from "@solana/web3.js";

const unstakeKeypair = Keypair.generate();
const tx = await stakeForFee.unstake(
  amount,
  unstakeKeypair.publicKey,
  wallet.publicKey,
);

tx.partialSign(unstakeKeypair);
```

### Cancel Or Withdraw

```typescript theme={"system"}
const cancelTx = await stakeForFee.cancelUnstake(
  unstakeKeypair.publicKey,
  wallet.publicKey,
);

const withdrawTx = await stakeForFee.withdraw(
  unstakeKeypair.publicKey,
  wallet.publicKey,
);
```

`withdraw` only succeeds after the `Unstake.release_at` timestamp has passed.

## Read User State

Refresh cached vault state before calculating claimable balances for a user-facing surface.

```typescript theme={"system"}
await stakeForFee.refreshStates();

const userState = await stakeForFee.getUserStakeAndClaimBalance(
  wallet.publicKey,
);

if (userState.stakeEscrow) {
  console.log(userState.stakeEscrow.stakeAmount.toString());
  console.log(userState.unclaimFee.feeA?.toString());
  console.log(userState.unclaimFee.feeB?.toString());
}
```

## Create A Vault

Vault creation is an integrator or launch workflow. The pool must be a DAMM v1 constant-product pool, the quote mint must be SOL or USDC, and the lock escrow must be owned by the derived vault PDA.

```typescript theme={"system"}
import StakeForFee from "@meteora-ag/m3m3";
import { PublicKey } from "@solana/web3.js";
import BN from "bn.js";

const tx = await StakeForFee.createFeeVault(
  connection,
  poolAddress,
  stakeMint,
  payer.publicKey,
  {
    topListLength: 10,
    unstakeLockDuration: new BN(86_400),
    secondsToFullUnlock: new BN(604_800),
    startFeeDistributeTimestamp: new BN(startTimestamp),
  },
);
```

The SDK also exposes `createFeeVaultWithParams` and `createFeeVaultInstructions` when you already know both pool mints or need raw instructions.

## Contributor Commands

If you have cloned the SDK repository and want to run the built-in tests:

```bash theme={"system"}
cd stake-for-fee-sdk/ts-client
pnpm install
pnpm run build
pnpm test
```

## Next Pages

<CardGroup cols={2}>
  <Card title="SDK Examples" icon="code" iconType="solid" href="/developer-guides/stake2earn/typescript-sdk/examples">
    Common vault, stake, claim, unstake, and read examples.
  </Card>

  <Card title="SDK Reference" icon="book" iconType="solid" href="/developer-guides/stake2earn/typescript-sdk/reference">
    Complete function, helper, constant, and type map for `@meteora-ag/m3m3`.
  </Card>
</CardGroup>
