@wormhole-foundation/sdk-evm-tbtc
Version:
SDK for EVM chains, used in conjunction with @wormhole-foundation/sdk
75 lines • 3.69 kB
JavaScript
import { TBTCBridge, nativeChainIds } from '@wormhole-foundation/sdk-connect';
import { EvmAddress, EvmPlatform, EvmUnsignedTransaction, addChainId, addFrom, } from '@wormhole-foundation/sdk-evm';
import { toChainId } from '@wormhole-foundation/sdk-base';
import { canonicalAddress, serialize, } from '@wormhole-foundation/sdk-definitions';
import { Contract } from 'ethers';
import { EvmWormholeCore } from '@wormhole-foundation/sdk-evm-core';
export class EvmTBTCBridge {
network;
chain;
provider;
contracts;
chainId;
core;
gatewayAddress;
gateway;
tbtcTokenAddr;
constructor(network, chain, provider, contracts) {
this.network = network;
this.chain = chain;
this.provider = provider;
this.contracts = contracts;
if (this.network !== 'Mainnet') {
throw new Error('TBTC is only supported on Mainnet');
}
if (!this.contracts.tbtc) {
throw new Error('TBTC contract address is required');
}
const tbtcToken = TBTCBridge.getNativeTbtcToken(this.chain);
if (!tbtcToken) {
throw new Error('Native tbtc token not found');
}
this.chainId = nativeChainIds.networkChainToNativeChainId.get(network, chain);
this.core = new EvmWormholeCore(network, chain, provider, contracts);
this.gatewayAddress = this.contracts.tbtc;
this.gateway = new Contract(this.gatewayAddress, [
'function sendTbtc(uint256 amount, uint16 recipientChain, bytes32 recipient, uint256 arbiterFee, uint32 nonce) payable returns (uint64)',
'function receiveTbtc(bytes calldata encodedVm)',
], provider);
this.tbtcTokenAddr = canonicalAddress(tbtcToken);
}
static async fromRpc(provider, config) {
const [network, chain] = await EvmPlatform.chainFromRpc(provider);
const conf = config[chain];
if (conf.network !== network)
throw new Error(`Network mismatch: ${conf.network} != ${network}`);
return new EvmTBTCBridge(network, chain, provider, conf.contracts);
}
async *transfer(sender, recipient, amount) {
const senderAddress = new EvmAddress(sender).toString();
const tx = await this.gateway.sendTbtc.populateTransaction(amount, toChainId(recipient.chain), recipient.address.toUniversalAddress().toUint8Array(), 0n, 0n);
tx.value = await this.core.getMessageFee();
yield* this.approve(senderAddress, amount, this.gatewayAddress);
yield this.createUnsignedTransaction(addFrom(tx, senderAddress), 'TBTCBridge.Send');
}
async *redeem(sender, vaa) {
if (vaa.payloadName !== 'GatewayTransfer') {
throw new Error('Invalid VAA payload');
}
const address = new EvmAddress(sender).toString();
const tx = await this.gateway.receiveTbtc.populateTransaction(serialize(vaa));
yield this.createUnsignedTransaction(addFrom(tx, address), 'TBTCBridge.Redeem');
}
async *approve(senderAddr, amount, contract) {
const tokenContract = EvmPlatform.getTokenImplementation(this.provider, this.tbtcTokenAddr);
const allowance = await tokenContract.allowance(senderAddr, contract);
if (allowance < amount) {
const txReq = await tokenContract.approve.populateTransaction(contract, amount);
yield this.createUnsignedTransaction(addFrom(txReq, senderAddr), 'TBTC.Approve');
}
}
createUnsignedTransaction(txReq, description) {
return new EvmUnsignedTransaction(addChainId(txReq, this.chainId), this.network, this.chain, description, false);
}
}
//# sourceMappingURL=bridge.js.map