UNPKG

near-ca-test

Version:

An SDK for controlling Ethereum Accounts from a Near Account.

176 lines (175 loc) 7.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NearEthAdapter = void 0; const viem_1 = require("viem"); const __1 = require(".."); const beta_1 = require("../beta"); const request_1 = require("../utils/request"); class NearEthAdapter { constructor(config) { this.mpcContract = config.mpcContract; this.derivationPath = config.derivationPath; this.address = config.sender; this.beta = new beta_1.Beta(this); } /** * @returns Near accountId linked to derived ETH. */ nearAccountId() { return this.mpcContract.connectedAccount.accountId; } /** * Retrieves the balance of the Ethereum address associated with this adapter. * * @param {number} chainId - The chain ID of the Ethereum network to query. * @returns {Promise<bigint>} - A promise that resolves to the balance of the address in wei. */ async getBalance(chainId) { const network = __1.Network.fromChainId(chainId); return network.client.getBalance({ address: this.address }); } /** * Constructs an EVM instance with the provided configuration. * @param {AdapterParams} args - The configuration object for the Adapter instance. */ static async fromConfig(args) { // Sender is uniquely determined by the derivation path! const mpcContract = args.mpcContract; const derivationPath = args.derivationPath || "ethereum,1"; return new NearEthAdapter({ sender: await mpcContract.deriveEthAddress(derivationPath), derivationPath, mpcContract, }); } /** * Constructs an EVM instance with the provided configuration. * @param {AdapterParams} args - The configuration object for the Adapter instance. */ static async mocked(args) { // Sender is uniquely determined by the derivation path! const mpcContract = args.mpcContract; const derivationPath = args.derivationPath || "ethereum,1"; return new NearEthAdapter({ sender: await mpcContract.deriveEthAddress(derivationPath), derivationPath, mpcContract, }); } /** * Takes a minimally declared Ethereum Transaction, * builds the full transaction payload (with gas estimates, prices etc...), * acquires signature from Near MPC Contract and submits transaction to public mempool. * * @param {BaseTx} txData - Minimal transaction data to be signed by Near MPC and executed on EVM. * @param {bigint} nearGas - manually specified gas to be sent with signature request. * Note that the signature request is a recursive function. */ async signAndSendTransaction(txData, nearGas) { const { transaction, signArgs } = await this.createTxPayload(txData); console.log(`Requesting signature from ${this.mpcContract.accountId()}`); const signature = await this.mpcContract.requestSignature(signArgs, nearGas); return (0, __1.broadcastSignedTransaction)({ transaction, signature }); } /** * Takes a minimally declared Ethereum Transaction, * builds the full transaction payload (with gas estimates, prices etc...), * acquires signature from Near MPC Contract and submits transaction to public mempool. * * @param {BaseTx} txData - Minimal transaction data to be signed by Near MPC and executed on EVM. * @param {bigint} nearGas - manually specified gas to be sent with signature request. * Note that the signature request is a recursive function. */ async getSignatureRequestPayload(txData, nearGas) { const { transaction, signArgs } = await this.createTxPayload(txData); return { transaction, requestPayload: await this.mpcContract.encodeSignatureRequestTx(signArgs, nearGas), }; } /** * Builds a Near Transaction Payload for Signing serialized EVM Transaction. * @param {Hex} transaction RLP encoded (i.e. serialized) Ethereum Transaction * @param nearGas optional gas parameter * @returns {FunctionCallTransaction<SignArgs>} Prepared Near Transaction with signerId as this.address */ async mpcSignRequest(transaction, nearGas) { return this.mpcContract.encodeSignatureRequestTx({ payload: (0, __1.buildTxPayload)(transaction), path: this.derivationPath, key_version: 0, }, nearGas); } /** * Builds a complete, unsigned transaction (with nonce, gas estimates, current prices) * and payload bytes in preparation to be relayed to Near MPC contract. * * @param {BaseTx} tx - Minimal transaction data to be signed by Near MPC and executed on EVM. * @param {number?} nonce - Optional transaction nonce. * @returns Transaction and its bytes (the payload to be signed on Near). */ async createTxPayload(tx) { console.log(`Creating payload for sender: ${this.nearAccountId()} <> ${this.address}`); const transaction = await this.buildTransaction(tx); console.log("Built (unsigned) Transaction", transaction); const signArgs = { payload: (0, __1.buildTxPayload)(transaction), path: this.derivationPath, key_version: 0, }; return { transaction, signArgs }; } /** * Transforms minimal transaction request data into a fully populated EVM transaction. * @param {BaseTx} tx - Minimal transaction request data * @returns {Hex} serialized (aka RLP encoded) transaction. */ async buildTransaction(tx) { const transaction = await (0, __1.populateTx)(tx, this.address); console.log("Transaction Request", transaction); return (0, viem_1.serializeTransaction)(transaction); } // Below code is inspired by https://github.com/Connor-ETHSeoul/near-viem async signTypedData(typedData) { return this.sign((0, viem_1.hashTypedData)(typedData)); } async signMessage(message) { return this.sign((0, viem_1.hashMessage)(message)); } /** * Requests signature from Near MPC Contract. * @param msgHash - Message Hash to be signed. * @returns Two different potential signatures for the hash (one of which is valid). */ async sign(msgHash) { const signature = await this.mpcContract.requestSignature({ path: this.derivationPath, payload: (0, __1.toPayload)(msgHash), key_version: 0, }); return (0, viem_1.serializeSignature)(signature); } /** * Encodes a signature request for submission to the Near-Ethereum transaction MPC contract. * * @async * @function encodeSignRequest * @param {SignRequestData} signRequest - The signature request data containing method, chain ID, and parameters. * @returns {Promise<NearEthTxData>} * - Returns a promise that resolves to an object containing the encoded Near-Ethereum transaction data, * the original EVM message, and recovery data necessary for verifying or reconstructing the signature. */ async encodeSignRequest(signRequest) { const { evmMessage, hashToSign } = await (0, request_1.requestRouter)(signRequest); return { nearPayload: await this.mpcContract.encodeSignatureRequestTx({ path: this.derivationPath, payload: (0, __1.toPayload)(hashToSign), key_version: 0, }), evmMessage, hashToSign, }; } } exports.NearEthAdapter = NearEthAdapter;