near-ca
Version:
An SDK for controlling Ethereum Accounts from a Near Account.
173 lines (172 loc) • 6.65 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.NearEthAdapter = void 0;
const viem_1 = require("viem");
const __1 = require("..");
const beta_1 = require("../beta");
const utils_1 = require("../utils");
/**
* Adapter class for interacting with Ethereum through NEAR MPC contract
*/
class NearEthAdapter {
constructor(config) {
this.mpcContract = config.mpcContract;
this.derivationPath = config.derivationPath;
this.address = config.sender;
this.beta = new beta_1.Beta(this);
}
/**
* Gets the NEAR account ID linked to derived EVM account
*
* @returns The connected NEAR account ID
*/
nearAccountId() {
return this.mpcContract.connectedAccount.accountId;
}
/**
* Retrieves the balance of the Ethereum address associated with this adapter
*
* @param chainId - The chain ID of the Ethereum network to query
* @returns 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 args - The configuration object for the Adapter instance
* @returns A new NearEthAdapter instance
*/
static async fromConfig(args) {
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 txData - Minimal transaction data to be signed by Near MPC and executed on EVM
* @param nearGas - Manually specified gas to be sent with signature request
* @returns The ethereum transaction hash
*/
async signAndSendTransaction(txData, nearGas) {
const { transaction, signArgs } = await this.createTxPayload(txData);
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...),
* and prepares the signature request payload for the Near MPC Contract
*
* @param txData - Minimal transaction data to be signed by Near MPC and executed on EVM
* @param nearGas - Manually specified gas to be sent with signature request
* @returns The transaction and request payload
*/
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 transaction - RLP encoded (i.e. serialized) Ethereum Transaction
* @param nearGas - Optional gas parameter
* @returns 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 tx - Minimal transaction data to be signed by Near MPC and executed on EVM
* @returns Transaction and its bytes (the payload to be signed on Near)
*/
async createTxPayload(tx) {
const transaction = await this.buildTransaction(tx);
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 tx - Minimal transaction request data
* @returns Serialized (aka RLP encoded) transaction
*/
async buildTransaction(tx) {
const transaction = await (0, __1.populateTx)(tx, this.address);
return (0, viem_1.serializeTransaction)(transaction);
}
/**
* Signs typed data according to EIP-712
*
* @param typedData - The typed data to sign
* @returns The signature hash
*/
async signTypedData(typedData) {
return this.sign((0, viem_1.hashTypedData)(typedData));
}
/**
* Signs a message according to personal_sign
*
* @param message - The message to sign
* @returns The signature hash
*/
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
*
* @param signRequest - The signature request data containing method, chain ID, and parameters
* @returns The encoded Near-Ethereum transaction data, original EVM message, and recovery data
*/
async encodeSignRequest(signRequest) {
const { evmMessage, hashToSign } = await (0, utils_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;