@wormhole-foundation/sdk-evm
Version:
SDK for EVM chains, used in conjunction with @wormhole-foundation/sdk
112 lines • 4.61 kB
JavaScript
import { PlatformNativeSigner, chainToPlatform, isNativeSigner, } from '@wormhole-foundation/sdk-connect';
import { NonceManager, Wallet } from 'ethers';
import { EvmPlatform } from './platform.js';
import { _platform } from './types.js';
export async function getEvmSigner(rpc, key, opts) {
const signer = typeof key === 'string' ? new Wallet(key, rpc) : key;
const chain = opts?.chain ?? (await EvmPlatform.chainFromRpc(rpc))[1];
const managedSigner = new NonceManager(signer);
if (managedSigner.provider === null) {
try {
managedSigner.connect(rpc);
}
catch (e) {
console.error('Cannot connect to network for signer', e);
}
}
return new EvmNativeSigner(chain, await signer.getAddress(), managedSigner, opts);
}
// Get a SignOnlySigner for the EVM platform
export async function getEvmSignerForKey(rpc, privateKey) {
return getEvmSigner(rpc, privateKey);
}
// Get a SignOnlySigner for the EVM platform
export async function getEvmSignerForSigner(signer) {
if (!signer.provider)
throw new Error('Signer must have a provider');
return getEvmSigner(signer.provider, signer, {});
}
export class EvmNativeSigner extends PlatformNativeSigner {
opts;
constructor(_chain, _address, _signer, opts) {
super(_chain, _address, _signer);
this.opts = opts;
}
chain() {
return this._chain;
}
address() {
return this._address;
}
async sign(tx) {
const chain = this.chain();
const signed = [];
// Default gas values
let gasLimit = 500000n;
let gasPrice = 100000000000n; // 100gwei
let maxFeePerGas = 1500000000n; // 1.5gwei
let maxPriorityFeePerGas = 100000000n; // 0.1gwei
// If no overrides were passed, we can get better
// gas values from the provider
if (this.opts?.overrides === undefined) {
// Celo does not support this call
if (chain !== 'Celo') {
const feeData = await this._signer.provider.getFeeData();
gasPrice = feeData.gasPrice ?? gasPrice;
maxFeePerGas = feeData.maxFeePerGas ?? maxFeePerGas;
maxPriorityFeePerGas =
feeData.maxPriorityFeePerGas ?? maxPriorityFeePerGas;
}
}
if (this.opts?.gasLimit !== undefined) {
gasLimit = this.opts.gasLimit;
}
if (this.opts?.maxGasLimit !== undefined) {
// why doesnt math.min work for bigints?
gasLimit =
gasLimit > this.opts?.maxGasLimit ? this.opts?.maxGasLimit : gasLimit;
}
// Oasis throws malformed errors unless we
// set it to use legacy transaction parameters
const gasOpts = chain === 'Oasis'
? { gasLimit, gasPrice, type: 0 } // Hardcoded to legacy transaction type
: { gasLimit, maxFeePerGas, maxPriorityFeePerGas };
for (const txn of tx) {
const { transaction, description } = txn;
if (this.opts?.debug)
console.log(`Signing: ${description} for ${this.address()}`);
const t = {
...transaction,
...gasOpts,
from: this.address(),
nonce: await this._signer.getNonce(),
// Override any existing values with those passed in the constructor
...this.opts?.overrides,
};
signed.push(await this._signer.signTransaction(t));
}
return signed;
}
}
export function isEvmNativeSigner(signer) {
return (isNativeSigner(signer) &&
chainToPlatform(signer.chain()) === _platform &&
isEthersSigner(signer.unwrap()));
}
// No type guard provided by ethers, instanceof checks will fail on even slightly different versions of ethers
function isEthersSigner(thing) {
return ('provider' in thing &&
typeof thing.connect === 'function' &&
typeof thing.getAddress === 'function' &&
typeof thing.getNonce === 'function' &&
typeof thing.populateCall === 'function' &&
typeof thing.populateTransaction === 'function' &&
typeof thing.estimateGas === 'function' &&
typeof thing.call === 'function' &&
typeof thing.resolveName === 'function' &&
typeof thing.signTransaction === 'function' &&
typeof thing.sendTransaction === 'function' &&
typeof thing.signMessage === 'function' &&
typeof thing.signTypedData === 'function');
}
//# sourceMappingURL=signer.js.map