npm package: @solayer-labs/bridge-sdk
Description: TypeScript SDK for the Bridge Program
Latest version: 0.2.7

# Bridge SDK

A TypeScript SDK for interacting with the Solayer Bridge Program, enabling cross-chain asset transfers between Solana and Solayer networks.

## Features

- 🔗 **Cross-chain bridging** between Solana and Solayer
- 🪙 **SPL Token support** for bridging any SPL tokens
- 💰 **Native SOL bridging** support
- 🔍 **Bridge proof tracking** and verification
- 🛡️ **Guardian signature verification** for security
- 📊 **Token binding mapping** between chains with automatic tokenInfo inclusion
- 🚀 **Easy-to-use client interface**
- 🛠️ **Robust error handling** and validation
- 📋 **Transaction creation helpers** for custom workflows

## Installation

```bash
npm install @solayer-labs/bridge-sdk
# or
yarn add @solayer-labs/bridge-sdk
```

## Quick Start

### Basic Setup

```typescript
import { BridgeClient, Chain } from "@solayer-labs/bridge-sdk";
import { Connection, Keypair } from "@solana/web3.js";
import * as anchor from "@coral-xyz/anchor";

// Initialize connections
const solanaConnection = new Connection("https://api.devnet.solana.com");
const solayerConnection = new Connection("https://rpc.devnet.solayer.com");

// Create user keypair
const userKeypair = Keypair.generate();
const bridgeClient = new BridgeClient({
  connection: solanaConnection,
  userPublicKey: userKeypair.publicKey,
  chain: Chain.Solana,
  commitment: "confirmed",
});
```

### Bridge SPL Tokens

```typescript
import { BridgeAssetSourceChainParams } from "@solayer-labs/bridge-sdk";
import { PublicKey } from "@solana/web3.js";
import * as anchor from "@coral-xyz/anchor";

// Bridge parameters
const params: BridgeAssetSourceChainParams = {
  bridgeProofNonce: new anchor.BN(Date.now()),
  amount: new anchor.BN(1000000000), // 1 token with 9 decimals
  recipient: new PublicKey("recipient_public_key_here"),
  additionalSolGas: new anchor.BN(0),
};

// Account information
const accounts = {
  mint: new PublicKey("token_mint_address"),
  signerVault: new PublicKey("your_token_account"),
};

// Create and send bridge transaction
const transaction = await bridgeClient.createBridgeAssetSourceChainTransaction(
  params,
  accounts
);
// You need to sign and send the transaction yourself
// const signature = await sendAndConfirmTransaction(connection, transaction, [userKeypair]);
console.log("Bridge transaction created:", transaction);

// The transaction now includes the tokenInfo field for cross-chain token mapping
```

### Bridge Native SOL

```typescript
import { BridgeAssetSourceChainSolParams } from "@solayer-labs/bridge-sdk";
import { PublicKey } from "@solana/web3.js";
import * as anchor from "@coral-xyz/anchor";

// Bridge SOL parameters
const params: BridgeAssetSourceChainSolParams = {
  bridgeProofNonce: new anchor.BN(Date.now()),
  amount: new anchor.BN(5000000), // 0.005 SOL
  recipient: new PublicKey("recipient_public_key_here"),
};

// Create SOL bridge transaction
const transaction =
  await bridgeClient.createBridgeAssetSourceChainSolTransaction(params);
// You need to sign and send the transaction yourself
// const signature = await sendAndConfirmTransaction(connection, transaction, [userKeypair]);
console.log("SOL bridge transaction created:", transaction);
```

## API Reference

### BridgeClient

The main client class for interacting with the bridge program.

#### Constructor

```typescript
new BridgeClient(config: BridgeClientConfig)
```

**Config Options:**

- `connection`: Solana connection instance
- `userPublicKey`: User's public key for transactions
- `chain`: Target chain (Solana or Solayer)
- `programId?`: Optional custom program ID
- `commitment?`: RPC commitment level

#### Methods

**Note:** The BridgeClient only creates transactions - you need to sign and send them yourself using `sendAndConfirmTransaction` or similar methods.

##### `getBridgeHandler(chain)`

Fetches bridge handler account information.

**Parameters:**

- `chain`: Chain enum (Solana or Solayer)

**Returns:** Bridge handler account data

##### `getSourceChainBridgeProof(bridgeHandler, signer, bridgeProofNonce)`

Fetches source chain bridge proof account.

**Parameters:**

- `bridgeHandler`: Bridge handler PublicKey
- `signer`: Signer PublicKey
- `bridgeProofNonce`: Bridge proof nonce

**Returns:** Source chain bridge proof account data

##### `getSourceChainBridgeProofByAccount(account)`

Fetches source chain bridge proof by account address.

**Parameters:**

- `account`: Bridge proof account PublicKey

**Returns:** Source chain bridge proof account data

##### `getDestinationChainBridgeProof(bridgeHandler, sourceTxId)`

Fetches destination chain bridge proof account.

**Parameters:**

- `bridgeHandler`: Bridge handler PublicKey
- `sourceTxId`: Source transaction ID

**Returns:** Destination chain bridge proof account data

##### `getDestinationChainBridgeProofByAccount(account)`

Fetches destination chain bridge proof by account address.

**Parameters:**

- `account`: Bridge proof account PublicKey

**Returns:** Destination chain bridge proof account data

##### `getBridgeHandlerVaultPDA(bridgeHandler, mint)`

Gets the bridge handler vault PDA for a mint.

**Parameters:**

- `bridgeHandler`: Bridge handler PublicKey
- `mint`: Token mint PublicKey

**Returns:** Bridge handler vault PDA

##### `createBridgeAssetSourceChainTransaction(params, accounts)`

Creates a bridge transaction without sending it, allowing for custom signing and sending. The method automatically determines the target chain mint address using the `get_target_mint` utility function and includes the `tokenInfo` field for token mapping between chains.

**Parameters:**

- `params`: BridgeAssetSourceChainParams
- `accounts`: Object containing mint and signerVault PublicKeys

**Returns:** Promise<Transaction>

##### `createBridgeAssetSourceChainSolTransaction(params)`

Creates a SOL bridge transaction without sending it, allowing for custom signing and sending.

**Parameters:**

- `params`: BridgeAssetSourceChainSolParams

**Returns:** Promise<Transaction>

### Utility Functions

#### `getBridgeHandlerPDA(chain)`

Gets the Program Derived Address (PDA) for bridge handler.

**Parameters:**

- `chain`: Chain enum

**Returns:** [PublicKey, number] tuple

#### `getSourceChainBridgeProofPDA(bridgeHandler, signer, bridgeProofNonce)`

Gets the PDA for source chain bridge proof.

**Parameters:**

- `bridgeHandler`: Bridge handler PublicKey
- `signer`: Signer PublicKey
- `bridgeProofNonce`: Bridge proof nonce

**Returns:** [PublicKey, number] tuple

#### `getDestinationChainBridgeProofPDA(bridgeHandler, sourceTxId)`

Gets the PDA for destination chain bridge proof.

**Parameters:**

- `bridgeHandler`: Bridge handler PublicKey
- `sourceTxId`: Source transaction ID

**Returns:** [PublicKey, number] tuple

#### `calculateTargetChainBridgedMintAddress(sourceMint, bridgeHandler)`

Calculates the target chain bridged mint address for a source mint.

**Parameters:**

- `sourceMint`: Source chain mint PublicKey
- `bridgeHandler`: Bridge handler PublicKey

**Returns:** Target chain bridged mint PublicKey

#### `calculateTokenInfoAddress(mint, bridgeHandler)`

Calculates the token info PDA address for a given mint.

**Parameters:**

- `mint`: Token mint PublicKey
- `bridgeHandler`: Bridge handler PublicKey

**Returns:** Token info PDA PublicKey

#### `is_mint_bridged_token(connection, bridgeHandler, mint)`

Checks if a mint is a bridged token by verifying its owner.

**Parameters:**

- `connection`: Solana connection instance
- `bridgeHandler`: Bridge handler PublicKey
- `mint`: Token mint PublicKey to check

**Returns:** Promise<boolean> - true if the mint is a bridged token

#### `get_target_mint(sourceChain, sourceChainConnection, bridgeHandler, sourceMint)`

Gets the target chain mint address for a given source mint, handling both bridged and native tokens.

**Parameters:**

- `sourceChain`: Source chain enum (Solana or Solayer)
- `sourceChainConnection`: Source chain RPC connection
- `bridgeHandler`: Bridge handler PublicKey
- `sourceMint`: Source chain mint PublicKey

**Returns:** Promise<PublicKey> - Target chain mint address

#### `getTargetChainBridgeTxIdFromSourceTxId(sourceTxId, sourceChain, targetChainConnection)`

Gets target chain bridge transaction ID from source transaction ID.

**Parameters:**

- `sourceTxId`: Source transaction ID
- `sourceChain`: Source chain enum
- `targetChainConnection`: Target chain RPC connection

**Returns:** Promise<string | null>

#### `getSourceChainBridgeTxIdFromTargetChainBridgeProof(bridgeProofKey, targetChainConnection)`

Gets source chain bridge transaction ID from target chain bridge proof.

**Parameters:**

- `bridgeProofKey`: Target chain bridge proof PublicKey
- `targetChainConnection`: Target chain RPC connection

**Returns:** Promise<string | null>

#### `getUserBridgeTx(connection, user, bridgeHandler)`

Gets all bridge transactions for a specific user.

**Parameters:**

- `connection`: RPC connection
- `user`: User PublicKey
- `bridgeHandler`: Bridge handler PublicKey

**Returns:** Promise<UserBridgeTx>

## Types

### BridgeAssetSourceChainParams

```typescript
interface BridgeAssetSourceChainParams {
  bridgeProofNonce: anchor.BN;
  amount: anchor.BN;
  recipient: PublicKey;
  additionalSolGas: anchor.BN;
}
```

### BridgeAssetSourceChainSolParams

```typescript
interface BridgeAssetSourceChainSolParams {
  bridgeProofNonce: anchor.BN;
  amount: anchor.BN;
  recipient: PublicKey;
}
```

### BridgeClientConfig

```typescript
interface BridgeClientConfig {
  connection: Connection;
  userPublicKey: PublicKey;
  chain: Chain;
  programId?: PublicKey;
  commitment?: anchor.web3.Commitment;
}
```

### UserBridgeTx

```typescript
interface UserBridgeTx {
  sourceChainBridgeTx: string[];
  targetChainBridgeTx: string[];
}
```

### Chain Enum

```typescript
enum Chain {
  Solana = 1,
  Solayer = 2,
}
```

### Exported Types

These types are exported from the SDK and represent the program account structures:

```typescript
export type BridgeHandler = BridgeProgram["accounts"][0];
export type BridgeProof = BridgeProgram["accounts"][1];
export type BridgeProofSourceChain = BridgeProgram["accounts"][2];
export type TokenInfo = BridgeProgram["types"][0];
```

- `BridgeHandler`: Bridge handler account structure
- `BridgeProof`: Bridge proof account structure for destination chain
- `BridgeProofSourceChain`: Bridge proof account structure for source chain
- `TokenInfo`: Token information structure containing mint addresses and status (automatically included in bridge transactions)

## Examples

### Complete Bridge Workflow

```typescript
import {
  BridgeClient,
  Chain,
  BridgeAssetSourceChainParams,
  getBridgeHandlerPDA,
} from "@solayer-labs/bridge-sdk";
import {
  Connection,
  Keypair,
  PublicKey,
  sendAndConfirmTransaction,
} from "@solana/web3.js";
import * as anchor from "@coral-xyz/anchor";

async function bridgeTokens() {
  // Setup connections
  const solanaConnection = new Connection("https://api.devnet.solana.com");

  // Initialize client
  const userKeypair = Keypair.generate();
  const bridgeClient = new BridgeClient({
    connection: solanaConnection,
    userPublicKey: userKeypair.publicKey,
    chain: Chain.Solana,
    commitment: "confirmed",
  });

  // Bridge parameters
  const params: BridgeAssetSourceChainParams = {
    bridgeProofNonce: new anchor.BN(Date.now()),
    amount: new anchor.BN(1000000000), // 1 token
    recipient: new PublicKey("recipient_address"),
    additionalSolGas: new anchor.BN(0),
  };

  const accounts = {
    mint: new PublicKey("token_mint"),
    signerVault: new PublicKey("your_token_account"),
  };

  try {
    // Create bridge transaction
    const transaction =
      await bridgeClient.createBridgeAssetSourceChainTransaction(
        params,
        accounts
      );

    // The transaction now includes tokenInfo for cross-chain token mapping
    // Sign and send transaction (you need to implement this)
    const signature = await sendAndConfirmTransaction(
      solanaConnection,
      transaction,
      [userKeypair]
    );
    console.log("Bridge successful:", signature);

    // Get bridge proof
    const [bridgeHandler] = getBridgeHandlerPDA(Chain.Solana);
    const bridgeProof = await bridgeClient.getSourceChainBridgeProof(
      bridgeHandler,
      userKeypair.publicKey,
      params.bridgeProofNonce
    );
    console.log("Bridge proof:", bridgeProof);
  } catch (error) {
    console.error("Bridge failed:", error);
  }
}
```

### SOL Bridge Workflow

```typescript
import {
  BridgeClient,
  Chain,
  BridgeAssetSourceChainSolParams,
} from "@solayer-labs/bridge-sdk";
import {
  Connection,
  Keypair,
  PublicKey,
  sendAndConfirmTransaction,
} from "@solana/web3.js";
import * as anchor from "@coral-xyz/anchor";

async function bridgeSOL() {
  const userKeypair = Keypair.generate();
  const bridgeClient = new BridgeClient({
    connection: new Connection("https://api.devnet.solana.com"),
    userPublicKey: userKeypair.publicKey,
    chain: Chain.Solana,
  });

  const params: BridgeAssetSourceChainSolParams = {
    bridgeProofNonce: new anchor.BN(Date.now()),
    amount: new anchor.BN(5000000), // 0.005 SOL
    recipient: new PublicKey("recipient_address"),
  };

  try {
    const transaction =
      await bridgeClient.createBridgeAssetSourceChainSolTransaction(params);

    // Sign and send transaction (you need to implement this)
    const signature = await sendAndConfirmTransaction(
      new Connection("https://api.devnet.solana.com"),
      transaction,
      [userKeypair]
    );
    console.log("SOL bridge initiated:", signature);
  } catch (error) {
    console.error("SOL bridge failed:", error);
  }
}
```

### Track Bridge Status

```typescript
import {
  getTargetChainBridgeTxIdFromSourceTxId,
  Chain,
} from "@solayer-labs/bridge-sdk";
import { Connection } from "@solana/web3.js";

async function trackBridgeStatus(sourceTxId: string) {
  const solayerConnection = new Connection("https://rpc.devnet.solayer.com");

  // Get target chain transaction ID
  const targetTxId = await getTargetChainBridgeTxIdFromSourceTxId(
    sourceTxId,
    Chain.Solana,
    solayerConnection
  );

  if (targetTxId) {
    console.log("Bridge completed on target chain:", targetTxId);
  } else {
    console.log("Bridge still pending on target chain");
  }
}
```

### Get User Bridge Transactions

```typescript
import {
  getUserBridgeTx,
  getBridgeHandlerPDA,
  Chain,
} from "@solayer-labs/bridge-sdk";
import { Connection, PublicKey } from "@solana/web3.js";

async function getUserTransactions() {
  const connection = new Connection("https://api.devnet.solana.com");
  const user = new PublicKey("user_public_key");
  const [bridgeHandler] = getBridgeHandlerPDA(Chain.Solana);

  const userTxs = await getUserBridgeTx(connection, user, bridgeHandler);

  console.log("Source chain transactions:", userTxs.sourceChainBridgeTx);
  console.log("Target chain transactions:", userTxs.targetChainBridgeTx);
}
```

### Create Custom Bridge Transaction

```typescript
import {
  BridgeClient,
  Chain,
  BridgeAssetSourceChainParams,
} from "@solayer-labs/bridge-sdk";
import {
  Connection,
  Keypair,
  PublicKey,
  sendAndConfirmTransaction,
} from "@solana/web3.js";
import * as anchor from "@coral-xyz/anchor";

async function createCustomBridgeTransaction() {
  const connection = new Connection("https://api.devnet.solana.com");
  const userKeypair = Keypair.generate();

  const bridgeClient = new BridgeClient({
    connection,
    userPublicKey: userKeypair.publicKey,
    chain: Chain.Solana,
  });

  const params: BridgeAssetSourceChainParams = {
    bridgeProofNonce: new anchor.BN(Date.now()),
    amount: new anchor.BN(1000000000),
    recipient: new PublicKey("recipient_address"),
    additionalSolGas: new anchor.BN(0),
  };

  const accounts = {
    mint: new PublicKey("token_mint"),
    signerVault: new PublicKey("your_token_account"),
  };

  // Create transaction without sending
  const transaction =
    await bridgeClient.createBridgeAssetSourceChainTransaction(
      params,
      accounts
    );

  // The transaction now includes tokenInfo for cross-chain token mapping
  // Add custom instructions if needed
  // transaction.add(customInstruction);

  // Sign and send manually
  const signature = await sendAndConfirmTransaction(connection, transaction, [
    userKeypair,
  ]);

  console.log("Custom bridge transaction:", signature);
}
```

## Development

### Building

```bash
# Install dependencies
yarn install

# Build the SDK
yarn build

# Development mode with watch
yarn dev
```

### Testing

```bash
# Run tests
yarn test

# Run tests with coverage
yarn test:coverage
```

## Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request

## License

MIT License - see LICENSE file for details

## Support

- 📖 [Documentation](https://docs.solayer.com)
- 💬 [Discord](https://discord.gg/solayer)
- 🐛 [Issues](https://github.com/solayer-labs/bridge-sdk/issues)
- 📧 [Email](mailto:support@solayer.com)