From 5429380c2f81337bb230e6fc015bcd026f5b0ac0 Mon Sep 17 00:00:00 2001 From: Georgi Tsonev Date: Tue, 1 Oct 2024 13:36:16 +0300 Subject: [PATCH 1/5] Add signTransaction() to BaseWalletBehaviour interface --- packages/core/src/lib/wallet/wallet.types.ts | 62 ++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/packages/core/src/lib/wallet/wallet.types.ts b/packages/core/src/lib/wallet/wallet.types.ts index 9ef2c7cae..7a6e57bf4 100644 --- a/packages/core/src/lib/wallet/wallet.types.ts +++ b/packages/core/src/lib/wallet/wallet.types.ts @@ -10,6 +10,11 @@ import type { ReadOnlyStore } from "../store.types"; import type { Transaction, Action } from "./transactions.types"; import type { Modify, Optional } from "../utils.types"; import type { FinalExecutionOutcome } from "near-api-js/lib/providers"; +import type { + SignedTransaction, + Transaction as Tx, +} from "near-api-js/lib/transaction"; +import type { Signer } from "near-api-js/lib/signer"; interface BaseWalletMetadata { /** @@ -121,6 +126,56 @@ interface SignAndSendTransactionsParams { transactions: Array>; } +interface SignTransactionParams { + /** + * The Transaction object to sign + */ + transaction: Tx; + /** + * The {Signer} object that assists with signing keys + */ + signer: Signer; + /** + * The human-readable NEAR account name + */ + accountId?: string; + /** + * The targeted network. (ex. default, betanet, etc…) + */ + networkId?: string; +} + +interface SignTransactionActionsParams { + /** + * The NEAR account ID of the transaction receiver. + */ + receiverId: string; + /** + * Tx nonce. + */ + nonce: bigint; + /** + * NEAR Action(s) to sign and send to the network (e.g. `FunctionCall`). You can find more information on `Action` {@link https://github.com/near/wallet-selector/blob/main/packages/core/docs/api/transactions.md | here}. + */ + actions: Array; + /** + * Block hash + */ + blockHash: Uint8Array; + /** + * The {Signer} object that assists with signing keys + */ + signer: Signer; + /** + * The human-readable NEAR account name + */ + accountId?: string; + /** + * The targeted network. (ex. default, betanet, etc…) + */ + networkId?: string; +} + interface BaseWalletBehaviour { /** * Programmatically sign in. Hardware wallets (e.g. Ledger) require `derivationPaths` to validate access key permissions. @@ -155,6 +210,13 @@ interface BaseWalletBehaviour { params: SignAndSendTransactionsParams ): Promise>; signMessage?(params: SignMessageParams): Promise; + /** + * Signs one or more NEAR Actions which can be broadcasted to the network. + * The user must be signed in to call this method. + */ + signTransaction( + params: SignTransactionParams | SignTransactionActionsParams + ): Promise<[Uint8Array, SignedTransaction]>; } type BaseWallet< From 2676f27fab7034d7ce4c1f7325dd8e18d190350e Mon Sep 17 00:00:00 2001 From: Georgi Tsonev Date: Tue, 1 Oct 2024 13:56:06 +0300 Subject: [PATCH 2/5] make signTransaction optional --- packages/core/src/lib/wallet/wallet.types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/lib/wallet/wallet.types.ts b/packages/core/src/lib/wallet/wallet.types.ts index 7a6e57bf4..bd22218d8 100644 --- a/packages/core/src/lib/wallet/wallet.types.ts +++ b/packages/core/src/lib/wallet/wallet.types.ts @@ -214,7 +214,7 @@ interface BaseWalletBehaviour { * Signs one or more NEAR Actions which can be broadcasted to the network. * The user must be signed in to call this method. */ - signTransaction( + signTransaction?( params: SignTransactionParams | SignTransactionActionsParams ): Promise<[Uint8Array, SignedTransaction]>; } From 55623dff6e0c474f8ddc9407710a829089642f51 Mon Sep 17 00:00:00 2001 From: Georgi Tsonev Date: Tue, 1 Oct 2024 15:09:40 +0300 Subject: [PATCH 3/5] Add signTransaction in decorateWallet() --- .../services/wallet-modules/wallet-modules.service.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/core/src/lib/services/wallet-modules/wallet-modules.service.ts b/packages/core/src/lib/services/wallet-modules/wallet-modules.service.ts index df954b930..298ba3666 100644 --- a/packages/core/src/lib/services/wallet-modules/wallet-modules.service.ts +++ b/packages/core/src/lib/services/wallet-modules/wallet-modules.service.ts @@ -301,6 +301,7 @@ export class WalletModules { const _signIn = wallet.signIn; const _signOut = wallet.signOut; const _signMessage = wallet.signMessage; + const _signTransaction = wallet.signTransaction; wallet.signIn = async (params: never) => { const accounts = await _signIn(params); @@ -332,6 +333,16 @@ export class WalletModules { return await _signMessage(params); }; + wallet.signTransaction = async (params: never) => { + if (_signTransaction === undefined) { + throw Error( + `The signTransaction method is not supported by ${wallet.metadata.name}` + ); + } + + return await _signTransaction(params); + }; + return wallet; } From 7465b61b87592da05a77ddd8e051c1c33ec27b5f Mon Sep 17 00:00:00 2001 From: Georgi Tsonev Date: Wed, 2 Oct 2024 10:18:00 +0300 Subject: [PATCH 4/5] Refactor signTransaction --- .../wallet-modules/wallet-modules.service.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/core/src/lib/services/wallet-modules/wallet-modules.service.ts b/packages/core/src/lib/services/wallet-modules/wallet-modules.service.ts index 298ba3666..7202a7525 100644 --- a/packages/core/src/lib/services/wallet-modules/wallet-modules.service.ts +++ b/packages/core/src/lib/services/wallet-modules/wallet-modules.service.ts @@ -335,12 +335,20 @@ export class WalletModules { wallet.signTransaction = async (params: never) => { if (_signTransaction === undefined) { - throw Error( + throw new Error( `The signTransaction method is not supported by ${wallet.metadata.name}` ); } - return await _signTransaction(params); + try { + return await _signTransaction(params); + } catch (error) { + throw new Error( + `Failed to sign transaction: ${ + error instanceof Error ? error.message : String(error) + }` + ); + } }; return wallet; From de49ad1caf829cb507ad58acd2180d0959e2265c Mon Sep 17 00:00:00 2001 From: Georgi Tsonev Date: Wed, 16 Oct 2024 15:25:48 +0300 Subject: [PATCH 5/5] Add signDelegateAction to BaseWalletBehaviour --- .../wallet-modules/wallet-modules.service.ts | 19 ++++++ packages/core/src/lib/wallet/wallet.types.ts | 64 +++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/packages/core/src/lib/services/wallet-modules/wallet-modules.service.ts b/packages/core/src/lib/services/wallet-modules/wallet-modules.service.ts index 7202a7525..409cda0e7 100644 --- a/packages/core/src/lib/services/wallet-modules/wallet-modules.service.ts +++ b/packages/core/src/lib/services/wallet-modules/wallet-modules.service.ts @@ -302,6 +302,7 @@ export class WalletModules { const _signOut = wallet.signOut; const _signMessage = wallet.signMessage; const _signTransaction = wallet.signTransaction; + const _signDelegateAction = wallet.signDelegateAction; wallet.signIn = async (params: never) => { const accounts = await _signIn(params); @@ -351,6 +352,24 @@ export class WalletModules { } }; + wallet.signDelegateAction = async (params: never) => { + if (_signDelegateAction === undefined) { + throw new Error( + `The signDelegateAction method is not supported by ${wallet.metadata.name}` + ); + } + + try { + return await _signDelegateAction(params); + } catch (error) { + throw new Error( + `Failed to sign delegate action: ${ + error instanceof Error ? error.message : String(error) + }` + ); + } + }; + return wallet; } diff --git a/packages/core/src/lib/wallet/wallet.types.ts b/packages/core/src/lib/wallet/wallet.types.ts index bd22218d8..454189e3e 100644 --- a/packages/core/src/lib/wallet/wallet.types.ts +++ b/packages/core/src/lib/wallet/wallet.types.ts @@ -13,8 +13,10 @@ import type { FinalExecutionOutcome } from "near-api-js/lib/providers"; import type { SignedTransaction, Transaction as Tx, + Signature, } from "near-api-js/lib/transaction"; import type { Signer } from "near-api-js/lib/signer"; +import type { PublicKey } from "near-api-js/lib/utils"; interface BaseWalletMetadata { /** @@ -176,6 +178,62 @@ interface SignTransactionActionsParams { networkId?: string; } +interface MessageSigner { + sign(message: Uint8Array): Promise; +} + +interface DelegateAction { + /** + * Account ID for the intended signer of the delegate action + */ + senderId: string; + /** + * The set of actions to be included in the meta transaction + */ + actions: Array; + /** + * Number of blocks past the current block height for which the SignedDelegate action may be included in a meta transaction + */ + blockHeightTtl: number; + /** + * Account ID for the intended receiver of the meta transaction + */ + receiverId: string; + /** + * Current nonce on the access key used to sign the delegate action + */ + nonce: bigint; + /** + * The maximum block height for which this action can be executed as part of a transaction + */ + maxBlockHeight: bigint; + /** + * Public key for the access key used to sign the delegate action + */ + publicKey: PublicKey; +} + +interface SignDelegateOptions { + /** + * Delegate action to be signed by the meta transaction sender + */ + delegateAction: DelegateAction; + /** + * Signer instance for the meta transaction sender + */ + signer: MessageSigner; +} + +interface SignedDelegate { + delegateAction: DelegateAction; + signature: Signature; +} + +interface SignedDelegateWithHash { + hash: Uint8Array; + signedDelegateAction: SignedDelegate; +} + interface BaseWalletBehaviour { /** * Programmatically sign in. Hardware wallets (e.g. Ledger) require `derivationPaths` to validate access key permissions. @@ -217,6 +275,12 @@ interface BaseWalletBehaviour { signTransaction?( params: SignTransactionParams | SignTransactionActionsParams ): Promise<[Uint8Array, SignedTransaction]>; + /** + * Composes and signs a SignedDelegate action to be executed in a transaction + */ + signDelegateAction?( + params: SignDelegateOptions + ): Promise; } type BaseWallet<