Skip to content

Commit

Permalink
Merge branch 'main' into wc-respond
Browse files Browse the repository at this point in the history
  • Loading branch information
bh2smith authored Aug 9, 2024
2 parents 61b7dfa + e0e656a commit ddc19e5
Show file tree
Hide file tree
Showing 12 changed files with 292 additions and 325 deletions.
12 changes: 6 additions & 6 deletions src/chains/ethereum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,27 @@ import {
} from "viem";
import {
BaseTx,
NearEthAdapterParams,
AdapterParams,
FunctionCallTransaction,
TxPayload,
TransactionWithSignature,
NearEthTxData,
SignArgs,
RecoveryData,
} from "../types/types";

Check failure on line 27 in src/chains/ethereum.ts

View workflow job for this annotation

GitHub Actions / types

Cannot find module '../types/types' or its corresponding type declarations.
import { MultichainContract } from "../mpcContract";
import { MpcContract } from "../mpcContract";
import { buildTxPayload, addSignature, populateTx } from "../utils/transaction";
import { Network } from "../network";
import { Web3WalletTypes } from "@walletconnect/web3wallet";
import { wcRouter } from "../wallet-connect/handlers";

export class NearEthAdapter {
readonly mpcContract: MultichainContract;
readonly mpcContract: MpcContract;
readonly address: Address;
readonly derivationPath: string;

private constructor(config: {
mpcContract: MultichainContract;
mpcContract: MpcContract;
derivationPath: string;
sender: Address;
}) {
Expand Down Expand Up @@ -66,9 +66,9 @@ export class NearEthAdapter {

/**
* Constructs an EVM instance with the provided configuration.
* @param {NearEthAdapterParams} args - The configuration object for the Adapter instance.
* @param {AdapterParams} args - The configuration object for the Adapter instance.
*/
static async fromConfig(args: NearEthAdapterParams): Promise<NearEthAdapter> {
static async fromConfig(args: AdapterParams): Promise<NearEthAdapter> {
// Sender is uniquely determined by the derivation path!
const mpcContract = args.mpcContract;
const derivationPath = args.derivationPath || "ethereum,1";
Expand Down
54 changes: 48 additions & 6 deletions src/chains/near.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,51 @@
import { keyStores, KeyPair, connect, Account } from "near-api-js";
import { NearConfig } from "near-api-js/lib/near";

export const TGAS = 1000000000000n;
export const NO_DEPOSIT = "0";
export const ONE_YOCTO = "1";

export interface NearConfig {
networkId: string;
nodeUrl: string;
type NetworkId = "mainnet" | "testnet";

/**
* Extracts the network ID from a given NEAR account ID.
* If the account ID does not end with "near" or "testnet", it logs a warning.
* Defaults to "mainnet" if the network ID is not "testnet".
*
* @param accountId - The NEAR account ID to extract the network ID from.
* @returns The network ID, either "mainnet" or "testnet".
*/
export function getNetworkId(accountId: string): NetworkId {
const accountExt = accountId.split(".").pop() || "";
if (!["near", "testnet"].includes(accountExt)) {
console.warn(
`Unusual or invalid network extracted from accountId ${accountId}`
);
}
// Consider anything that isn't testnet as mainnet.
return accountExt !== "testnet" ? "mainnet" : accountExt;
}

/**
* Generates a NEAR configuration object based on the provided network ID.
*
* @param networkId - The network ID, either "mainnet" or "testnet".
* @returns A NearConfig object containing the network ID and node URL.
*/
export function configFromNetworkId(networkId: NetworkId): NearConfig {
return {
networkId,
nodeUrl: `https://rpc.${networkId}.near.org`,
};
}

/**
* Loads Near Account from provided keyPair and accountId
* Defaults to TESTNET_CONFIG
*
* @param keyPair {KeyPair}
* @param accountId {string}
* @param network {NearConfig} network settings
* @returns {Account}
* @returns A Promise that resolves to a NEAR Account instance.
*/
export const nearAccountFromKeyPair = async (config: {
keyPair: KeyPair;
Expand All @@ -25,8 +55,12 @@ export const nearAccountFromKeyPair = async (config: {
return createNearAccount(config.accountId, config.network, config.keyPair);
};

/** Minimally sufficient Account instance to construct the signing contract instance.
/** Minimally sufficient Account instance to construct readonly MpcContract connection.
* Can't be used to change methods.
*
* @param accountId {string}
* @param network {NearConfig} network settings
* @returns A Promise that resolves to a NEAR Account instance.
*/
export const nearAccountFromAccountId = async (
accountId: string,
Expand All @@ -35,6 +69,14 @@ export const nearAccountFromAccountId = async (
return createNearAccount(accountId, network);
};

/**
* Creates a NEAR account instance using the provided account ID, network configuration, and optional key pair.
*
* @param accountId - The NEAR account ID.
* @param network - The NEAR network configuration.
* @param keyPair - (Optional) The key pair for the account.
* @returns A Promise that resolves to a NEAR Account instance.
*/
export const createNearAccount = async (
accountId: string,
network: NearConfig,
Expand Down
42 changes: 19 additions & 23 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
import { Account, KeyPair } from "near-api-js";
import { NearEthAdapter } from "./chains/ethereum";
import { MultichainContract } from "./mpcContract";
import { MpcContract } from "./mpcContract";
import { NearConfig } from "near-api-js/lib/near";
import { createNearAccount } from "./chains/near";
import {
configFromNetworkId,
createNearAccount,
getNetworkId,
} from "./chains/near";

export * from "./chains/ethereum";
export * from "./chains/near";
export * from "./mpcContract";
export * from "./types/types";
export * from "./types";
export * from "./utils/signature";
export * from "./network";
export * from "./utils/transaction";

/**
* Configuration for setting up the adapter.
*
* @property {string} accountId - The NEAR account ID.
* @property {string} mpcContractId - The MPC contract ID.
* @property {NearConfig} [network] - (Optional) The NEAR network configuration.
* @property {string} [privateKey] - (Optional) The private key for the account.
* @property {string} [derivationPath] - (Optional) The derivation path for the Ethereum account. Defaults to "ethereum,1".
*/
interface SetupConfig {
accountId: string;
mpcContractId: string;
Expand All @@ -20,24 +33,6 @@ interface SetupConfig {
derivationPath?: string;
}

type NetworkId = "near" | "testnet";

function getNetworkId(accountId: string): NetworkId {
const networkId = accountId.split(".").pop() || "";
if (!["near", "testnet"].includes(networkId)) {
throw new Error(`Invalid network extracted from accountId ${accountId}`);
}
return networkId as NetworkId;
}

export function configFromNetworkId(networkId: NetworkId): NearConfig {
const network = networkId === "near" ? "mainnet" : "testnet";
return {
networkId,
nodeUrl: `https://rpc.${network}.near.org`,
};
}

export async function setupAdapter(args: SetupConfig): Promise<NearEthAdapter> {
const {
accountId,
Expand All @@ -50,7 +45,7 @@ export async function setupAdapter(args: SetupConfig): Promise<NearEthAdapter> {
const config = args.network ?? configFromNetworkId(accountNetwork);
if (accountNetwork !== config.networkId) {
throw new Error(
`The accountId ${accountId} does not match the networkId ${config.networkId}. Please ensure that your accountId is correct and corresponds to the intended network.`
`accountId ${accountId} doesn't match the networkId ${config.networkId}. Please ensure that your accountId is correct and corresponds to the intended network.`
);
}

Expand All @@ -59,14 +54,15 @@ export async function setupAdapter(args: SetupConfig): Promise<NearEthAdapter> {
account = await createNearAccount(
accountId,
config,
// Without private key, MPC contract connection is read-only.
privateKey ? KeyPair.fromString(privateKey) : undefined
);
} catch (error: unknown) {
console.error(`Failed to create NEAR account: ${error}`);
throw error;
}
return NearEthAdapter.fromConfig({
mpcContract: new MultichainContract(account, mpcContractId),
mpcContract: new MpcContract(account, mpcContractId),
derivationPath: derivationPath,
});
}
24 changes: 14 additions & 10 deletions src/mpcContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,26 @@ import {
uncompressedHexPointToEvmAddress,
} from "./utils/kdf";
import { TGAS, ONE_YOCTO } from "./chains/near";
import { MPCSignature, FunctionCallTransaction, SignArgs } from "./types/types";
import { MPCSignature, FunctionCallTransaction, SignArgs } from "./types";
import { transformSignature } from "./utils/signature";

/// Near Contract Type for change methods
/**
* Near Contract Type for change methods.
*
* @template T - The type of the arguments for the change method.
* @property {T} args - Change method function arguments.
* @property {string} gas - Gas limit on transaction execution.
* @property {Account} signerAccount - Account signing the call.
* @property {string} amount - Attached deposit (i.e., payable amount) to attach to the transaction.
*/
export interface ChangeMethodArgs<T> {
/// Change method function agruments.
args: T;
/// GasLimit on transaction execution.
gas: string;
/// Account Signing the call
signerAccount: Account;
/// attachedDeposit (i.e. payable amount) to attach to transaction.
amount: string;
}

interface MultichainContractInterface extends Contract {
interface MpcContractInterface extends Contract {
// Define the signature for the `public_key` view method
public_key: () => Promise<string>;

Expand All @@ -35,8 +39,8 @@ interface MultichainContractInterface extends Contract {
* High-level interface for the Near MPC-Recovery Contract
* located in: https://github.com/near/mpc-recovery
*/
export class MultichainContract {
contract: MultichainContractInterface;
export class MpcContract {
contract: MpcContractInterface;
connectedAccount: Account;

constructor(account: Account, contractId: string) {
Expand All @@ -46,7 +50,7 @@ export class MultichainContract {
changeMethods: ["sign"],
viewMethods: ["public_key"],
useLocalViewExecution: false,
}) as MultichainContractInterface;
}) as MpcContractInterface;
}

accountId(): string {
Expand Down
Loading

0 comments on commit ddc19e5

Please sign in to comment.