New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

near-ca

Package Overview
Dependencies
Maintainers
2
Versions
79
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

near-ca - npm Package Compare versions

Comparing version 0.0.0-beta.5 to 0.0.1

37

dist/chains/ethereum.d.ts
import { FeeMarketEIP1559Transaction } from "@ethereumjs/tx";
import { Address, Hash } from "viem";
import { BaseTx, NearEthAdapterParams, NearSignPayload, TxPayload } from "../types";
import { BaseTx, NearEthAdapterParams, NearContractFunctionPayload, TxPayload } from "../types";
import BN from "bn.js";
export declare class NearEthAdapter {
private client;
private ethClient;
private scanUrl;

@@ -11,5 +11,13 @@ private gasStationUrl;

private derivationPath;
sender: Address;
private sender;
private constructor();
/**
* @returns ETH address derived by Near account via `derivationPath`.
*/
ethPublicKey(): Address;
/**
* @returns Near accountId linked to derived ETH.
*/
nearAccountId(): string;
/**
* Constructs an EVM instance with the provided configuration.

@@ -25,9 +33,19 @@ * @param {NearEthAdapterParams} args - The configuration object for the Adapter instance.

* @param {BaseTx} txData - Minimal transaction data to be signed by Near MPC and executed on EVM.
* @param {BN} nearGas - manually specified gas to be sent with signature request (default 200 TGAS).
* Note that the signature request is a recursive function.
*/
signAndSendTransaction(txData: BaseTx, nearGas?: BN): Promise<Hash>;
/**
* 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 {BN} nearGas - manually specified gas to be sent with signature request (default 200 TGAS).
* Note that the signature request is a recursive function.
*/
getSignatureRequestPayload(txData: BaseTx, nearGas?: BN): Promise<{
transaction: FeeMarketEIP1559Transaction;
requestPayload: NearSignPayload;
requestPayload: NearContractFunctionPayload;
}>;
reconstructSignature: (transaction: FeeMarketEIP1559Transaction, big_r: string, big_s: string) => FeeMarketEIP1559Transaction;
/**

@@ -38,3 +56,3 @@ * Relays signed transaction to Etherem mempool for execution.

*/
relayTransaction(signedTx: FeeMarketEIP1559Transaction): Promise<Hash>;
relayTransaction(transaction: FeeMarketEIP1559Transaction, big_r: string, big_s: string): Promise<Hash>;
/**

@@ -49,2 +67,9 @@ * Builds a complete, unsigned transaction (with nonce, gas estimates, current prices)

private buildTransaction;
private reconstructSignature;
/**
* Relays signed transaction to Etherem mempool for execution.
* @param signedTx - Signed Ethereum transaction.
* @returns Transaction Hash of relayed transaction.
*/
private relaySignedTransaction;
}

98

dist/chains/ethereum.js

@@ -6,3 +6,3 @@ import { FeeMarketEIP1559Transaction } from "@ethereumjs/tx";

export class NearEthAdapter {
client;
ethClient;
scanUrl;

@@ -14,3 +14,5 @@ gasStationUrl;

constructor(config) {
this.client = createPublicClient({ transport: http(config.providerUrl) });
this.ethClient = createPublicClient({
transport: http(config.providerUrl),
});
this.scanUrl = config.scanUrl;

@@ -23,2 +25,14 @@ this.mpcContract = config.mpcContract;

/**
* @returns ETH address derived by Near account via `derivationPath`.
*/
ethPublicKey() {
return this.sender;
}
/**
* @returns Near accountId linked to derived ETH.
*/
nearAccountId() {
return this.mpcContract.contract.account.accountId;
}
/**
* Constructs an EVM instance with the provided configuration.

@@ -44,32 +58,30 @@ * @param {NearEthAdapterParams} args - The configuration object for the Adapter instance.

* @param {BaseTx} txData - Minimal transaction data to be signed by Near MPC and executed on EVM.
* @param {BN} nearGas - manually specified gas to be sent with signature request (default 200 TGAS).
* Note that the signature request is a recursive function.
*/
async signAndSendTransaction(txData, nearGas) {
console.log("Creating Payload for sender:", this.sender);
const { transaction, payload } = await this.createTxPayload(txData);
const { transaction, signArgs } = await this.createTxPayload(txData);
console.log("Requesting signature from Near...");
const { big_r, big_s } = await this.mpcContract.requestSignature(payload, this.derivationPath, nearGas);
const signedTx = this.reconstructSignature(transaction, big_r, big_s);
console.log("Relaying signed tx to EVM...");
return this.relayTransaction(signedTx);
const { big_r, big_s } = await this.mpcContract.requestSignature(signArgs, nearGas);
return this.relayTransaction(transaction, big_r, big_s);
}
/**
* 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 {BN} nearGas - manually specified gas to be sent with signature request (default 200 TGAS).
* Note that the signature request is a recursive function.
*/
async getSignatureRequestPayload(txData, nearGas) {
console.log("Creating Payload for sender:", this.sender);
const { transaction, payload } = await this.createTxPayload(txData);
const { transaction, signArgs } = await this.createTxPayload(txData);
console.log("Requesting signature from Near...");
return {
transaction,
requestPayload: await this.mpcContract.buildSignatureRequestTx(payload, this.derivationPath, nearGas),
requestPayload: await this.mpcContract.encodeSignatureRequestTx(signArgs, nearGas),
};
}
reconstructSignature = (transaction, big_r, big_s) => {
const r = Buffer.from(big_r.substring(2), "hex");
const s = Buffer.from(big_s, "hex");
const candidates = [0n, 1n].map((v) => transaction.addSignature(v, r, s));
const signature = candidates.find((c) => c.getSenderAddress().toString().toLowerCase() ===
this.sender.toLowerCase());
if (!signature) {
throw new Error("Signature is not valid");
}
return signature;
};
/**

@@ -80,9 +92,5 @@ * Relays signed transaction to Etherem mempool for execution.

*/
async relayTransaction(signedTx) {
const serializedTx = bytesToHex(signedTx.serialize());
const txHash = await this.client.sendRawTransaction({
serializedTransaction: serializedTx,
});
console.log(`Transaction Confirmed: ${this.scanUrl}/tx/${txHash}`);
return txHash;
async relayTransaction(transaction, big_r, big_s) {
const signedTx = await this.reconstructSignature(transaction, big_r, big_s);
return this.relaySignedTransaction(signedTx);
}

@@ -98,8 +106,9 @@ /**

const transaction = await this.buildTransaction(tx);
console.log("Built Transaction", JSON.stringify(transaction));
console.log("Built (unsigned) Transaction", transaction.toJSON());
const payload = Array.from(new Uint8Array(transaction.getHashedMessageToSign().slice().reverse()));
return { transaction, payload };
const signArgs = { payload, path: this.derivationPath, key_version: 0 };
return { transaction, signArgs };
}
async buildTransaction(tx) {
const nonce = await this.client.getTransactionCount({
const nonce = await this.ethClient.getTransactionCount({
address: this.sender,

@@ -115,3 +124,3 @@ });

};
const estimatedGas = await this.client.estimateGas(transactionData);
const estimatedGas = await this.ethClient.estimateGas(transactionData);
const transactionDataWithGasLimit = {

@@ -122,7 +131,30 @@ ...transactionData,

maxPriorityFeePerGas,
chainId: await this.client.getChainId(),
chainId: await this.ethClient.getChainId(),
};
console.log("TxData:", transactionDataWithGasLimit);
return FeeMarketEIP1559Transaction.fromTxData(transactionDataWithGasLimit);
}
reconstructSignature = (transaction, big_r, big_s) => {
const r = Buffer.from(big_r.substring(2), "hex");
const s = Buffer.from(big_s, "hex");
const candidates = [0n, 1n].map((v) => transaction.addSignature(v, r, s));
const signature = candidates.find((c) => c.getSenderAddress().toString().toLowerCase() ===
this.sender.toLowerCase());
if (!signature) {
throw new Error("Signature is not valid");
}
return signature;
};
/**
* Relays signed transaction to Etherem mempool for execution.
* @param signedTx - Signed Ethereum transaction.
* @returns Transaction Hash of relayed transaction.
*/
async relaySignedTransaction(signedTx) {
const serializedTx = bytesToHex(signedTx.serialize());
const txHash = await this.ethClient.sendRawTransaction({
serializedTransaction: serializedTx,
});
console.log(`Transaction Confirmed: ${this.scanUrl}/tx/${txHash}`);
return txHash;
}
}
import { Contract, Account } from "near-api-js";
import { Address } from "viem";
import BN from "bn.js";
import { NearSignPayload } from "./types";
interface ChangeMethodArgs<T> {
args: T;
gas: BN;
attachedDeposit: BN;
}
interface SignArgs {
path: string;
payload: number[];
}
interface SignResult {
big_r: string;
big_s: string;
}
import { ChangeMethodArgs, MPCSignature, NearContractFunctionPayload, SignArgs } from "./types";
interface MultichainContractInterface extends Contract {

@@ -22,2 +9,6 @@ public_key: () => Promise<string>;

}
/**
* High-level interface for the Near MPC-Recovery Contract
* located in: https://github.com/near/mpc-recovery
*/
export declare class MultichainContract {

@@ -28,5 +19,5 @@ contract: MultichainContractInterface;

deriveEthAddress: (derivationPath: string) => Promise<Address>;
requestSignature: (payload: number[], path: string, gas?: BN) => Promise<SignResult>;
buildSignatureRequestTx: (payload: number[], path: string, gas?: BN) => Promise<NearSignPayload>;
requestSignature: (signArgs: SignArgs, gas?: BN) => Promise<MPCSignature>;
encodeSignatureRequestTx: (signArgs: SignArgs, gas?: BN) => Promise<NearContractFunctionPayload>;
}
export {};

@@ -5,2 +5,6 @@ import { Contract } from "near-api-js";

import BN from "bn.js";
/**
* High-level interface for the Near MPC-Recovery Contract
* located in: https://github.com/near/mpc-recovery
*/
export class MultichainContract {

@@ -24,5 +28,5 @@ contract;

};
requestSignature = async (payload, path, gas) => {
requestSignature = async (signArgs, gas) => {
const [big_r, big_s] = await this.contract.sign({
args: { path, payload },
args: signArgs,
// Default of 200 TGAS

@@ -34,3 +38,3 @@ gas: gas || TGAS.muln(200),

};
buildSignatureRequestTx = async (payload, path, gas) => {
encodeSignatureRequestTx = async (signArgs, gas) => {
return {

@@ -44,3 +48,3 @@ signerId: this.contract.account.accountId,

methodName: "sign",
args: { path, payload },
args: signArgs,
gas: (gas || TGAS.muln(200)).toString(),

@@ -47,0 +51,0 @@ deposit: NO_DEPOSIT,

@@ -5,2 +5,3 @@ import { FeeMarketEIP1559Transaction } from "@ethereumjs/tx";

import { FunctionCallAction } from "@near-wallet-selector/core";
import BN from "bn.js";
export interface BaseTx {

@@ -28,7 +29,21 @@ receiver: Address;

}
export interface ChangeMethodArgs<T> {
args: T;
gas: BN;
attachedDeposit: BN;
}
/**
* Arguments required for signature request from MPC Contract
* cf. https://github.com/near/mpc-recovery/blob/ac040bcbb31ba9362a6641a5899647105a53ee4a/contract/src/lib.rs#L297-L320
*/
export interface SignArgs {
path: string;
payload: number[];
key_version: number;
}
export interface TxPayload {
transaction: FeeMarketEIP1559Transaction;
payload: number[];
signArgs: SignArgs;
}
export interface NearSignPayload {
export interface NearContractFunctionPayload {
signerId: string;

@@ -38,1 +53,16 @@ receiverId: string;

}
/**
* Result Type of MPC contract signature request.
* Representing Affine Points on eliptic curve.
*/
export interface MPCSignature {
big_r: string;
big_s: string;
}
/**
* Sufficient data required to construct a signed Ethereum Transaction.
*/
export interface TransactionWithSignature {
transaction: FeeMarketEIP1559Transaction;
signature: MPCSignature;
}
{
"name": "near-ca",
"module": "index.ts",
"version": "0.0.0-beta.5",
"version": "0.0.1",
"main": "dist/index.js",

@@ -6,0 +6,0 @@ "types": "dist/index.d.ts",

@@ -15,3 +15,3 @@ import { FeeMarketEIP1559Transaction } from "@ethereumjs/tx";

NearEthAdapterParams,
NearSignPayload,
NearContractFunctionPayload,
TxPayload,

@@ -24,8 +24,9 @@ } from "../types";

export class NearEthAdapter {
private client: PublicClient;
private ethClient: PublicClient;
private scanUrl: string;
private gasStationUrl: string;
private mpcContract: MultichainContract;
private derivationPath: string;
sender: Address;
private sender: Address;

@@ -40,3 +41,5 @@ private constructor(config: {

}) {
this.client = createPublicClient({ transport: http(config.providerUrl) });
this.ethClient = createPublicClient({
transport: http(config.providerUrl),
});
this.scanUrl = config.scanUrl;

@@ -50,2 +53,15 @@ this.mpcContract = config.mpcContract;

/**
* @returns ETH address derived by Near account via `derivationPath`.
*/
ethPublicKey(): Address {
return this.sender;
}
/**
* @returns Near accountId linked to derived ETH.
*/
nearAccountId(): string {
return this.mpcContract.contract.account.accountId;
}
/**
* Constructs an EVM instance with the provided configuration.

@@ -72,18 +88,26 @@ * @param {NearEthAdapterParams} args - The configuration object for the Adapter instance.

* @param {BaseTx} txData - Minimal transaction data to be signed by Near MPC and executed on EVM.
* @param {BN} nearGas - manually specified gas to be sent with signature request (default 200 TGAS).
* Note that the signature request is a recursive function.
*/
async signAndSendTransaction(txData: BaseTx, nearGas?: BN): Promise<Hash> {
console.log("Creating Payload for sender:", this.sender);
const { transaction, payload } = await this.createTxPayload(txData);
const { transaction, signArgs } = await this.createTxPayload(txData);
console.log("Requesting signature from Near...");
const { big_r, big_s } = await this.mpcContract.requestSignature(
payload,
this.derivationPath,
signArgs,
nearGas
);
const signedTx = this.reconstructSignature(transaction, big_r, big_s);
console.log("Relaying signed tx to EVM...");
return this.relayTransaction(signedTx);
return this.relayTransaction(transaction, big_r, big_s);
}
/**
* 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 {BN} nearGas - manually specified gas to be sent with signature request (default 200 TGAS).
* Note that the signature request is a recursive function.
*/
async getSignatureRequestPayload(

@@ -94,12 +118,11 @@ txData: BaseTx,

transaction: FeeMarketEIP1559Transaction;
requestPayload: NearSignPayload;
requestPayload: NearContractFunctionPayload;
}> {
console.log("Creating Payload for sender:", this.sender);
const { transaction, payload } = await this.createTxPayload(txData);
const { transaction, signArgs } = await this.createTxPayload(txData);
console.log("Requesting signature from Near...");
return {
transaction,
requestPayload: await this.mpcContract.buildSignatureRequestTx(
payload,
this.derivationPath,
requestPayload: await this.mpcContract.encodeSignatureRequestTx(
signArgs,
nearGas

@@ -110,24 +133,2 @@ ),

reconstructSignature = (
transaction: FeeMarketEIP1559Transaction,
big_r: string,
big_s: string
): FeeMarketEIP1559Transaction => {
const r = Buffer.from(big_r.substring(2), "hex");
const s = Buffer.from(big_s, "hex");
const candidates = [0n, 1n].map((v) => transaction.addSignature(v, r, s));
const signature = candidates.find(
(c) =>
c.getSenderAddress().toString().toLowerCase() ===
this.sender.toLowerCase()
);
if (!signature) {
throw new Error("Signature is not valid");
}
return signature;
};
/**

@@ -138,9 +139,9 @@ * Relays signed transaction to Etherem mempool for execution.

*/
async relayTransaction(signedTx: FeeMarketEIP1559Transaction): Promise<Hash> {
const serializedTx = bytesToHex(signedTx.serialize()) as Hex;
const txHash = await this.client.sendRawTransaction({
serializedTransaction: serializedTx,
});
console.log(`Transaction Confirmed: ${this.scanUrl}/tx/${txHash}`);
return txHash;
async relayTransaction(
transaction: FeeMarketEIP1559Transaction,
big_r: string,
big_s: string
): Promise<Hash> {
const signedTx = await this.reconstructSignature(transaction, big_r, big_s);
return this.relaySignedTransaction(signedTx);
}

@@ -157,7 +158,8 @@

const transaction = await this.buildTransaction(tx);
console.log("Built Transaction", JSON.stringify(transaction));
console.log("Built (unsigned) Transaction", transaction.toJSON());
const payload = Array.from(
new Uint8Array(transaction.getHashedMessageToSign().slice().reverse())
);
return { transaction, payload };
const signArgs = { payload, path: this.derivationPath, key_version: 0 };
return { transaction, signArgs };
}

@@ -168,3 +170,3 @@

): Promise<FeeMarketEIP1559Transaction> {
const nonce = await this.client.getTransactionCount({
const nonce = await this.ethClient.getTransactionCount({
address: this.sender,

@@ -182,3 +184,3 @@ });

};
const estimatedGas = await this.client.estimateGas(transactionData);
const estimatedGas = await this.ethClient.estimateGas(transactionData);
const transactionDataWithGasLimit = {

@@ -189,7 +191,44 @@ ...transactionData,

maxPriorityFeePerGas,
chainId: await this.client.getChainId(),
chainId: await this.ethClient.getChainId(),
};
console.log("TxData:", transactionDataWithGasLimit);
return FeeMarketEIP1559Transaction.fromTxData(transactionDataWithGasLimit);
}
private reconstructSignature = (
transaction: FeeMarketEIP1559Transaction,
big_r: string,
big_s: string
): FeeMarketEIP1559Transaction => {
const r = Buffer.from(big_r.substring(2), "hex");
const s = Buffer.from(big_s, "hex");
const candidates = [0n, 1n].map((v) => transaction.addSignature(v, r, s));
const signature = candidates.find(
(c) =>
c.getSenderAddress().toString().toLowerCase() ===
this.sender.toLowerCase()
);
if (!signature) {
throw new Error("Signature is not valid");
}
return signature;
};
/**
* Relays signed transaction to Etherem mempool for execution.
* @param signedTx - Signed Ethereum transaction.
* @returns Transaction Hash of relayed transaction.
*/
private async relaySignedTransaction(
signedTx: FeeMarketEIP1559Transaction
): Promise<Hash> {
const serializedTx = bytesToHex(signedTx.serialize()) as Hex;
const txHash = await this.ethClient.sendRawTransaction({
serializedTransaction: serializedTx,
});
console.log(`Transaction Confirmed: ${this.scanUrl}/tx/${txHash}`);
return txHash;
}
}

@@ -10,20 +10,9 @@ import { Contract, Account } from "near-api-js";

import BN from "bn.js";
import { NearSignPayload } from "./types";
import {
ChangeMethodArgs,
MPCSignature,
NearContractFunctionPayload,
SignArgs,
} from "./types";
interface ChangeMethodArgs<T> {
args: T;
gas: BN;
attachedDeposit: BN;
}
interface SignArgs {
path: string;
payload: number[];
}
interface SignResult {
big_r: string;
big_s: string;
}
interface MultichainContractInterface extends Contract {

@@ -37,2 +26,6 @@ // Define the signature for the `public_key` view method

/**
* High-level interface for the Near MPC-Recovery Contract
* located in: https://github.com/near/mpc-recovery
*/
export class MultichainContract {

@@ -70,8 +63,7 @@ contract: MultichainContractInterface;

requestSignature = async (
payload: number[],
path: string,
signArgs: SignArgs,
gas?: BN
): Promise<SignResult> => {
): Promise<MPCSignature> => {
const [big_r, big_s] = await this.contract.sign({
args: { path, payload },
args: signArgs,
// Default of 200 TGAS

@@ -84,7 +76,6 @@ gas: gas || TGAS.muln(200),

buildSignatureRequestTx = async (
payload: number[],
path: string,
encodeSignatureRequestTx = async (
signArgs: SignArgs,
gas?: BN
): Promise<NearSignPayload> => {
): Promise<NearContractFunctionPayload> => {
return {

@@ -98,3 +89,3 @@ signerId: this.contract.account.accountId,

methodName: "sign",
args: { path, payload },
args: signArgs,
gas: (gas || TGAS.muln(200)).toString(),

@@ -101,0 +92,0 @@ deposit: NO_DEPOSIT,

@@ -5,2 +5,3 @@ import { FeeMarketEIP1559Transaction } from "@ethereumjs/tx";

import { FunctionCallAction } from "@near-wallet-selector/core";
import BN from "bn.js";

@@ -44,11 +45,58 @@ export interface BaseTx {

/// Near Contract Type for change methods
export interface ChangeMethodArgs<T> {
/// Change method function agruments.
args: T;
/// GasLimit on transaction execution.
gas: BN;
/// Deposit (i.e. payable amount) to attach to transaction.
attachedDeposit: BN;
}
/**
* Arguments required for signature request from MPC Contract
* cf. https://github.com/near/mpc-recovery/blob/ac040bcbb31ba9362a6641a5899647105a53ee4a/contract/src/lib.rs#L297-L320
*/
export interface SignArgs {
/// Derivation Path of for ETH account associated with Near AccountId
path: string;
/// Serialized Ethereum Transaction Bytes.
payload: number[];
/// version number associated with derived ETH Address (must be increasing).
key_version: number;
}
export interface TxPayload {
/// Deserialized Ethereum Transaction.
transaction: FeeMarketEIP1559Transaction;
payload: number[];
/// Arguments required by Near MPC Contract signature request.
signArgs: SignArgs;
}
export interface NearSignPayload {
export interface NearContractFunctionPayload {
/// Signer of function call.
signerId: string;
/// Transaction Recipient (a Near ContractId).
receiverId: string;
/// Function call actions.
actions: Array<FunctionCallAction>;
}
/**
* Result Type of MPC contract signature request.
* Representing Affine Points on eliptic curve.
*/
export interface MPCSignature {
big_r: string;
big_s: string;
}
/**
* Sufficient data required to construct a signed Ethereum Transaction.
*/
export interface TransactionWithSignature {
/// Unsigned Ethereum transaction data.
transaction: FeeMarketEIP1559Transaction;
/// Representation of the transaction's signature.
signature: MPCSignature;
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc