@wormhole-foundation/sdk-evm
Version:
SDK for EVM chains, used in conjunction with @wormhole-foundation/sdk
179 lines • 7.9 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EvmPlatform = void 0;
const sdk_connect_1 = require("@wormhole-foundation/sdk-connect");
const ethers_1 = require("ethers");
const ethers_contracts = __importStar(require("./ethers-contracts/index.js"));
const address_js_1 = require("./address.js");
const chain_js_1 = require("./chain.js");
const types_js_1 = require("./types.js");
const indexer_js_1 = require("./indexer.js");
/**
* @category EVM
*/
class EvmPlatform extends sdk_connect_1.PlatformContext {
static _platform = types_js_1._platform;
_providers = {};
constructor(network, _config) {
super(network, _config ?? (0, sdk_connect_1.networkPlatformConfigs)(network, EvmPlatform._platform));
}
getRpc(chain) {
const cachedProvider = this._providers[chain];
if (cachedProvider) {
return cachedProvider;
}
if (chain in this.config && this.config[chain].rpc) {
const provider = new ethers_1.JsonRpcProvider(this.config[chain].rpc, sdk_connect_1.nativeChainIds.networkChainToNativeChainId.get(this.network, chain), {
staticNetwork: true,
});
this._providers[chain] = provider;
return provider;
}
else {
throw new Error('No configuration available for chain: ' + chain);
}
}
getChain(chain, rpc) {
if (chain in this.config)
return new chain_js_1.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 sdk_connect_1.Wormhole.tokenId(chain, address_js_1.EvmZeroAddress);
}
static isNativeTokenId(network, chain, tokenId) {
if (!EvmPlatform.isSupportedChain(chain))
return false;
if (tokenId.chain !== chain)
return false;
return tokenId.address.toString() === address_js_1.EvmZeroAddress;
}
static isSupportedChain(chain) {
const platform = (0, sdk_connect_1.chainToPlatform)(chain);
return platform === EvmPlatform._platform;
}
static async getDecimals(_network, _chain, rpc, token) {
if ((0, sdk_connect_1.isNative)(token))
return sdk_connect_1.decimals.nativeDecimals(EvmPlatform._platform);
const tokenContract = EvmPlatform.getTokenImplementation(rpc, new address_js_1.EvmAddress(token).toString());
return Number(await tokenContract.decimals());
}
static async getBalance(_network, _chain, rpc, walletAddr, token) {
if ((0, sdk_connect_1.isNative)(token))
return rpc.getBalance(walletAddr);
const tokenImpl = EvmPlatform.getTokenImplementation(rpc, new address_js_1.EvmAddress(token).toString());
return tokenImpl.balanceOf(walletAddr);
}
static async getBalances(network, chain, rpc, walletAddr, indexers) {
if (indexers) {
if (indexers.goldRush) {
try {
const goldRush = new indexer_js_1.GoldRushClient(indexers.goldRush);
if (goldRush.supportsChain(network, chain)) {
const balances = await goldRush.getBalances(network, chain, walletAddr);
if (balances['native'] === undefined) {
balances['native'] = await rpc.getBalance(walletAddr);
}
return balances;
}
else {
console.error(`Network=${network} Chain=${chain} not supported by Gold Rush indexer API`);
}
}
catch (e) {
console.error(`Error querying Gold Rush indexer API: ${e}`);
}
}
if (indexers.alchemy) {
try {
const alchemy = new indexer_js_1.AlchemyClient(indexers.alchemy);
if (alchemy.supportsChain(network, chain)) {
const balances = await alchemy.getBalances(network, chain, walletAddr);
balances['native'] = await rpc.getBalance(walletAddr);
return balances;
}
else {
console.error(`Network=${network} Chain=${chain} not supported by Alchemy indexer API`);
}
}
catch (e) {
console.error(`Error querying Alchemy indexer API: ${e}`);
}
}
}
else {
throw new Error(`Can't get all EVM balances without an indexer. Use getBalance to make individual calls instead.`);
}
throw new Error(`Failed to get a successful response from an EVM indexer`);
}
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 = sdk_connect_1.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(sdk_connect_1.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;
}
}
exports.EvmPlatform = EvmPlatform;
//# sourceMappingURL=platform.js.map