@starkware-industries/starkgate-sdk
TypeScript icon, indicating that this package has built-in type declarations

1.1.0 • Public • Published

BridgeSDK

BridgeSDK is a TypeScript library for managing cross-chain token transfers between Ethereum and Starknet networks. It supports multiple token bridges and provides an interface for deposits, withdrawals, and balance checks.

Features

  • Support for multiple tokens and bridges
  • Easy configuration for different networks
  • Deposit and withdraw tokens between Ethereum and Starknet
  • Balance checks for available deposits and withdrawals

Installation

Install BridgeSDK using npm:

npm install @starkware-industries/starkgate-sdk

Usage

Creating an Instance of BridgeSDK

To create an instance of BridgeSDK, use the create method:

import {BridgeSDK, BridgeSDKConfig} from '@starkware-industries/starkgate-sdk';

const config: BridgeSDKConfig = {
  network: 'main',
  ethereum: {
    provider: yourEthereumProvider,
    signer: yourEthereumSigner
  },
  starknet: {
    provider: yourStarknetProvider,
    account: yourStarknetAccount
  },
  debug: true
};

const bridgeSDK = await BridgeSDK.create(config);

Configuration

BridgeSDKConfig

  • debug: A boolean flag to enable debug mode. Default is false.
  • network: The network to use, either 'sepolia' or 'main'.
  • ethereum: An optional object containing the Ethereum provider (JsonRpcProvider) and signer(JsonRpcSigner).
  • starknet: An optional object containing the Starknet provider (RpcProvider) and account (Account).

Setting Signers and Providers

You can update the Ethereum signer or Starknet provider/account after the SDK has been initialized:

bridgeSDK.setEthereumSigner(newSigner);
bridgeSDK.setEthereumProvider(newProvider);
bridgeSDK.setStarknetProvider(newProvider);
bridgeSDK.setStarknetAccount(newAccount);

Getting the supported bridges

import {BridgeToken} from '@starkware-industries/starkgate-sdk';

const bridges: BridgeToken = bridgeSDK.getBridgeTokens();

Performing Operations

Deposit

import {StarknetAddress, TokenIdentifier} from '@starkware-industries/starkgate-sdk';

const tokenId: TokenIdentifier = 'strk';
const amount = '150';
const l2Recipient: StarknetAddress = '0x...';

await bridgeSDK.deposit(tokenId, amount, l2Recipient);

Withdraw

import {EthereumAddress, TokenIdentifier} from '@starkware-industries/starkgate-sdk';

const tokenId: TokenIdentifier = 'strk';
const amount = '10';
const recipient: EthereumAddress = '0x...';

await bridgeSDK.withdraw(tokenId, amount, recipient);

Initiate Withdraw

import {EthereumAddress, TokenIdentifier} from '@starkware-industries/starkgate-sdk';

const tokenId: TokenIdentifier = 'strk';
const l1Recipient: EthereumAddress = '0x...';
const amount = '0.5';

await bridgeSDK.initiateWithdraw(tokenId, l1Recipient, amount);

Initiate Auto Withdraw

import {EthereumAddress, TokenIdentifier} from '@starkware-industries/starkgate-sdk';

const tokenId: TokenIdentifier = 'strk';
const l1Recipient: EthereumAddress = '0x...';
const amount = '0.5';
const autoWithdrawConfig = {
  preferredFeeToken: '0x...' // The L2 address of the preferred token to be used for fees. If the user has a balance in this token, it will be used. Otherwise, the fee will be paid in another available token.
};

await bridgeSDK.initiateWithdraw(tokenId, l1Recipient, amount, autoWithdrawConfig);

Balance Checks

import {
  EthereumAddress,
  StarknetAddress,
  TokenIdentifier
} from '@starkware-industries/starkgate-sdk';

const tokenId: TokenIdentifier = 'strk';
const account: EthereumAddress = '0x...';
const starknetAccount: StarknetAddress = '0x...';

const availableDepositBalance = await bridgeSDK.getAvailableDepositBalance(token, account);
const availableWithdrawBalance = await bridgeSDK.getAvailableWithdrawBalance(
  tokenId,
  starknetAccount
);

Fee Estimation

Run these functions to get a fee estimation on the following flows:

Deposit

You must have more than 0 of the selected token in the connected l1 wallet to get an estimate of the deposit.

// built into library
type DepositFeeEstimation = {
  l1Fee: L1FeeAmount;
  l2Fee: string;
  l2FeeUnit: SnFeeUnit;
};

const tokenId: TokenIdentifier = 'strk';

const depositEstimate: DepositFeeEstimation = await bridgeSDK.getDepositFeeEstimate(tokenId);

Initiate Withdraw

You must have more than 0 of the selected token in the connected l2 wallet to get an estimate of the withdrawal. This function contains two optional fields, autoWithdrawConfig and preferredL2FeeToken. Should you want to get the fees to perform an auto withdrawal, you will need to provide autoWithdrawConfig, otherwise the parameter defaults to undefined. By default, the l2 fees will be returned as STRK in accordance with V3 starknet transaction standards. Should you want to receive the Fees in ETH, you will need to pass the string "ETH" to the preferredL2FeeToken parameter.

Should you try to estimate initiate withdraw using a non-deployed wallet, you will get an error in the l2FeeError field and the l2Fee will return as 0.

// built into library
type InitiateWithdrawalFeeEstimation = {
  l2Fee: string;
  feeUnit: SnFeeUnit;
  autoWithdrawCostMap?: Record<SnFeeUnit, string>;
  l2FeeError?: string;
};

type AutoWithdrawConfig = {
  preferredFeeToken: StarknetAddress;
};

const tokenId: TokenIdentifier = 'strk';
const autoWithdrawConfig = {
  preferredFeeToken: '0x...'
};

const depositEstimate: InitiateWithdrawalFeeEstimation = await bridgeSDK.getDepositFeeEstimate(
  tokenId,
  autoWithdrawConfig
);

Withdrawal

Note that this is the only estimation where you need to provide the recipient and the amount being withdrawn.

type L1FeeAmount = string; // built in to library

const tokenId: TokenIdentifier = 'strk';
const amount: string = '112';
const l1Recipient: EthereumAddress = '0x...';

const feeEstimation: L1FeeAmount = await bridgeSDK.getWithdrawalFeeEstimate(
  tokenId,
  amount,
  l1Recipient
);

Event Subscription

BridgeSDK provides a robust event subscription API to handle different actions and states during deposit and withdrawal operations. The API allows you to subscribe to specific bridge actions and get notified about various events related to those actions.

API

  • subscribe(action: BridgeAction, cb: BridgeCallback): Subscribes to a specified bridge action.
  • unsubscribe(action: BridgeAction, cb: BridgeCallback): Unsubscribes from a specified bridge action.

Types

  • BridgeCallback: A callback function that takes an event of type BridgeEvent.

    export type BridgeCallback = (event: BridgeEvent) => void;
  • BridgeAction: Enum representing the bridge actions you can subscribe to.

    export enum BridgeAction {
      DEPOSIT = 'DEPOSIT',
      INITIATE_WITHDRAW = 'INITIATE_WITHDRAW',
      WITHDRAW = 'WITHDRAW'
    }
  • BridgeEvent: An object containing the event type and associated data.

    export class BridgeEvent {
      public type: DepositEventType | WithdrawEventType | InitiateWithdrawEventType;
      public data?: any;
    }

Event Payloads

For each event, the payload contains specific data related to that event. Here are the payloads for each event type:

  • Deposit Events:

    • DEPOSIT_STARTED: { amount: bigint; l2Recipient: StarknetAddress }

    • CHECKING_ALLOWANCE: { owner: string; spender: string }

    • APPROVE_TX_SENT: { spender: string; amount: string }

    • APPROVE_TX_SIGNED: { txHash: string }

    • APPROVE_TX_COMPLETED: { receipt: ContractTransactionReceipt }

    • APPROVAL_OK: { allowance: string }

    • DEPOSIT_TX_SENT: { transactionDetails: { args: string[]; transaction: { from: string; value?: bigint } } }

    • DEPOSIT_TX_SIGNED: { txHash: string }

    • DEPOSIT_COMPLETED: {}

    • DEPOSIT_ERROR: { error: Error }

  • Withdraw Events:

    • WITHDRAW_STARTED: { amount: bigint; recipient: EthereumAddress }
    • WITHDRAW_TX_SENT: { transactionDetails: { method: string; args: string[]; transaction: { from: string; value?: bigint } } }
    • WITHDRAW_TX_SIGNED: { txHash: string }
    • WITHDRAW_COMPLETED: { txHash: string }
    • WITHDRAW_ERROR: { error: Error }
  • Initiate Withdraw Events:

    • INITIATE_WITHDRAW_STARTED: { amount: bigint; l1Recipient: EthereumAddress; auto: boolean }
    • INITIATE_WITHDRAW_TX_SENT: { transactionDetails: Call | Call[] }
    • INITIATE_WITHDRAW_TX_SIGNED: { txHash: string }
    • INITIATE_WITHDRAW_TX_COMPLETED: { receipt: GetTransactionReceiptResponse }
    • INITIATE_WITHDRAW_COMPLETED: { txHash: string }
    • INITIATE_WITHDRAW_ERROR: { error: Error }

Usage

To subscribe to an event, you need to define a callback function that will handle the event data and then use the subscribe method with the appropriate BridgeAction. You can unsubscribe from an event using the unsubscribe method.

import {
  BridgeAction,
  BridgeCallback,
  BridgeEvent,
  BridgeSDK,
  DepositEventType
} from '@starkware-industries/starkgate-sdk';

// Define a callback function to handle events
const handleEvent: BridgeCallback = (event: BridgeEvent) => {
  switch (event.type) {
    case DepositEventType.DEPOSIT_STARTED:
      console.log('Deposit process has started.', event.data);
      break;
    case DepositEventType.APPROVE_TX_SENT:
      console.log('Approval transaction sent.', event.data);
      break;
    case DepositEventType.DEPOSIT_COMPLETED:
      console.log('Deposit completed successfully.', event.data);
      break;
    case DepositEventType.DEPOSIT_ERROR:
      console.error('An error occurred during deposit.', event.data);
      break;
    // Handle other events similarly
    default:
      console.log('Unhandled event:', event);
  }
};

// Subscribe to deposit events
bridgeSDK.subscribe(BridgeAction.DEPOSIT, handleEvent);

// Unsubscribe from deposit events when no longer needed
bridgeSDK.unsubscribe(BridgeAction.DEPOSIT, handleEvent);

This approach ensures that you are kept informed about the various stages and statuses of your deposit and withdrawal operations, allowing you to handle each event appropriately within your application.

Registering an External Bridge

BridgeSDK allows for the registration of external bridge classes that implement the IBridge interface. This can be useful for adding support for additional tokens or custom bridge logic.

To register a custom internal bridge class, which doesn't provide a token object, use the registerInternalBridge method:

class newTokenBridge implements IBridge {
  // Implement required methods...
}

BridgeSDK.registerInternalBridge('myNewToken', newTokenBridge);

To register a custom external bridge class, which includes a BridgeToken, use the registerExternalBridge method:

const myNewToken: BridgeToken = {
  symbol: 'newToken',
  name: 'myNewToken',
  decimals: 18,
  l1Address: '0x...',
  l2Address: '0x...'
  // ...Other properties
};

class newTokenBridge implements IBridge {
  // Implement required methods...
}

BridgeSDK.registerExternalBridge('myNewToken', newTokenBridge, myNewToken);

Readme

Keywords

none

Package Sidebar

Install

npm i @starkware-industries/starkgate-sdk

Weekly Downloads

1

Version

1.1.0

License

none

Unpacked Size

8.23 MB

Total Files

78

Last publish

Collaborators

  • danielgluskin
  • starkware-npm
  • roia
  • gkaempfer
  • z-dan
  • dan-starkware
  • guyvel
  • yairans-starkware