diff --git a/src/chains/ethereum.ts b/src/chains/ethereum.ts index 3eb0f6f..ace8277 100644 --- a/src/chains/ethereum.ts +++ b/src/chains/ethereum.ts @@ -22,7 +22,7 @@ import { TxPayload, TransactionWithSignature, } from "../types"; -import { MultichainContract } from "../mpcContract"; +import { MultichainContract } from "../contracts/mpc"; import BN from "bn.js"; import { queryGasPrice } from "../utils/gasPrice"; import { buildTxPayload, addSignature } from "../utils/transaction"; diff --git a/src/chains/near.ts b/src/chains/near.ts index 12e2fd6..08cd5c0 100644 --- a/src/chains/near.ts +++ b/src/chains/near.ts @@ -3,7 +3,7 @@ import { keyStores, KeyPair, connect, Account } from "near-api-js"; import { Wallet } from "@near-wallet-selector/core"; export const TGAS = new BN(1000000000000); -export const NO_DEPOSIT = "0"; +export const NO_DEPOSIT = new BN("0"); export interface NearConfig { networkId: string; diff --git a/src/contracts/gas_station.ts b/src/contracts/gas_station.ts new file mode 100644 index 0000000..f85d828 --- /dev/null +++ b/src/contracts/gas_station.ts @@ -0,0 +1,125 @@ +import { Contract, Account } from "near-api-js"; +import { NO_DEPOSIT, TGAS, nearAccountFromEnv } from "../chains/near"; +import { ChangeMethodArgs } from "../types"; +import BN from "bn.js"; + +interface GetPaymasterArgs { + chain_id: string; +} + +interface PaymasterConfiguration { + nonce: number; + token_id: string; + foreign_address: string; + minimum_available_balance: bigint; +} + +interface SetPaymasterNonceArgs { + chain_id: string; + token_id: string; + nonce: number; +} + +interface CreateTxArgs { + transaction_rlp_hex: string; + use_paymaster: boolean; + token_id: string; +} + +interface SignNextArgs { + id: string; +} + +interface TransactionSequenceCreation { + id: bigint; + pending_signature_count: number; +} + +interface GasStationInterface extends Contract { + // TODO - determine return types... + get_paymasters: ( + args: ChangeMethodArgs + ) => Promise; + set_paymaster_nonce: ( + args: ChangeMethodArgs + ) => Promise; + create_transaction: ( + args: ChangeMethodArgs + ) => Promise; + /// This returns some deep nested Promise Type... + sign_next: (args: ChangeMethodArgs) => Promise; +} + +/** + * High-level interface for the Near MPC-Recovery Contract + * located in: https://github.com/near/mpc-recovery + */ +export class GasStationContract { + contract: GasStationInterface; + + constructor(account: Account, contractId: string) { + this.contract = new Contract(account, contractId, { + changeMethods: [ + "get_paymasters", + "set_paymaster_nonce", + "create_transaction", + "sign_next", + ], + viewMethods: [], + useLocalViewExecution: false, + }) as GasStationInterface; + } + + static async fromEnv(): Promise { + const account = await nearAccountFromEnv(); + return new GasStationContract( + account, + process.env.NEAR_MULTICHAIN_CONTRACT! + ); + } + + async get_paymasters( + args: GetPaymasterArgs, + gas?: BN + ): Promise { + const paymasters = await this.contract.get_paymasters({ + args, + gas: gas || TGAS.muln(100), + attachedDeposit: NO_DEPOSIT, + }); + return paymasters; + } + + async set_paymaster_nonce( + args: SetPaymasterNonceArgs, + gas?: BN + ): Promise { + this.contract.set_paymaster_nonce({ + args, + gas: gas || TGAS.muln(100), + attachedDeposit: NO_DEPOSIT, + }); + } + + async create_transaction( + args: CreateTxArgs, + attachedDeposit: BN, + gas?: BN + ): Promise { + const sequence = await this.contract.create_transaction({ + args, + gas: gas || TGAS.muln(100), + attachedDeposit, + }); + return sequence; + } + + async sign_next(args: SignNextArgs, gas?: BN): Promise { + // TODO - determine return type. + await this.contract.sign_next({ + args, + gas: gas || TGAS.muln(100), + attachedDeposit: NO_DEPOSIT, + }); + } +} diff --git a/src/mpcContract.ts b/src/contracts/mpc.ts similarity index 87% rename from src/mpcContract.ts rename to src/contracts/mpc.ts index 4415ac3..823febd 100644 --- a/src/mpcContract.ts +++ b/src/contracts/mpc.ts @@ -4,17 +4,17 @@ import { deriveChildPublicKey, najPublicKeyStrToUncompressedHexPoint, uncompressedHexPointToEvmAddress, -} from "./utils/kdf"; -import { NO_DEPOSIT, nearAccountFromEnv, TGAS } from "./chains/near"; +} from "../utils/kdf"; +import { NO_DEPOSIT, nearAccountFromEnv, TGAS } from "../chains/near"; import BN from "bn.js"; import { ChangeMethodArgs, MPCSignature, NearContractFunctionPayload, SignArgs, -} from "./types"; +} from "../types"; -interface MultichainContractInterface extends Contract { +interface MPCInterface extends Contract { // Define the signature for the `public_key` view method public_key: () => Promise; @@ -27,14 +27,14 @@ interface MultichainContractInterface extends Contract { * located in: https://github.com/near/mpc-recovery */ export class MultichainContract { - contract: MultichainContractInterface; + contract: MPCInterface; constructor(account: Account, contractId: string) { this.contract = new Contract(account, contractId, { changeMethods: ["sign"], viewMethods: ["public_key"], useLocalViewExecution: false, - }) as MultichainContractInterface; + }) as MPCInterface; } static async fromEnv(): Promise { @@ -65,7 +65,7 @@ export class MultichainContract { args: signArgs, // Default of 200 TGAS gas: gas || TGAS.muln(200), - attachedDeposit: new BN(NO_DEPOSIT), + attachedDeposit: NO_DEPOSIT, }); return { big_r, big_s }; }; @@ -84,7 +84,7 @@ export class MultichainContract { methodName: "sign", args: signArgs, gas: (gas || TGAS.muln(200)).toString(), - deposit: NO_DEPOSIT, + deposit: NO_DEPOSIT.toString(), }, }, ], diff --git a/src/contracts/nft_key.ts b/src/contracts/nft_key.ts new file mode 100644 index 0000000..f74e357 --- /dev/null +++ b/src/contracts/nft_key.ts @@ -0,0 +1,62 @@ +import { Contract, Account } from "near-api-js"; +import { NO_DEPOSIT, TGAS, nearAccountFromEnv } from "../chains/near"; +import { ChangeMethodArgs } from "../types"; +import BN from "bn.js"; + +interface CktApproveArgs { + token_id: bigint; + account_id: string; + msg: string; +} + +interface NftKeyInterface extends Contract { + // TODO - determine return types... + storage_deposit: (args: ChangeMethodArgs) => Promise; + mint: (args: ChangeMethodArgs) => Promise; + ckt_approve: (args: ChangeMethodArgs) => Promise; +} + +/** + * High-level interface for the Near MPC-Recovery Contract + * located in: https://github.com/near/mpc-recovery + */ +export class NftKeyContract { + contract: NftKeyInterface; + + constructor(account: Account, contractId: string) { + this.contract = new Contract(account, contractId, { + changeMethods: ["storage_deposit", "mint", "ckt_approve"], + viewMethods: [], + useLocalViewExecution: false, + }) as NftKeyInterface; + } + + static async fromEnv(): Promise { + const account = await nearAccountFromEnv(); + return new NftKeyContract(account, process.env.NEAR_MULTICHAIN_CONTRACT!); + } + + async storage_deposit(attachedDeposit: bigint, gas?: BN): Promise { + await this.contract.storage_deposit({ + args: {}, + gas: gas || TGAS.muln(100), + attachedDeposit: new BN(attachedDeposit.toString()), + }); + } + + async mint(gas?: BN): Promise { + await this.contract.mint({ + args: {}, + gas: gas || TGAS.muln(100), + attachedDeposit: NO_DEPOSIT, + }); + } + + async ckt_approve(args: CktApproveArgs, gas?: BN): Promise { + await this.contract.mint({ + args, + gas: gas || TGAS.muln(100), + attachedDeposit: NO_DEPOSIT, + }); + } +} diff --git a/src/index.ts b/src/index.ts index 74b4ab4..85e7a8d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ export * from "./chains/ethereum"; -export * from "./mpcContract"; +export * from "./contracts/mpc"; export * from "./chains/near"; export * from "./types"; export * from "./network"; diff --git a/src/types.ts b/src/types.ts index a1fe3e9..0ddf4f5 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -import { MultichainContract } from "./mpcContract"; +import { MultichainContract } from "./contracts/mpc"; import { FunctionCallAction } from "@near-wallet-selector/core"; import BN from "bn.js"; import { Hex } from "viem"; diff --git a/tests/e2e.test.ts b/tests/e2e.test.ts index e47a382..10d2555 100644 --- a/tests/e2e.test.ts +++ b/tests/e2e.test.ts @@ -13,7 +13,7 @@ describe("End To End", () => { }); afterAll(async () => { - clearTimeout(); + clearTimeout(undefined); }); it("signAndSendTransaction", async () => {