Skip to content

Commit

Permalink
Merge branch 'main' into remove-BN
Browse files Browse the repository at this point in the history
  • Loading branch information
bh2smith authored May 8, 2024
2 parents dcde4c8 + 0b1a6a0 commit f354f14
Show file tree
Hide file tree
Showing 14 changed files with 293 additions and 86 deletions.
24 changes: 11 additions & 13 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,25 @@
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"plugins": ["@typescript-eslint"],
"rules": {
"indent": ["error", 2],
"indent": ["error", 2, { "SwitchCase": 1 }],
"linebreak-style": ["error", "unix"],
"quotes": ["error", "double"],
"semi": ["error","always"],
"semi": ["error", "always"],
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/explicit-function-return-type": ["error", {
"allowExpressions": true,
"allowTypedFunctionExpressions": true
}]
"@typescript-eslint/explicit-function-return-type": [
"error",
{
"allowExpressions": true,
"allowTypedFunctionExpressions": true
}
]
}
}
18 changes: 8 additions & 10 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,13 @@ jobs:
- name: Install & Build
run: yarn && yarn build

- name: Lint & Test
- name: Lint & Unit Test
run: |
yarn lint
yarn test
env:
NODE_URL: https://rpc2.sepolia.org
SCAN_URL: https://sepolia.etherscan.io
GAS_STATION_URL: https://sepolia.beaconcha.in/api/v1/execution/gasnow

NEAR_MULTICHAIN_CONTRACT: multichain-testnet-2.testnet
NEAR_ACCOUNT_ID: ${{secrets.NEAR_ACCOUNT_ID}}
NEAR_ACCOUNT_PRIVATE_KEY: ${{secrets.NEAR_PK}}
yarn test unit
# These are only relevant for e2e tests
# env:
# NEAR_MULTICHAIN_CONTRACT: multichain-testnet-2.testnet
# NEAR_MULTICHAIN_CONTRACT: v5.multichain-mpc-dev.testnet
# NEAR_ACCOUNT_ID: ${{secrets.NEAR_ACCOUNT_ID}}
# NEAR_ACCOUNT_PRIVATE_KEY: ${{secrets.NEAR_PK}}
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.eslintrc
52 changes: 8 additions & 44 deletions src/chains/ethereum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ import {
NearContractFunctionPayload,
TxPayload,
TransactionWithSignature,
} from "../types";
} from "../types/types";
import { MultichainContract } from "../mpcContract";
import BN from "bn.js";
import { queryGasPrice } from "../utils/gasPrice";
import { buildTxPayload, addSignature } from "../utils/transaction";
import { buildTxPayload, addSignature, populateTx } from "../utils/transaction";
import { Network } from "../network";
import { pickValidSignature } from "../utils/signature";

export class NearEthAdapter {
readonly mpcContract: MultichainContract;
Expand Down Expand Up @@ -150,32 +150,9 @@ export class NearEthAdapter {
* @returns {Hex} serialized (aka RLP encoded) transaction.
*/
async buildTransaction(tx: BaseTx): Promise<Hex> {
const network = Network.fromChainId(tx.chainId);
const transactionData = {
nonce:
tx.nonce ||
(await network.client.getTransactionCount({
address: this.address,
})),
account: this.address,
to: tx.to,
value: tx.value ?? 0n,
data: tx.data ?? "0x",
};
const [estimatedGas, { maxFeePerGas, maxPriorityFeePerGas }] =
await Promise.all([
network.client.estimateGas(transactionData),
queryGasPrice(network.gasStationUrl),
]);
const transactionDataWithGasLimit = {
...transactionData,
gas: BigInt(estimatedGas.toString()),
maxFeePerGas,
maxPriorityFeePerGas,
chainId: network.chainId,
};
console.log("Transaction Request", transactionDataWithGasLimit);
return serializeTransaction(transactionDataWithGasLimit);
const transaction = await populateTx(tx, this.address);
console.log("Transaction Request", transaction);
return serializeTransaction(transaction);
}

reconstructSignature(tx: TransactionWithSignature): Hex {
Expand Down Expand Up @@ -225,7 +202,7 @@ export class NearEthAdapter {
...common,
}),
]);
return this.pickValidSignature(validity, sigs);
return pickValidSignature(validity, sigs);
}

async signMessage(message: SignableMessage): Promise<Hash> {
Expand All @@ -244,7 +221,7 @@ export class NearEthAdapter {
...common,
}),
]);
return this.pickValidSignature(validity, sigs);
return pickValidSignature(validity, sigs);
}

/**
Expand All @@ -268,17 +245,4 @@ export class NearEthAdapter {
signatureToHex({ r, s, yParity: 1 }),
];
}

private pickValidSignature(
[valid0, valid1]: [boolean, boolean],
[sig0, sig1]: [Hash, Hash]
): Hash {
if (!valid0 && !valid1) {
throw new Error("Invalid signature");
} else if (valid0) {
return sig0;
} else {
return sig1;
}
}
}
5 changes: 3 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from "./chains/ethereum";
export * from "./mpcContract";
export * from "./chains/near";
export * from "./types";
export * from "./mpcContract";
export * from "./types/types";
export * from "./utils/signature";
export * from "./network";
10 changes: 5 additions & 5 deletions src/mpcContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
MPCSignature,
NearContractFunctionPayload,
SignArgs,
} from "./types";
} from "./types/types";

interface MultichainContractInterface extends Contract {
// Define the signature for the `public_key` view method
Expand Down Expand Up @@ -70,10 +70,10 @@ export class MultichainContract {
return { big_r, big_s };
};

encodeSignatureRequestTx = async (
encodeSignatureRequestTx(
signArgs: SignArgs,
gas?: bigint
): Promise<NearContractFunctionPayload> => {
gas?: BN
): NearContractFunctionPayload {
return {
signerId: this.contract.account.accountId,
receiverId: this.contract.contractId,
Expand All @@ -89,5 +89,5 @@ export class MultichainContract {
},
],
};
};
}
}
133 changes: 133 additions & 0 deletions src/types/rpc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// Basic structure of the JSON-RPC response
export interface JSONRPCResponse {
jsonrpc: string;
result: Result;
id: string;
}

// Result contains various fields like final execution status, an array of receipts, etc.
export interface Result {
final_execution_status: string;
receipts: Receipt[];
receipts_outcome: ReceiptOutcome[];
status: TransactionStatus;
transaction: Transaction;
transaction_outcome: TransactionOutcome;
}

// Define Receipt type with its structure
interface Receipt {
predecessor_id: string;
receipt: ReceiptDetail;
receipt_id: string;
receiver_id: string;
}

// Detailed structure of a receipt which includes actions and other properties
interface ReceiptDetail {
Action: ActionDetail;
}

// Actions within the receipt
interface ActionDetail {
actions: Action[];
gas_price: string;
// TODO - determine types here and find a non-trivial example.
// cf: https://github.com/Mintbase/near-ca/issues/31
// input_data_ids: any[];
// output_data_receivers: any[];
signer_id: string;
signer_public_key: string;
}

// Action can have different types like FunctionCall or Transfer
interface Action {
FunctionCall?: FunctionCall;
Transfer?: Transfer;
}

// FunctionCall action specifics
interface FunctionCall {
args: string;
deposit: string;
gas: number;
method_name: string;
}

// Transfer action specifics
interface Transfer {
deposit: string;
}

// Receipt outcomes are listed in an array
export interface ReceiptOutcome {
block_hash: string;
id: string;
outcome: Outcome;
proof: Proof[];
}

// Outcome of executing the action
interface Outcome {
executor_id: string;
gas_burnt: number;
logs: string[];
metadata: Metadata;
receipt_ids: string[];
status: OutcomeStatus;
tokens_burnt: string;
}

// Metadata may contain various gas profiling information
interface Metadata {
gas_profile: GasProfile[];
version: number;
}

// Detailed gas usage per action or computation step
interface GasProfile {
cost: string;
cost_category: string;
gas_used: number;
}

// Status of the outcome, success or failure specifics
interface OutcomeStatus {
SuccessReceiptId?: string;
SuccessValue?: string;
}

// Proofs for the transaction validation
interface Proof {
direction: string;
hash: string;
}

// Status field detailing the transaction execution result
interface TransactionStatus {
SuccessValue: string;
}

// Transaction detail structure
interface Transaction {
actions: TransactionAction[];
hash: string;
nonce: number;
public_key: string;
receiver_id: string;
signature: string;
signer_id: string;
}

// Actions within a transaction
interface TransactionAction {
FunctionCall: FunctionCall;
}

// Transaction outcome mirrors structure similar to receipt outcomes
interface TransactionOutcome {
block_hash: string;
id: string;
outcome: Outcome;
proof: Proof[];
}
6 changes: 4 additions & 2 deletions src/types.ts → src/types/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MultichainContract } from "./mpcContract";
import { MultichainContract } from "../mpcContract";
import { FunctionCallAction } from "@near-wallet-selector/core";
import BN from "bn.js";
import { Hex } from "viem";
Expand All @@ -14,6 +14,8 @@ export interface BaseTx {
chainId: number;
/// Specified transaction nonce
nonce?: number;
/// optional gasLimit
gas?: bigint;
}

export interface NearEthAdapterParams {
Expand Down Expand Up @@ -52,7 +54,7 @@ export interface SignArgs {
}

export interface TxPayload {
/// Deserialized Ethereum Transaction.
/// Serialized Ethereum Transaction.
transaction: Hex;
/// Arguments required by Near MPC Contract signature request.
signArgs: SignArgs;
Expand Down
2 changes: 1 addition & 1 deletion src/utils/gasPrice.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GasPrices } from "../types";
import { GasPrices } from "../types/types";

interface GasPriceResponse {
code: number;
Expand Down
Loading

0 comments on commit f354f14

Please sign in to comment.