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.
- 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
Install BridgeSDK using npm:
npm install @starkware-industries/starkgate-sdk
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);
-
debug
: A boolean flag to enable debug mode. Default isfalse
. -
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
).
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);
import {BridgeToken} from '@starkware-industries/starkgate-sdk';
const bridges: BridgeToken = bridgeSDK.getBridgeTokens();
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);
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);
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);
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);
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
);
Run these functions to get a fee estimation on the following flows:
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);
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
);
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
);
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.
-
subscribe(action: BridgeAction, cb: BridgeCallback)
: Subscribes to a specified bridge action. -
unsubscribe(action: BridgeAction, cb: BridgeCallback)
: Unsubscribes from a specified bridge action.
-
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; }
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 }
-
WITHDRAW_STARTED:
-
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 }
-
INITIATE_WITHDRAW_STARTED:
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.
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);