From 97dd9d6576b7c9086cd736a15ba1e58511c751db Mon Sep 17 00:00:00 2001 From: "Kujtim.Prenku" Date: Fri, 12 Aug 2022 01:36:18 +0200 Subject: [PATCH 1/6] Added verify owner method, copied code from PR #320 --- .../components/content/content.component.html | 1 + .../components/content/content.component.ts | 15 +++++++ examples/react/components/Content.tsx | 16 ++++++++ packages/core/docs/api/wallet.md | 31 +++++++++++++++ packages/core/src/lib/wallet/wallet.types.ts | 14 ++++++- packages/ledger/src/lib/ledger.ts | 36 +++++++++++++++++ packages/math-wallet/src/lib/math-wallet.ts | 33 ++++++++++++++++ .../meteor-wallet/src/lib/meteor-wallet.ts | 8 +++- .../my-near-wallet/src/lib/my-near-wallet.ts | 35 ++++++++++++++++- .../src/lib/nightly-connect.ts | 12 +++++- packages/nightly/src/lib/nightly.ts | 7 ++++ packages/sender/src/lib/injected-sender.ts | 3 +- packages/sender/src/lib/sender.ts | 39 +++++++++++++++++++ .../wallet-connect/src/lib/wallet-connect.ts | 8 +++- 14 files changed, 252 insertions(+), 6 deletions(-) diff --git a/examples/angular/src/app/components/content/content.component.html b/examples/angular/src/app/components/content/content.component.html index 88ca7ffb4..43e57a47c 100644 --- a/examples/angular/src/app/components/content/content.component.html +++ b/examples/angular/src/app/components/content/content.component.html @@ -2,6 +2,7 @@
+ diff --git a/examples/angular/src/app/components/content/content.component.ts b/examples/angular/src/app/components/content/content.component.ts index 62ed199bf..6bd0e71f2 100644 --- a/examples/angular/src/app/components/content/content.component.ts +++ b/examples/angular/src/app/components/content/content.component.ts @@ -111,6 +111,21 @@ export class ContentComponent implements OnInit, OnDestroy { alert("Switched account to " + nextAccountId); } + async onVerifyOwner() { + const wallet = await this.selector.wallet(); + try { + const signature = await wallet.verifyOwner(); + + if (signature) { + alert(`Signature for verification: ${signature.signature.toString()}`); + } + } catch (err) { + const message = + err instanceof Error ? err.message : "Something went wrong"; + alert(message); + } + } + subscribeToEvents() { this.subscription = this.selector.store.observable .pipe( diff --git a/examples/react/components/Content.tsx b/examples/react/components/Content.tsx index 9b14c73a9..919d571f6 100644 --- a/examples/react/components/Content.tsx +++ b/examples/react/components/Content.tsx @@ -164,6 +164,21 @@ const Content: React.FC = () => { [selector, accountId] ); + const handleVerifyOwner = async () => { + const wallet = await selector.wallet(); + try { + const signature = await wallet.verifyOwner(); + + if (signature) { + alert(`Signature for verification: ${signature.signature.toString()}`); + } + } catch (err) { + const message = + err instanceof Error ? err.message : "Something went wrong"; + alert(message); + } + }; + const handleSubmit = useCallback( async (e: SubmitEvent) => { e.preventDefault(); @@ -220,6 +235,7 @@ const Content: React.FC = () => {
+ {accounts.length > 1 && ( )} diff --git a/packages/core/docs/api/wallet.md b/packages/core/docs/api/wallet.md index 6291dc1dd..47d5d6f54 100644 --- a/packages/core/docs/api/wallet.md +++ b/packages/core/docs/api/wallet.md @@ -182,6 +182,37 @@ Returns one or more accounts when signed in. This method can be useful for walle })(); ``` +### `.verifyOwner(params)` + +**Parameters** +- `params` (`object`) + - `message` (`string?`): The message requested sign. Defaults to `verify owner` string. + - `signerId` (`string?`): Account ID used to sign the message. Defaults to the first account. + - `publicKey` (`PublicKey?`): Public key used to sign the message. Defaults to the public key of the signed in account. + - `callbackUrl` (`string?`): Applicable to browser wallets (e.g. MyNearWallet). This is the callback url once the signing is approved. Defaults to `window.location.href`. + - `meta` (`string?`): Applicable to browser wallets (e.g. MyNearWallet) extra data that will be passed to the callback url once the signing is approved. + +**Returns** +- `Promise`: Browser wallets won't return the signing outcome as they may need to redirect for signing. For MyNearWallet the outcome is passed to the callback url. + +**Description** + +Signs the message and verifies the owner. Message is not sent to blockchain. + +> Note: This feature is currently supported only by MyNearWallet on **testnet**. Sender can sign messages when unlocked. +**Example** + +```ts +// MyNearWallet +(async () => { + const wallet = await selector.wallet("my-near-wallet"); + await wallet.verifyOwner({ + message: "Test message", + }); +})(); +``` + + ### `.signAndSendTransaction(params)` **Parameters** diff --git a/packages/core/src/lib/wallet/wallet.types.ts b/packages/core/src/lib/wallet/wallet.types.ts index 435409d31..65d133c5b 100644 --- a/packages/core/src/lib/wallet/wallet.types.ts +++ b/packages/core/src/lib/wallet/wallet.types.ts @@ -1,4 +1,4 @@ -import { providers } from "near-api-js"; +import { providers, utils } from "near-api-js"; import { EventEmitterService, @@ -10,6 +10,7 @@ import type { Options } from "../options.types"; import type { ReadOnlyStore } from "../store.types"; import type { Transaction, Action } from "./transactions.types"; import type { Modify, Optional } from "../utils.types"; +import { PublicKey } from "near-api-js/lib/utils"; import type { FinalExecutionOutcome } from "near-api-js/lib/providers"; interface BaseWalletMetadata { @@ -29,6 +30,14 @@ export interface SignInParams { methodNames?: Array; } +export interface VerifyOwnerParams { + message?: string; + signerId?: string; + publicKey?: PublicKey; + callbackUrl?: string; + meta?: string; +} + export interface SignAndSendTransactionParams { signerId?: string; receiverId?: string; @@ -43,6 +52,9 @@ interface BaseWalletBehaviour { signIn(params: SignInParams): Promise>; signOut(): Promise; getAccounts(): Promise>; + verifyOwner( + params?: VerifyOwnerParams + ): Promise; signAndSendTransaction( params: SignAndSendTransactionParams ): Promise; diff --git a/packages/ledger/src/lib/ledger.ts b/packages/ledger/src/lib/ledger.ts index 101dfd88b..9653346a7 100644 --- a/packages/ledger/src/lib/ledger.ts +++ b/packages/ledger/src/lib/ledger.ts @@ -60,6 +60,7 @@ const Ledger: WalletBehaviourFactory = async ({ provider, logger, storage, + metadata, }) => { const _state = await setupLedgerState(storage); @@ -219,6 +220,41 @@ const Ledger: WalletBehaviourFactory = async ({ return getAccounts(); }, + async verifyOwner({ message = "verify owner", signerId, publicKey } = {}) { + logger.log("Ledger:verifyOwner", { message, signerId, publicKey }); + + const account = getActiveAccount(store.getState()); + + if (!account) { + throw new Error("No active account"); + } + + // Note: Connection must be triggered by user interaction. + await connectLedgerDevice(); + + const networkId = options.network.networkId; + const accountId = signerId || account.accountId; + const pubKey = + publicKey || (await signer.getPublicKey(accountId, networkId)); + const block = await provider.block({ finality: "final" }); + + const msg = JSON.stringify({ + accountId, + message, + blockId: block.header.hash, + publicKey: Buffer.from(pubKey.data).toString("base64"), + keyType: pubKey.keyType, + }); + + throw new Error(`Method not supported by ${metadata.name}`); + + return signer.signMessage( + new Uint8Array(Buffer.from(msg)), + accountId, + networkId + ); + }, + async signAndSendTransaction({ signerId, receiverId, actions }) { logger.log("signAndSendTransaction", { signerId, receiverId, actions }); diff --git a/packages/math-wallet/src/lib/math-wallet.ts b/packages/math-wallet/src/lib/math-wallet.ts index ce0a4a11f..ff5b0e2dd 100644 --- a/packages/math-wallet/src/lib/math-wallet.ts +++ b/packages/math-wallet/src/lib/math-wallet.ts @@ -41,6 +41,7 @@ const setupMathWalletState = (): MathWalletState => { }; const MathWallet: WalletBehaviourFactory = async ({ + metadata, options, store, provider, @@ -104,6 +105,38 @@ const MathWallet: WalletBehaviourFactory = async ({ return getAccounts(); }, + async verifyOwner({ message = "verify owner", signerId, publicKey } = {}) { + logger.log("MathWallet:verifyOwner", { message, signerId, publicKey }); + + const account = getActiveAccount(store.getState()); + + if (!account) { + throw new Error("No active account"); + } + + const accountId = signerId || account.accountId; + const pubKey = + publicKey || (await _state.wallet.signer.getPublicKey(accountId)); + const block = await provider.block({ finality: "final" }); + + const msg = JSON.stringify({ + accountId, + message, + blockId: block.header.hash, + publicKey: Buffer.from(pubKey.data).toString("base64"), + keyType: pubKey.keyType, + }); + + // Note: Math Wallet currently hangs when calling signMessage. + throw new Error(`Method not supported by ${metadata.name}`); + + return _state.wallet.signer.signMessage( + new Uint8Array(Buffer.from(msg)), + accountId, + options.network.networkId + ); + }, + async signAndSendTransaction({ signerId, receiverId, actions }) { logger.log("signAndSendTransaction", { signerId, receiverId, actions }); const signedTransactions = await signTransactions( diff --git a/packages/meteor-wallet/src/lib/meteor-wallet.ts b/packages/meteor-wallet/src/lib/meteor-wallet.ts index c01f57f24..e0e90fff0 100644 --- a/packages/meteor-wallet/src/lib/meteor-wallet.ts +++ b/packages/meteor-wallet/src/lib/meteor-wallet.ts @@ -48,7 +48,7 @@ const setupWalletState = async ( const createMeteorWalletInjected: WalletBehaviourFactory< InjectedWallet, { params: MeteorWalletParams_Injected } -> = async ({ options, logger, store, params }) => { +> = async ({ metadata, options, logger, store, params }) => { const _state = await setupWalletState(params, options.network); const cleanup = () => { @@ -155,6 +155,12 @@ const createMeteorWalletInjected: WalletBehaviourFactory< return getAccounts(); }, + async verifyOwner({ message = "verify owner", signerId, publicKey } = {}) { + logger.log("MeteorWallet:verifyOwner", { message, signerId, publicKey }); + + throw new Error(`Method not supported by ${metadata.name}`); + }, + async signAndSendTransaction({ signerId, receiverId, actions }) { logger.log("MeteorWallet:signAndSendTransaction", { signerId, diff --git a/packages/my-near-wallet/src/lib/my-near-wallet.ts b/packages/my-near-wallet/src/lib/my-near-wallet.ts index d723dd15e..f6e772412 100644 --- a/packages/my-near-wallet/src/lib/my-near-wallet.ts +++ b/packages/my-near-wallet/src/lib/my-near-wallet.ts @@ -74,7 +74,7 @@ const setupWalletState = async ( const MyNearWallet: WalletBehaviourFactory< BrowserWallet, { params: MyNearWalletExtraOptions } -> = async ({ options, store, params, logger }) => { +> = async ({ metadata, options, store, params, logger }) => { const _state = await setupWalletState(params, options.network); const cleanup = () => { @@ -155,6 +155,39 @@ const MyNearWallet: WalletBehaviourFactory< return getAccounts(); }, + async verifyOwner({ + message = "verify owner", + signerId, + publicKey, + callbackUrl, + meta, + } = {}) { + logger.log("verifyOwner", { message, signerId, publicKey }); + + const account = _state.wallet.account(); + + if (!account) { + throw new Error("Wallet not signed in"); + } + const locationUrl = + typeof window !== "undefined" ? window.location.href : ""; + + const url = callbackUrl || locationUrl; + + if (!url) { + throw new Error(`The callbackUrl is missing for ${metadata.name}`); + } + + const encodedUrl = encodeURIComponent(url); + const extraMeta = meta ? `&meta=${meta}` : ""; + + window.location.replace( + `${params.walletUrl}/verify-owner?message=${message}&callbackUrl=${encodedUrl}${extraMeta}` + ); + + return; + }, + async signAndSendTransaction({ signerId, receiverId, diff --git a/packages/nightly-connect/src/lib/nightly-connect.ts b/packages/nightly-connect/src/lib/nightly-connect.ts index 5cf380ecc..6331e5779 100644 --- a/packages/nightly-connect/src/lib/nightly-connect.ts +++ b/packages/nightly-connect/src/lib/nightly-connect.ts @@ -44,7 +44,7 @@ const setupNightlyConnectState = (): NightlyConnectState => { const NightlyConnect: WalletBehaviourFactory< BridgeWallet, { params: NightlyConnectParams } -> = async ({ store, params, logger, options, provider, emitter }) => { +> = async ({ metadata, store, params, logger, options, provider, emitter }) => { const _state = setupNightlyConnectState(); const getAccounts = () => { @@ -156,6 +156,16 @@ const NightlyConnect: WalletBehaviourFactory< return getAccounts().map(({ accountId }) => ({ accountId })); }, + async verifyOwner({ message = "verify owner", signerId, publicKey } = {}) { + logger.log("NightlyConnect:verifyOwner", { + message, + signerId, + publicKey, + }); + + throw new Error(`Method not supported by ${metadata.name}`); + }, + async signAndSendTransaction({ signerId, receiverId, actions }) { logger.log("signAndSendTransaction", { signerId, receiverId, actions }); diff --git a/packages/nightly/src/lib/nightly.ts b/packages/nightly/src/lib/nightly.ts index 67703d8ed..91afbc3fa 100644 --- a/packages/nightly/src/lib/nightly.ts +++ b/packages/nightly/src/lib/nightly.ts @@ -40,6 +40,7 @@ const isInstalled = () => { return waitFor(() => !!window.nightly!.near!).catch(() => false); }; const Nightly: WalletBehaviourFactory = async ({ + metadata, options, store, logger, @@ -141,6 +142,12 @@ const Nightly: WalletBehaviourFactory = async ({ return getAccounts().map(({ accountId }) => ({ accountId })); }, + async verifyOwner({ message = "verify owner", signerId, publicKey } = {}) { + logger.log("Nightly:verifyOwner", { message, signerId, publicKey }); + + throw new Error(`Method not supported by ${metadata.name}`); + }, + async signAndSendTransaction({ signerId, receiverId, actions }) { logger.log("signAndSendTransaction", { signerId, receiverId, actions }); diff --git a/packages/sender/src/lib/injected-sender.ts b/packages/sender/src/lib/injected-sender.ts index 6ad3aa201..6a04c153f 100644 --- a/packages/sender/src/lib/injected-sender.ts +++ b/packages/sender/src/lib/injected-sender.ts @@ -1,7 +1,7 @@ // Interfaces based on "documentation": https://github.com/SenderWallet/sender-wallet-integration-tutorial // Empty string if we haven't signed in before. -import { providers } from "near-api-js"; +import { Account, providers } from "near-api-js"; interface AccessKey { publicKey: { @@ -114,6 +114,7 @@ export interface InjectedSender { callbacks: Record; getAccountId: () => string | null; getRpc: () => Promise; + account(): Account | null; requestSignIn: ( params: RequestSignInParams ) => Promise; diff --git a/packages/sender/src/lib/sender.ts b/packages/sender/src/lib/sender.ts index a64b0fd31..9e4986dad 100644 --- a/packages/sender/src/lib/sender.ts +++ b/packages/sender/src/lib/sender.ts @@ -42,6 +42,7 @@ const Sender: WalletBehaviourFactory = async ({ options, metadata, store, + provider, emitter, logger, }) => { @@ -174,6 +175,44 @@ const Sender: WalletBehaviourFactory = async ({ return getAccounts(); }, + async verifyOwner({ message = "verify owner", signerId, publicKey } = {}) { + logger.log("Sender:verifyOwner", { message, signerId, publicKey }); + + const account = _state.wallet.account(); + + if (!account) { + throw new Error("Wallet not signed in"); + } + + // Note: When the wallet is locked, Sender returns an empty Signer interface. + // Even after unlocking the wallet, the user will need to refresh to gain + // access to these methods. + if (!account.connection.signer.signMessage) { + throw new Error("Wallet is locked"); + } + + const networkId = options.network.networkId; + const accountId = signerId || account.accountId; + const pubKey = + publicKey || + (await account.connection.signer.getPublicKey(accountId, networkId)); + const block = await provider.block({ finality: "final" }); + + const msg = JSON.stringify({ + accountId, + message, + blockId: block.header.hash, + publicKey: Buffer.from(pubKey.data).toString("base64"), + keyType: pubKey.keyType, + }); + + return account.connection.signer.signMessage( + new Uint8Array(Buffer.from(msg)), + accountId, + networkId + ); + }, + async signAndSendTransaction({ signerId, receiverId, actions }) { logger.log("signAndSendTransaction", { signerId, receiverId, actions }); diff --git a/packages/wallet-connect/src/lib/wallet-connect.ts b/packages/wallet-connect/src/lib/wallet-connect.ts index b12a33094..2dca5dcf2 100644 --- a/packages/wallet-connect/src/lib/wallet-connect.ts +++ b/packages/wallet-connect/src/lib/wallet-connect.ts @@ -66,7 +66,7 @@ const setupWalletConnectState = async ( const WalletConnect: WalletBehaviourFactory< BridgeWallet, { params: WalletConnectExtraOptions } -> = async ({ options, store, params, emitter, logger }) => { +> = async ({ metadata, options, store, params, emitter, logger }) => { const _state = await setupWalletConnectState(params); const getChainId = () => { @@ -177,6 +177,12 @@ const WalletConnect: WalletBehaviourFactory< return getAccounts(); }, + async verifyOwner({ message = "verify owner", signerId, publicKey } = {}) { + logger.log("WalletConnect:verifyOwner", { message, signerId, publicKey }); + + throw new Error(`Method not supported by ${metadata.name}`); + }, + async signAndSendTransaction({ signerId, receiverId, actions }) { logger.log("signAndSendTransaction", { signerId, receiverId, actions }); From d556051cf8b208adff71cbe3c735cca6675bf886 Mon Sep 17 00:00:00 2001 From: "Kujtim.Prenku" Date: Fri, 12 Aug 2022 07:49:21 +0200 Subject: [PATCH 2/6] Throw error for ledger since ledger app can sign only valid transactions --- packages/ledger/src/lib/ledger.ts | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/packages/ledger/src/lib/ledger.ts b/packages/ledger/src/lib/ledger.ts index 9653346a7..f8cff90e2 100644 --- a/packages/ledger/src/lib/ledger.ts +++ b/packages/ledger/src/lib/ledger.ts @@ -223,36 +223,7 @@ const Ledger: WalletBehaviourFactory = async ({ async verifyOwner({ message = "verify owner", signerId, publicKey } = {}) { logger.log("Ledger:verifyOwner", { message, signerId, publicKey }); - const account = getActiveAccount(store.getState()); - - if (!account) { - throw new Error("No active account"); - } - - // Note: Connection must be triggered by user interaction. - await connectLedgerDevice(); - - const networkId = options.network.networkId; - const accountId = signerId || account.accountId; - const pubKey = - publicKey || (await signer.getPublicKey(accountId, networkId)); - const block = await provider.block({ finality: "final" }); - - const msg = JSON.stringify({ - accountId, - message, - blockId: block.header.hash, - publicKey: Buffer.from(pubKey.data).toString("base64"), - keyType: pubKey.keyType, - }); - throw new Error(`Method not supported by ${metadata.name}`); - - return signer.signMessage( - new Uint8Array(Buffer.from(msg)), - accountId, - networkId - ); }, async signAndSendTransaction({ signerId, receiverId, actions }) { From 7693666ec7301d0ba80f2f4877857c7633fc8a58 Mon Sep 17 00:00:00 2001 From: "Kujtim.Prenku" Date: Fri, 12 Aug 2022 08:58:07 +0200 Subject: [PATCH 3/6] Changed return type to align with PR 2801 of Near Wallet repo --- packages/core/src/index.ts | 2 ++ packages/core/src/lib/wallet/wallet.types.ts | 13 ++++++++++--- packages/math-wallet/src/lib/math-wallet.ts | 15 +++++++++++---- packages/sender/src/lib/sender.ts | 15 +++++++++++---- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 5f94c63a7..6b6584a6c 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -45,6 +45,8 @@ export type { BridgeWalletMetadata, BridgeWalletBehaviour, BridgeWallet, + VerifiedOwner, + VerifyOwnerParams, Account, Transaction, Action, diff --git a/packages/core/src/lib/wallet/wallet.types.ts b/packages/core/src/lib/wallet/wallet.types.ts index 65d133c5b..088043197 100644 --- a/packages/core/src/lib/wallet/wallet.types.ts +++ b/packages/core/src/lib/wallet/wallet.types.ts @@ -38,6 +38,15 @@ export interface VerifyOwnerParams { meta?: string; } +export interface VerifiedOwner { + accountId: string; + message: string; + blockId: string; + publicKey: string; + signature: string; + keyType: utils.key_pair.KeyType; +} + export interface SignAndSendTransactionParams { signerId?: string; receiverId?: string; @@ -52,9 +61,7 @@ interface BaseWalletBehaviour { signIn(params: SignInParams): Promise>; signOut(): Promise; getAccounts(): Promise>; - verifyOwner( - params?: VerifyOwnerParams - ): Promise; + verifyOwner(params?: VerifyOwnerParams): Promise; signAndSendTransaction( params: SignAndSendTransactionParams ): Promise; diff --git a/packages/math-wallet/src/lib/math-wallet.ts b/packages/math-wallet/src/lib/math-wallet.ts index ff5b0e2dd..2db8b7584 100644 --- a/packages/math-wallet/src/lib/math-wallet.ts +++ b/packages/math-wallet/src/lib/math-wallet.ts @@ -119,22 +119,29 @@ const MathWallet: WalletBehaviourFactory = async ({ publicKey || (await _state.wallet.signer.getPublicKey(accountId)); const block = await provider.block({ finality: "final" }); - const msg = JSON.stringify({ + const data = { accountId, message, blockId: block.header.hash, publicKey: Buffer.from(pubKey.data).toString("base64"), keyType: pubKey.keyType, - }); + }; + const encoded = JSON.stringify(data); // Note: Math Wallet currently hangs when calling signMessage. throw new Error(`Method not supported by ${metadata.name}`); - return _state.wallet.signer.signMessage( - new Uint8Array(Buffer.from(msg)), + const signed = await _state.wallet.signer.signMessage( + new Uint8Array(Buffer.from(encoded)), accountId, options.network.networkId ); + + return { + ...data, + signature: Buffer.from(signed.signature).toString("base64"), + keyType: signed.publicKey.keyType, + }; }, async signAndSendTransaction({ signerId, receiverId, actions }) { diff --git a/packages/sender/src/lib/sender.ts b/packages/sender/src/lib/sender.ts index 9e4986dad..7db89bb66 100644 --- a/packages/sender/src/lib/sender.ts +++ b/packages/sender/src/lib/sender.ts @@ -198,19 +198,26 @@ const Sender: WalletBehaviourFactory = async ({ (await account.connection.signer.getPublicKey(accountId, networkId)); const block = await provider.block({ finality: "final" }); - const msg = JSON.stringify({ + const data = { accountId, message, blockId: block.header.hash, publicKey: Buffer.from(pubKey.data).toString("base64"), keyType: pubKey.keyType, - }); + }; + const encoded = JSON.stringify(data); - return account.connection.signer.signMessage( - new Uint8Array(Buffer.from(msg)), + const signed = await account.connection.signer.signMessage( + new Uint8Array(Buffer.from(encoded)), accountId, networkId ); + + return { + ...data, + signature: Buffer.from(signed.signature).toString("base64"), + keyType: signed.publicKey.keyType, + }; }, async signAndSendTransaction({ signerId, receiverId, actions }) { From fa003bbc79f37fca635de16a66670fc24e4b9c98 Mon Sep 17 00:00:00 2001 From: "Kujtim.Prenku" Date: Fri, 12 Aug 2022 09:00:03 +0200 Subject: [PATCH 4/6] Updated docs --- packages/core/docs/api/wallet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/docs/api/wallet.md b/packages/core/docs/api/wallet.md index 47d5d6f54..9460ce7a2 100644 --- a/packages/core/docs/api/wallet.md +++ b/packages/core/docs/api/wallet.md @@ -193,7 +193,7 @@ Returns one or more accounts when signed in. This method can be useful for walle - `meta` (`string?`): Applicable to browser wallets (e.g. MyNearWallet) extra data that will be passed to the callback url once the signing is approved. **Returns** -- `Promise`: Browser wallets won't return the signing outcome as they may need to redirect for signing. For MyNearWallet the outcome is passed to the callback url. +- `Promise`: Browser wallets won't return the signing outcome as they may need to redirect for signing. For MyNearWallet the outcome is passed to the callback url. **Description** From 684535f664867cf2b9eee08a90dedeab8ddc32cb Mon Sep 17 00:00:00 2001 From: "Kujtim.Prenku" Date: Fri, 12 Aug 2022 09:07:45 +0200 Subject: [PATCH 5/6] Updated examples to show all details returned by verifyOwner --- .../angular/src/app/components/content/content.component.ts | 6 +++--- examples/react/components/Content.tsx | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/angular/src/app/components/content/content.component.ts b/examples/angular/src/app/components/content/content.component.ts index 6bd0e71f2..2c9f3521b 100644 --- a/examples/angular/src/app/components/content/content.component.ts +++ b/examples/angular/src/app/components/content/content.component.ts @@ -114,10 +114,10 @@ export class ContentComponent implements OnInit, OnDestroy { async onVerifyOwner() { const wallet = await this.selector.wallet(); try { - const signature = await wallet.verifyOwner(); + const owner = await wallet.verifyOwner(); - if (signature) { - alert(`Signature for verification: ${signature.signature.toString()}`); + if (owner) { + alert(`Signature for verification: ${JSON.stringify(owner)}`); } } catch (err) { const message = diff --git a/examples/react/components/Content.tsx b/examples/react/components/Content.tsx index 919d571f6..48447f7b5 100644 --- a/examples/react/components/Content.tsx +++ b/examples/react/components/Content.tsx @@ -167,10 +167,10 @@ const Content: React.FC = () => { const handleVerifyOwner = async () => { const wallet = await selector.wallet(); try { - const signature = await wallet.verifyOwner(); + const owner = await wallet.verifyOwner(); - if (signature) { - alert(`Signature for verification: ${signature.signature.toString()}`); + if (owner) { + alert(`Signature for verification: ${JSON.stringify(owner)}`); } } catch (err) { const message = From 91fdad05d8ec71ee80fd4001bb5075186f1abbaa Mon Sep 17 00:00:00 2001 From: Daryl Collins Date: Tue, 16 Aug 2022 11:34:55 -0700 Subject: [PATCH 6/6] Sync `verifyOwner` API with base implementation in NW - Require `message` - Remove unsupported 'signerId' and 'publicKey' arguments from caller interface - Require `params` be passed to `verifyOwner` method in all cases. - PublicKey and signer account ID uses active wallet account in all cases. --- .../src/app/components/content/content.component.ts | 4 +++- examples/react/components/Content.tsx | 4 +++- packages/core/docs/api/wallet.md | 4 +--- packages/core/src/lib/wallet/wallet.types.ts | 7 ++----- packages/ledger/src/lib/ledger.ts | 4 ++-- packages/math-wallet/src/lib/math-wallet.ts | 9 ++++----- packages/meteor-wallet/src/lib/meteor-wallet.ts | 4 ++-- packages/my-near-wallet/src/lib/my-near-wallet.ts | 10 ++-------- packages/nightly-connect/src/lib/nightly-connect.ts | 8 ++------ packages/nightly/src/lib/nightly.ts | 4 ++-- packages/sender/src/lib/sender.ts | 13 +++++++------ packages/wallet-connect/src/lib/wallet-connect.ts | 4 ++-- 12 files changed, 32 insertions(+), 43 deletions(-) diff --git a/examples/angular/src/app/components/content/content.component.ts b/examples/angular/src/app/components/content/content.component.ts index 2c9f3521b..3f4ee7367 100644 --- a/examples/angular/src/app/components/content/content.component.ts +++ b/examples/angular/src/app/components/content/content.component.ts @@ -114,7 +114,9 @@ export class ContentComponent implements OnInit, OnDestroy { async onVerifyOwner() { const wallet = await this.selector.wallet(); try { - const owner = await wallet.verifyOwner(); + const owner = await wallet.verifyOwner({ + message: "test message for verification", + }); if (owner) { alert(`Signature for verification: ${JSON.stringify(owner)}`); diff --git a/examples/react/components/Content.tsx b/examples/react/components/Content.tsx index 48447f7b5..ca24c5257 100644 --- a/examples/react/components/Content.tsx +++ b/examples/react/components/Content.tsx @@ -167,7 +167,9 @@ const Content: React.FC = () => { const handleVerifyOwner = async () => { const wallet = await selector.wallet(); try { - const owner = await wallet.verifyOwner(); + const owner = await wallet.verifyOwner({ + message: "test message for verification", + }); if (owner) { alert(`Signature for verification: ${JSON.stringify(owner)}`); diff --git a/packages/core/docs/api/wallet.md b/packages/core/docs/api/wallet.md index 9460ce7a2..549a77b1e 100644 --- a/packages/core/docs/api/wallet.md +++ b/packages/core/docs/api/wallet.md @@ -186,9 +186,7 @@ Returns one or more accounts when signed in. This method can be useful for walle **Parameters** - `params` (`object`) - - `message` (`string?`): The message requested sign. Defaults to `verify owner` string. - - `signerId` (`string?`): Account ID used to sign the message. Defaults to the first account. - - `publicKey` (`PublicKey?`): Public key used to sign the message. Defaults to the public key of the signed in account. + - `message` (`string`): The message requested sign. Defaults to `verify owner` string. - `callbackUrl` (`string?`): Applicable to browser wallets (e.g. MyNearWallet). This is the callback url once the signing is approved. Defaults to `window.location.href`. - `meta` (`string?`): Applicable to browser wallets (e.g. MyNearWallet) extra data that will be passed to the callback url once the signing is approved. diff --git a/packages/core/src/lib/wallet/wallet.types.ts b/packages/core/src/lib/wallet/wallet.types.ts index 088043197..df06fa38f 100644 --- a/packages/core/src/lib/wallet/wallet.types.ts +++ b/packages/core/src/lib/wallet/wallet.types.ts @@ -10,7 +10,6 @@ import type { Options } from "../options.types"; import type { ReadOnlyStore } from "../store.types"; import type { Transaction, Action } from "./transactions.types"; import type { Modify, Optional } from "../utils.types"; -import { PublicKey } from "near-api-js/lib/utils"; import type { FinalExecutionOutcome } from "near-api-js/lib/providers"; interface BaseWalletMetadata { @@ -31,9 +30,7 @@ export interface SignInParams { } export interface VerifyOwnerParams { - message?: string; - signerId?: string; - publicKey?: PublicKey; + message: string; callbackUrl?: string; meta?: string; } @@ -61,7 +58,7 @@ interface BaseWalletBehaviour { signIn(params: SignInParams): Promise>; signOut(): Promise; getAccounts(): Promise>; - verifyOwner(params?: VerifyOwnerParams): Promise; + verifyOwner(params: VerifyOwnerParams): Promise; signAndSendTransaction( params: SignAndSendTransactionParams ): Promise; diff --git a/packages/ledger/src/lib/ledger.ts b/packages/ledger/src/lib/ledger.ts index f8cff90e2..c967c32c1 100644 --- a/packages/ledger/src/lib/ledger.ts +++ b/packages/ledger/src/lib/ledger.ts @@ -220,8 +220,8 @@ const Ledger: WalletBehaviourFactory = async ({ return getAccounts(); }, - async verifyOwner({ message = "verify owner", signerId, publicKey } = {}) { - logger.log("Ledger:verifyOwner", { message, signerId, publicKey }); + async verifyOwner({ message }) { + logger.log("Ledger:verifyOwner", { message }); throw new Error(`Method not supported by ${metadata.name}`); }, diff --git a/packages/math-wallet/src/lib/math-wallet.ts b/packages/math-wallet/src/lib/math-wallet.ts index 2db8b7584..c90d90622 100644 --- a/packages/math-wallet/src/lib/math-wallet.ts +++ b/packages/math-wallet/src/lib/math-wallet.ts @@ -105,8 +105,8 @@ const MathWallet: WalletBehaviourFactory = async ({ return getAccounts(); }, - async verifyOwner({ message = "verify owner", signerId, publicKey } = {}) { - logger.log("MathWallet:verifyOwner", { message, signerId, publicKey }); + async verifyOwner({ message }) { + logger.log("MathWallet:verifyOwner", { message }); const account = getActiveAccount(store.getState()); @@ -114,9 +114,8 @@ const MathWallet: WalletBehaviourFactory = async ({ throw new Error("No active account"); } - const accountId = signerId || account.accountId; - const pubKey = - publicKey || (await _state.wallet.signer.getPublicKey(accountId)); + const accountId = account.accountId; + const pubKey = await _state.wallet.signer.getPublicKey(accountId); const block = await provider.block({ finality: "final" }); const data = { diff --git a/packages/meteor-wallet/src/lib/meteor-wallet.ts b/packages/meteor-wallet/src/lib/meteor-wallet.ts index e0e90fff0..27d642dbe 100644 --- a/packages/meteor-wallet/src/lib/meteor-wallet.ts +++ b/packages/meteor-wallet/src/lib/meteor-wallet.ts @@ -155,8 +155,8 @@ const createMeteorWalletInjected: WalletBehaviourFactory< return getAccounts(); }, - async verifyOwner({ message = "verify owner", signerId, publicKey } = {}) { - logger.log("MeteorWallet:verifyOwner", { message, signerId, publicKey }); + async verifyOwner({ message }) { + logger.log("MeteorWallet:verifyOwner", { message }); throw new Error(`Method not supported by ${metadata.name}`); }, diff --git a/packages/my-near-wallet/src/lib/my-near-wallet.ts b/packages/my-near-wallet/src/lib/my-near-wallet.ts index f6e772412..87811d480 100644 --- a/packages/my-near-wallet/src/lib/my-near-wallet.ts +++ b/packages/my-near-wallet/src/lib/my-near-wallet.ts @@ -155,14 +155,8 @@ const MyNearWallet: WalletBehaviourFactory< return getAccounts(); }, - async verifyOwner({ - message = "verify owner", - signerId, - publicKey, - callbackUrl, - meta, - } = {}) { - logger.log("verifyOwner", { message, signerId, publicKey }); + async verifyOwner({ message, callbackUrl, meta }) { + logger.log("verifyOwner", { message }); const account = _state.wallet.account(); diff --git a/packages/nightly-connect/src/lib/nightly-connect.ts b/packages/nightly-connect/src/lib/nightly-connect.ts index 6331e5779..c79545d8a 100644 --- a/packages/nightly-connect/src/lib/nightly-connect.ts +++ b/packages/nightly-connect/src/lib/nightly-connect.ts @@ -156,12 +156,8 @@ const NightlyConnect: WalletBehaviourFactory< return getAccounts().map(({ accountId }) => ({ accountId })); }, - async verifyOwner({ message = "verify owner", signerId, publicKey } = {}) { - logger.log("NightlyConnect:verifyOwner", { - message, - signerId, - publicKey, - }); + async verifyOwner({ message }) { + logger.log("NightlyConnect:verifyOwner", { message }); throw new Error(`Method not supported by ${metadata.name}`); }, diff --git a/packages/nightly/src/lib/nightly.ts b/packages/nightly/src/lib/nightly.ts index 91afbc3fa..0bb7e92ff 100644 --- a/packages/nightly/src/lib/nightly.ts +++ b/packages/nightly/src/lib/nightly.ts @@ -142,8 +142,8 @@ const Nightly: WalletBehaviourFactory = async ({ return getAccounts().map(({ accountId }) => ({ accountId })); }, - async verifyOwner({ message = "verify owner", signerId, publicKey } = {}) { - logger.log("Nightly:verifyOwner", { message, signerId, publicKey }); + async verifyOwner({ message }) { + logger.log("Nightly:verifyOwner", { message }); throw new Error(`Method not supported by ${metadata.name}`); }, diff --git a/packages/sender/src/lib/sender.ts b/packages/sender/src/lib/sender.ts index 7db89bb66..7160d5e02 100644 --- a/packages/sender/src/lib/sender.ts +++ b/packages/sender/src/lib/sender.ts @@ -175,8 +175,8 @@ const Sender: WalletBehaviourFactory = async ({ return getAccounts(); }, - async verifyOwner({ message = "verify owner", signerId, publicKey } = {}) { - logger.log("Sender:verifyOwner", { message, signerId, publicKey }); + async verifyOwner({ message }) { + logger.log("Sender:verifyOwner", { message }); const account = _state.wallet.account(); @@ -192,10 +192,11 @@ const Sender: WalletBehaviourFactory = async ({ } const networkId = options.network.networkId; - const accountId = signerId || account.accountId; - const pubKey = - publicKey || - (await account.connection.signer.getPublicKey(accountId, networkId)); + const accountId = account.accountId; + const pubKey = await account.connection.signer.getPublicKey( + accountId, + networkId + ); const block = await provider.block({ finality: "final" }); const data = { diff --git a/packages/wallet-connect/src/lib/wallet-connect.ts b/packages/wallet-connect/src/lib/wallet-connect.ts index 2dca5dcf2..229abd7c7 100644 --- a/packages/wallet-connect/src/lib/wallet-connect.ts +++ b/packages/wallet-connect/src/lib/wallet-connect.ts @@ -177,8 +177,8 @@ const WalletConnect: WalletBehaviourFactory< return getAccounts(); }, - async verifyOwner({ message = "verify owner", signerId, publicKey } = {}) { - logger.log("WalletConnect:verifyOwner", { message, signerId, publicKey }); + async verifyOwner({ message }) { + logger.log("WalletConnect:verifyOwner", { message }); throw new Error(`Method not supported by ${metadata.name}`); },