Before initializing the tBTC SDK instance in your project, you need to answer the following questions:
What Bitcoin network and which tBTC contracts do you plan to interact with?
Do you want to perform just read-only actions or send transactions as well?
Answering those questions will allow initializing the SDK in the right way. The SDK is prepared to handle common use cases but provides some flexibility as well. This guide explains that in detail.
Ethereum and Bitcoin mainnet
This is the most common case when you want to use the SDK to interact with the tBTC bridge on Ethereum and Bitcoin mainnet. The SDK addresses it by exposing the TBTC.initializeMainnet function. That function:
Takes an Ethers signer or provider as a parameter and uses it to interact with tBTC contracts deployed on Ethereum mainnet
Automatically configures an Electrum Bitcoin client to communicate with the Bitcoin mainnet (communication is done through a set of pre-configured Electrum servers)
The following code snippet presents the usage of this function:
import*as ethers from"ethers"import { TBTC } from"@keep-network/tbtc-v2.ts"// Create an Ethers provider. Pass the URL of an Ethereum mainnet node.// For example, Alchemy or Infura.constprovider=newethers.providers.JsonRpcProvider("...")// Create an Ethers signer. Pass the private key and the above provider.constsigner=newethers.Wallet("...", provider)// If you want to initialize the SDK just for read-only actions, it is// enough to pass the provider. constsdkReadonly=awaitTBTC.initializeMainnet(provider)// If you want to make transactions as well, you have to pass the signer.constsdk=awaitTBTC.initializeMainnet(signer)
The above code snippet presents just one way of creating an Ethers signer/provider. Please refer Ethers v5 documentation to learn more.
Ethereum and Bitcoin testnet
This is the case where you want to use the SDK to interact with the tBTC bridge on Ethereum and Bitcoin testnet. The SDK addresses it by exposing the TBTC.initializeSepolia function. That function:
Takes an Ethers signer or provider as a parameter and uses it to interact with tBTC contracts deployed on Ethereum Sepolia
Automatically configures an Electrum Bitcoin client to communicate with the Bitcoin testnet (communication is done through a set of pre-configured Electrum servers)
The usage of this function is exactly the same as for the previous TBTC.initializeMainnet function.
Custom mode
Apart from the opinionated initialization functions, the SDK provides a flexible TBTC.initializeCustom function for advanced users. This function allows setting up the SDK to work with custom tBTC smart contracts and custom Bitcoin network. For example, it can be used to address the following use cases:
Using locally deployed tBTC contracts and local Bitcoin network
This is the common case when you are setting up a development environment. Let's suppose you have deployed the tBTC contracts on your local Ethereum chain and you are using a local Bitcoin regtest node. The following snippet demonstrates SDK initialization in that case:
import*as ethers from"ethers"import { TBTC, TBTCContracts, EthereumBridge, EthereumTBTCToken, EthereumTBTCVault, EthereumWalletRegistry, ElectrumClient,} from"@keep-network/tbtc-v2.ts"// Create an Ethers provider. Pass the URL of your local Ethereum node.constprovider=newethers.providers.JsonRpcProvider("...")// Create an Ethers signer. Pass the private key and the above provider.constsigner=newethers.Wallet("...", provider)// Create a reference to your locally deployed tBTC contracts.// ABI will be loaded from the following contract packages:// - @keep-network/tbtc-v2// - @keep-network/ecdsaconsttbtcContracts:TBTCContracts= { bridge:newEthereumBridge({address:"...", signerOrProvider: signer}), tbtcToken:newEthereumTBTCToken({address:"...", signerOrProvider: signer}), tbtcVault:newEthereumTBTCVault({address:"...", signerOrProvider: signer}), walletRegistry:newEthereumWalletRegistry({address:"...", signerOrProvider: signer})}// Create an Electrum Bitcoin client pointing to your local regtest node.constbitcoinClient=ElectrumClient.fromUrl("...")// Initialize the SDK.constsdk=awaitTBTC.initializeCustom(tbtcContracts, bitcoinClient)
Using a custom Bitcoin client instead of the automatically configured one
In some cases, you may want to initialize the SDK for mainnet/testnet, but point the Electrum Bitcoin client to your own server. Here is how you can do that:
import*as ethers from"ethers"import { TBTC, TBTCContracts, loadEthereumContracts, ElectrumClient} from"@keep-network/tbtc-v2.ts"// Create an Ethers provider. Pass a URL of an Ethereum mainnet node.// For example, Alchemy or Infura.constprovider=newethers.providers.JsonRpcProvider("...")// Create an Ethers signer. Pass the private key and the above provider.constsigner=newethers.Wallet("...", provider)// Load tBTC Ethereum mainnet contracts manually.consttbtcContracts:TBTCContracts=awaitloadEthereumContracts(signer,"mainnet")// Create an Electrum Bitcoin client pointing to your own mainnet server.constbitcoinClient=ElectrumClient.fromUrl("...")// Initialize the SDK with Electrum Bitcoin client pointing to your own server.constsdk=awaitTBTC.initializeCustom(tbtcContracts, bitcoinClient)
You can even use another (non-Electrum) Bitcoin client implementation. This is how you can achieve that:
import*as ethers from"ethers"import { TBTC, TBTCContracts, loadEthereumContracts, BitcoinClient,} from"@keep-network/tbtc-v2.ts"// Create an Ethers provider. Pass a URL of an Ethereum mainnet node.// For example, Alchemy or Infura.constprovider=newethers.providers.JsonRpcProvider("...")// Create an Ethers signer. Pass the private key and the above provider.constsigner=newethers.Wallet("...", provider)// Load tBTC Ethereum mainnet contracts manually.consttbtcContracts:TBTCContracts=awaitloadEthereumContracts(signer,"mainnet")// Create your own Bitcoin client implementation.classOwnBitcoinClientImplimplementsBitcoinClient {// Implement all required methods}// Initialize your own Bitcoin client implementation.constbitcoinClient=newOwnBitcoinClientImpl()// Initialize the SDK with your own Bitcoin client implementation.constsdk=awaitTBTC.initializeCustom(tbtcContracts, bitcoinClient)
Using mock tBTC contracts and mock Bitcoin network
Sometimes, you may also want to initialize the SDK with mock tBTC contracts and Bitcoin network for testing purposes. This can be done as follows:
import { TBTC, TBTCContracts, Bridge, TBTCToken, TBTCVault, WalletRegistry, BitcoinClient,} from"@keep-network/tbtc-v2.ts"// Create mock Bridge contract implementation.classMockBridgeimplementsBridge {// Implement all required methods}// Create mock TBTCToken contract implementation.classMockTBTCTokenimplementsTBTCToken {// Implement all required methods}// Create mock TBTCVault contract implementation.classMockTBTCVaultimplementsTBTCVault {// Implement all required methods}// Create mock WalletRegistry contract implementation.classMockWalletRegistryimplementsWalletRegistry {// Implement all required methods}// Create mock BitcoinClient contract implementation.classMockBitcoinClientimplementsBitcoinClient {// Implement all required methods}// Create instances of the mock contracts.consttbtcContracts:TBTCContracts= { bridge:newMockBridge(), tbtcToken:newMockTBTCToken(), tbtcVault:newMockTBTCVault(), walletRegistry:newMockWalletRegistry()}// Create an instance of the mock Bitcoin client.constbitcoinClient=newMockBitcoinClient()// Initialize the SDK.constsdk=awaitTBTC.initializeCustom(tbtcContracts, bitcoinClient)