Skip to content

Commit

Permalink
Migrate to TSDoc (from JSDoc) (#163)
Browse files Browse the repository at this point in the history
  • Loading branch information
bh2smith authored Feb 25, 2025
1 parent 01b8f41 commit b492517
Show file tree
Hide file tree
Showing 16 changed files with 639 additions and 363 deletions.
27 changes: 26 additions & 1 deletion src/beta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,39 @@ import { isSignMethod, NearEncodedSignRequest, signMethods } from "./types";
import { NearEthAdapter } from "./chains/ethereum";
import { requestRouter } from "./utils/request";

/**
* Removes the EIP-155 prefix from an address string
*
* @param eip155Address - The EIP-155 formatted address
* @returns The address without the EIP-155 prefix
*/
function stripEip155Prefix(eip155Address: string): string {
return eip155Address.split(":").pop() ?? "";
}

/**
* Features currently underdevelopment that will be migrated into the adapter class once refined.
* Features currently under development that will be migrated into the adapter class once refined.
* These features are accessible through the adapter class as `adapter.beta.methodName(...)`
*/
export class Beta {
adapter: NearEthAdapter;

/**
* Creates a new Beta instance
*
* @param adapter - The NearEthAdapter instance to use
*/
constructor(adapter: NearEthAdapter) {
this.adapter = adapter;
}

/**
* Handles a WalletConnect session request by encoding it for NEAR
*
* @param request - The WalletConnect session request
* @returns The encoded request for NEAR
* @throws Error if the sign method is not supported
*/
async handleSessionRequest(
request: Partial<WalletKitTypes.SessionRequest>
): Promise<NearEncodedSignRequest> {
Expand Down Expand Up @@ -52,6 +70,13 @@ export class Beta {
};
}

/**
* Responds to a session request with a signature
*
* @param signature - The signature to respond with
* @param transaction - Optional transaction hex
* @returns The serialized signature or transaction hash
*/
async respondSessionRequest(
signature: Signature,
transaction?: Hex
Expand Down
101 changes: 59 additions & 42 deletions src/chains/ethereum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ import { Beta } from "../beta";
import { requestRouter } from "../utils/request";
import { Account } from "near-api-js";

/**
* Adapter class for interacting with Ethereum through NEAR MPC contract
*/
export class NearEthAdapter {
readonly mpcContract: IMpcContract;
readonly address: Address;
Expand All @@ -47,36 +50,41 @@ export class NearEthAdapter {
}

/**
* @returns Near Account linked to derived EVM account.
* Gets the NEAR Account linked to derived EVM account
*
* @returns The connected NEAR Account
*/
nearAccount(): Account {
return this.mpcContract.connectedAccount;
}

/**
* @returns Near accountId linked to derived EVM account.
* Gets the NEAR account ID linked to derived EVM account
*
* @returns The connected NEAR account ID
*/
nearAccountId(): string {
return this.mpcContract.connectedAccount.accountId;
}

/**
* Retrieves the balance of the Ethereum address associated with this adapter.
* Retrieves the balance of the Ethereum address associated with this adapter
*
* @param {number} chainId - The chain ID of the Ethereum network to query.
* @returns {Promise<bigint>} - A promise that resolves to the balance of the address in wei.
* @param chainId - The chain ID of the Ethereum network to query
* @returns The balance of the address in wei
*/
async getBalance(chainId: number): Promise<bigint> {
const network = Network.fromChainId(chainId);
return network.client.getBalance({ address: this.address });
}

/**
* Constructs an EVM instance with the provided configuration.
* @param {AdapterParams} args - The configuration object for the Adapter instance.
* 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: AdapterParams): Promise<NearEthAdapter> {
// Sender is uniquely determined by the derivation path!
const mpcContract = args.mpcContract;
const derivationPath = args.derivationPath || "ethereum,1";
return new NearEthAdapter({
Expand All @@ -87,11 +95,12 @@ export class NearEthAdapter {
}

/**
* Constructs an EVM instance with the provided configuration.
* @param {AdapterParams} args - The configuration object for the Adapter instance.
* Creates a mocked EVM instance with the provided configuration
*
* @param args - The configuration object for the Adapter instance
* @returns A new mocked NearEthAdapter instance
*/
static async mocked(args: AdapterParams): Promise<NearEthAdapter> {
// Sender is uniquely determined by the derivation path!
const mpcContract = args.mpcContract;
const derivationPath = args.derivationPath || "ethereum,1";
return new NearEthAdapter({
Expand All @@ -104,11 +113,11 @@ export class NearEthAdapter {
/**
* 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.
* 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 {bigint} nearGas - manually specified gas to be sent with signature request.
* Note that the signature request is a recursive function.
* @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: BaseTx,
Expand All @@ -125,11 +134,11 @@ export class NearEthAdapter {
/**
* 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.
* and prepares the signature request payload for the Near MPC Contract
*
* @param {BaseTx} txData - Minimal transaction data to be signed by Near MPC and executed on EVM.
* @param {bigint} nearGas - manually specified gas to be sent with signature request.
* Note that the signature request is a recursive function.
* @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: BaseTx,
Expand All @@ -149,10 +158,11 @@ export class NearEthAdapter {
}

/**
* Builds a Near Transaction Payload for Signing serialized EVM Transaction.
* @param {Hex} transaction RLP encoded (i.e. serialized) Ethereum Transaction
* @param nearGas optional gas parameter
* @returns {FunctionCallTransaction<SignArgs>} Prepared Near Transaction with signerId as this.address
* 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: Hex,
Expand All @@ -170,11 +180,10 @@ export class NearEthAdapter {

/**
* Builds a complete, unsigned transaction (with nonce, gas estimates, current prices)
* and payload bytes in preparation to be relayed to Near MPC contract.
* and payload bytes in preparation to be relayed to Near MPC contract
*
* @param {BaseTx} tx - Minimal transaction data to be signed by Near MPC and executed on EVM.
* @param {number?} nonce - Optional transaction nonce.
* @returns Transaction and its bytes (the payload to be signed on Near).
* @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: BaseTx): Promise<TxPayload> {
const transaction = await this.buildTransaction(tx);
Expand All @@ -187,32 +196,44 @@ export class NearEthAdapter {
}

/**
* Transforms minimal transaction request data into a fully populated EVM transaction.
* @param {BaseTx} tx - Minimal transaction request data
* @returns {Hex} serialized (aka RLP encoded) transaction.
* 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: BaseTx): Promise<Hex> {
const transaction = await populateTx(tx, this.address);
return serializeTransaction(transaction);
}

// Below code is inspired by https://github.com/Connor-ETHSeoul/near-viem

/**
* Signs typed data according to EIP-712
*
* @param typedData - The typed data to sign
* @returns The signature hash
*/
async signTypedData<
const typedData extends TypedData | Record<string, unknown>,
primaryType extends keyof typedData | "EIP712Domain" = keyof typedData,
>(typedData: TypedDataDefinition<typedData, primaryType>): Promise<Hash> {
return this.sign(hashTypedData(typedData));
}

/**
* Signs a message according to personal_sign
*
* @param message - The message to sign
* @returns The signature hash
*/
async signMessage(message: SignableMessage): Promise<Hash> {
return this.sign(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).
* 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: `0x${string}` | Uint8Array): Promise<Hex> {
const signature = await this.mpcContract.requestSignature({
Expand All @@ -224,14 +245,10 @@ export class NearEthAdapter {
}

/**
* Encodes a signature request for submission to the Near-Ethereum transaction MPC contract.
* Encodes a signature request for submission to the Near-Ethereum transaction MPC contract
*
* @async
* @function encodeSignRequest
* @param {SignRequestData} signRequest - The signature request data containing method, chain ID, and parameters.
* @returns {Promise<NearEthTxData>}
* - Returns a promise that resolves to an object containing the encoded Near-Ethereum transaction data,
* the original EVM message, and recovery data necessary for verifying or reconstructing the signature.
* @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: SignRequestData
Expand Down
2 changes: 2 additions & 0 deletions src/chains/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./ethereum";
export * from "./near";
57 changes: 29 additions & 28 deletions src/chains/near.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { keyStores, KeyPair, connect, Account } from "near-api-js";
import { NearConfig } from "near-api-js/lib/near";
import { NearAccountConfig } from "../types/interfaces";

/** Gas unit constant for NEAR transactions (1 TeraGas) */
export const TGAS = 1000000000000n;

/** Default deposit value for NEAR transactions */
export const NO_DEPOSIT = "0";

/** Valid NEAR network identifiers */
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".
* Extracts the network ID from a given NEAR account ID
*
* @param accountId - The NEAR account ID to extract the network ID from.
* @returns The network ID, either "mainnet" or "testnet".
* @param accountId - The NEAR account ID to analyze
* @returns The network ID ("mainnet" or "testnet")
* @remarks If the account ID doesn't end with "near" or "testnet", defaults to "mainnet"
*/
export function getNetworkId(accountId: string): NetworkId {
const accountExt = accountId.split(".").pop() || "";
Expand All @@ -21,10 +25,10 @@ export function getNetworkId(accountId: string): NetworkId {
}

/**
* Generates a NEAR configuration object based on the provided network ID.
* Generates a NEAR configuration object for a specific network
*
* @param networkId - The network ID, either "mainnet" or "testnet".
* @returns A NearConfig object containing the network ID and node URL.
* @param networkId - The target network identifier
* @returns Configuration object for NEAR connection
*/
export function configFromNetworkId(networkId: NetworkId): NearConfig {
return {
Expand All @@ -34,27 +38,24 @@ export function configFromNetworkId(networkId: NetworkId): NearConfig {
}

/**
* Loads Near Account from provided keyPair and accountId
* Creates a NEAR Account instance from provided credentials
*
* @param keyPair {KeyPair}
* @param accountId {string}
* @param network {NearConfig} network settings
* @returns A Promise that resolves to a NEAR Account instance.
* @param config - Configuration containing account ID, network, and key pair
* @returns A NEAR Account instance
*/
export const nearAccountFromKeyPair = async (config: {
keyPair: KeyPair;
accountId: string;
network: NearConfig;
}): Promise<Account> => {
export const nearAccountFromKeyPair = async (
config: NearAccountConfig
): Promise<Account> => {
return createNearAccount(config.accountId, config.network, config.keyPair);
};

/** Minimally sufficient Account instance to construct readonly MpcContract connection.
* Can't be used to change methods.
/**
* Creates a read-only NEAR Account instance from an account ID
*
* @param accountId {string}
* @param network {NearConfig} network settings
* @returns A Promise that resolves to a NEAR Account instance.
* @param accountId - The NEAR account identifier
* @param network - The NEAR network configuration
* @returns A read-only NEAR Account instance
* @remarks This account cannot perform write operations
*/
export const nearAccountFromAccountId = async (
accountId: string,
Expand All @@ -64,12 +65,12 @@ export const nearAccountFromAccountId = async (
};

/**
* Creates a NEAR account instance using the provided account ID, network configuration, and optional key pair.
* Creates a NEAR Account instance with optional write capabilities
*
* @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.
* @param accountId - The NEAR account identifier
* @param network - The NEAR network configuration
* @param keyPair - Optional key pair for write access
* @returns A NEAR Account instance
*/
export const createNearAccount = async (
accountId: string,
Expand Down
Loading

0 comments on commit b492517

Please sign in to comment.