@wormhole-foundation/sdk-evm
Version:
SDK for EVM chains, used in conjunction with @wormhole-foundation/sdk
107 lines • 4.63 kB
JavaScript
import { PlatformContext, Wormhole, chainToPlatform, decimals, encoding, isNative, nativeChainIds, networkPlatformConfigs, } from '@wormhole-foundation/sdk-connect';
import { JsonRpcProvider } from 'ethers';
import * as ethers_contracts from './ethers-contracts/index.js';
import { EvmAddress, EvmZeroAddress } from './address.js';
import { EvmChain } from './chain.js';
import { _platform } from './types.js';
/**
* @category EVM
*/
export class EvmPlatform extends PlatformContext {
static _platform = _platform;
constructor(network, _config) {
super(network, _config ?? networkPlatformConfigs(network, EvmPlatform._platform));
}
getRpc(chain) {
if (chain in this.config && this.config[chain].rpc)
return new JsonRpcProvider(this.config[chain].rpc);
throw new Error('No configuration available for chain: ' + chain);
}
getChain(chain, rpc) {
if (chain in this.config)
return new EvmChain(chain, this, rpc);
throw new Error('No configuration available for chain: ' + chain);
}
static nativeTokenId(network, chain) {
if (!EvmPlatform.isSupportedChain(chain))
throw new Error(`invalid chain for EVM: ${chain}`);
return Wormhole.tokenId(chain, EvmZeroAddress);
}
static isNativeTokenId(network, chain, tokenId) {
if (!EvmPlatform.isSupportedChain(chain))
return false;
if (tokenId.chain !== chain)
return false;
return tokenId.address.toString() === EvmZeroAddress;
}
static isSupportedChain(chain) {
const platform = chainToPlatform(chain);
return platform === EvmPlatform._platform;
}
static async getDecimals(chain, rpc, token) {
if (isNative(token))
return decimals.nativeDecimals(EvmPlatform._platform);
const tokenContract = EvmPlatform.getTokenImplementation(rpc, new EvmAddress(token).toString());
return Number(await tokenContract.decimals());
}
static async getBalance(chain, rpc, walletAddr, token) {
if (isNative(token))
return rpc.getBalance(walletAddr);
const tokenImpl = EvmPlatform.getTokenImplementation(rpc, new EvmAddress(token).toString());
return tokenImpl.balanceOf(walletAddr);
}
static async getBalances(chain, rpc, walletAddr, tokens) {
const balancesArr = await Promise.all(tokens.map(async (token) => {
const balance = await this.getBalance(chain, rpc, walletAddr, token);
const address = isNative(token)
? 'native'
: new EvmAddress(token).toString();
return { [address]: balance };
}));
return balancesArr.reduce((obj, item) => Object.assign(obj, item), {});
}
static async sendWait(chain, rpc, stxns) {
const txhashes = [];
for (const stxn of stxns) {
const txRes = await rpc.broadcastTransaction(stxn);
txhashes.push(txRes.hash);
if (chain === 'Celo') {
console.error('TODO: override celo block fetching');
continue;
}
// Wait for confirmation
const txReceipt = await txRes.wait();
if (txReceipt === null)
throw new Error('Received null TxReceipt');
}
return txhashes;
}
static async getLatestBlock(rpc) {
return await rpc.getBlockNumber();
}
static async getLatestFinalizedBlock(rpc) {
const block = await rpc.getBlock('finalized');
if (!block)
throw new Error('Could not get finalized block');
return block?.number;
}
// Look up the Wormhole Canonical Network and Chain from the EVM chainId
static chainFromChainId(eip155ChainId) {
const networkChainPair = nativeChainIds.platformNativeChainIdToNetworkChain(EvmPlatform._platform, BigInt(eip155ChainId));
if (networkChainPair === undefined)
throw new Error(`Unknown EVM chainId ${eip155ChainId}`);
const [network, chain] = networkChainPair;
return [network, chain];
}
static async chainFromRpc(rpc) {
const { chainId } = await rpc.getNetwork();
return EvmPlatform.chainFromChainId(encoding.bignum.encode(chainId, true));
}
static getTokenImplementation(connection, address) {
const ti = ethers_contracts.TokenImplementation__factory.connect(address, connection);
if (!ti)
throw new Error(`No token implementation available for: ${address}`);
return ti;
}
}
//# sourceMappingURL=platform.js.map