Next.js Demo - Application • Next.js Demo - Repository
This TypeScript SDK is designed for building token bridge applications between Tezos (L1) and Etherlink (L2). It allows developers to easily:
- Deposit native (XTZ) and FA tokens from Tezos to Etherlink.
- Withdraw native and ERC20 tokens from Etherlink back to Tezos.
- Retrieve information on all token transfers (deposits and withdrawals) or by operation/transaction hash, or addresses.
- Receive actual token balances for specific addresses.
- Obtain real-time updates on existing or new token transfers for specific addresses or all transfers.
The SDK is isomorphic, enabling developers to create bridge applications on the frontend using popular frameworks or Vanilla JavaScript, as well as on the server-side using Node.js.
-
Install the SDK package:
npm install @baking-bad/tezos-etherlink-bridge-sdk
or
yarn add @baking-bad/tezos-etherlink-bridge-sdk
-
Install additional dependencies:
The SDK requires additional libraries for interacting with the blockchains. These packages are marked as optional
peerDependencies
, so depending on your preference, you also need to install and configure the appropriate package for each blockchain manually in your application.Tezos
-
Taquito. The SDK supports both the Wallet API and Contract API:
-
The Wallet API. If your application needs to interact with wallets using the Beacon SDK
npm install @taquito/taquito @taquito/beacon-wallet
or
yarn add @taquito/taquito @taquito/beacon-wallet
-
Contract API.
npm install @taquito/taquito
or
yarn add @taquito/taquito
-
Etherlink. Choose one of these packages for interfacing with the Etherlink blockchain, depending on your preference. You only need one of these packages, not both.
-
-
Install ws for Node.js applications (optional):
If you are developing a Node.js application, you also need to install the ws package as Node.js doesn't have a native WebSocket implementation.
npm install ws
or
yarn add ws
Depending on the blockchain libraries you choose to use, you will need to configure them to sign data and transactions.
import { BeaconWallet } from '@taquito/beacon-wallet';
import { TezosToolkit } from '@taquito/taquito';
const tezosRpcUrl = 'https://rpc.tzkt.io/ghostnet';
const tezosToolkit = new TezosToolkit(tezosRpcUrl);
const beaconWallet = new BeaconWallet({
name: 'Your dApp name',
network: { type: 'custom', rpcUrl: tezosRpcUrl }
});
tezosToolkit.setWalletProvider(beaconWallet);
import { InMemorySigner } from '@taquito/signer';
import { TezosToolkit } from '@taquito/taquito';
const tezosRpcUrl = 'https://rpc.tzkt.io/ghostnet';
const tezosToolkit = new TezosToolkit(tezosRpcUrl);
const signer = new InMemorySigner('<your secret key>');
tezosToolkit.setSignerProvider(signer);
import Web3 from 'web3';
// Use MetaMask
const web3 = new Web3(window.ethereum);
import { ethers } from 'ethers';
// Use MetaMask
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
The SDK only allows registered (listed) tokens to be transferred between Tezos and Etherlink (see details). Configure a list of token pairs or the corresponding provider:
Example token pair configuration code
import type { TokenPair } from '@baking-bad/tezos-etherlink-bridge-sdk';
// ...
const tokenPairs: TokenPair[] = [
// Native
{
tezos: {
type: 'native',
ticketHelperContractAddress: 'KT1VEjeQfDBSfpDH5WeBM5LukHPGM2htYEh3',
},
etherlink: {
type: 'native',
}
},
// tzBTC
{
tezos: {
type: 'fa1.2',
address: 'KT1HmyazXfKDbo8XjwtWPXcoyHcmNPDCvZyb',
ticketerContractAddress: 'KT1H7if3gSZE1pZSK48W3NzGpKmbWyBxWDHe',
ticketHelperContractAddress: 'KT1KUAaaRMeMS5TJJyGTQJANcpSR4egvHBUk',
},
etherlink: {
type: 'erc20',
address: '0x8e73aE3CF688Fbd8368c99520d26F9eF1B4d3BCa',
}
},
// USDt
{
tezos: {
type: 'fa2',
address: 'KT1V2ak1MfNd3w4oyKD64ehYU7K4CrpUcDGR',
tokenId: '0',
ticketerContractAddress: 'KT1S6Nf9MnafAgSUWLKcsySPNFLUxxqSkQCw',
ticketHelperContractAddress: 'KT1JLZe4qTa76y6Us2aDoRNUgZyssSDUr6F5',
},
etherlink: {
type: 'erc20',
address: '0xf68997eCC03751cb99B5B36712B213f11342452b',
}
}
];
Once token pairs are configured, creating an instance of TokenBridge
is a type through which you can deposit, withdraw tokens, and receive token transfers between layers.
import { DefaultDataProvider, TokenBridge } from '@baking-bad/tezos-etherlink-bridge-sdk';
// ...
const defaultDataProvider = const defaultDataProvider = new DefaultDataProvider({
tokenPairs,
dipDup: {
baseUrl: 'https://testnet.bridge.indexer.etherlink.com',
webSocketApiBaseUrl: 'wss://testnet.bridge.indexer.etherlink.com'
},
tzKTApiBaseUrl: 'https://api.ghostnet.tzkt.io',
etherlinkRpcUrl: 'https://node.ghostnet.etherlink.com',
})
const tokenBridge = new TokenBridge({
tezosBridgeBlockchainService: new TaquitoWalletTezosBridgeBlockchainService({
tezosToolkit: this.tezosToolkit,
smartRollupAddress: config.bridge.smartRollupAddress
}),
etherlinkBridgeBlockchainService: new Web3EtherlinkBridgeBlockchainService({
web3
}),
// or for ethers
// etherlinkBridgeBlockchainService: new EthersEtherlinkBridgeBlockchainService({
// ethers,
// signer
// }),
bridgeDataProviders: {
transfers: defaultDataProvider,
balances: defaultDataProvider,
tokens: defaultDataProvider,
}
});
The second approach is to create an instance directly (new TokenBridge(<options>)
) and configure all options and data providers manually:
import {
TokenBridge, DefaultDataProvider,
defaultEtherlinkKernelAddress, defaultEtherlinkWithdrawPrecompileAddress
} from '@baking-bad/tezos-etherlink-bridge-sdk';
// ...
const defaultDataProvider = new DefaultDataProvider({
dipDup: {
baseUrl: 'https://etherlink-indexer.dipdup.net/',
webSocketApiBaseUrl: 'wss://etherlink-indexer.dipdup.net'
},
tzKTApiBaseUrl: 'https://api.oxfordnet.tzkt.io',
etherlinkRpcUrl: 'https://etherlink.dipdup.net',
tokenPairs
});
const tokenBridge = new TokenBridge({
tezosBridgeBlockchainService: new TaquitoWalletTezosBridgeBlockchainService({
tezosToolkit: this.tezosToolkit,
smartRollupAddress: config.bridge.smartRollupAddress
}),
etherlinkBridgeBlockchainService: new Web3EtherlinkBridgeBlockchainService({
web3: this.etherlinkToolkit
}),
// or for ethers
// etherlinkBridgeBlockchainService: new EthersEtherlinkBridgeBlockchainService({
// ethers,
// signer
// }),
bridgeDataProviders: {
transfers: defaultDataProvider,
balances: defaultDataProvider,
tokens: defaultDataProvider,
}
});