diff --git a/examples/angular/src/app/components/content/content.component.ts b/examples/angular/src/app/components/content/content.component.ts index c4ab8f5c6..631c027da 100644 --- a/examples/angular/src/app/components/content/content.component.ts +++ b/examples/angular/src/app/components/content/content.component.ts @@ -5,7 +5,12 @@ import type { AccountView, CodeResult, } from "near-api-js/lib/providers/provider"; -import type { AccountState, Transaction } from "@near-wallet-selector/core"; +import type { + AccountState, + SignMessageParams, + SignedMessage, + Transaction, +} from "@near-wallet-selector/core"; import { verifyFullKeyBelongsToUser, verifySignature, @@ -52,6 +57,7 @@ export class ContentComponent implements OnInit, OnDestroy { this.messages = messages; this.subscribeToEvents(); + await this.verifyMessageBrowserWallet(); } async getAccountBalance({ provider, accountId }: GetAccountBalanceProps) { @@ -165,12 +171,87 @@ export class ContentComponent implements OnInit, OnDestroy { } } + async verifyMessage( + message: SignMessageParams, + signedMessage: SignedMessage + ) { + const verifiedSignature = verifySignature({ + message: message.message, + nonce: message.nonce, + recipient: message.recipient, + publicKey: signedMessage.publicKey, + signature: signedMessage.signature, + callbackUrl: message.callbackUrl, + }); + const verifiedFullKeyBelongsToUser = await verifyFullKeyBelongsToUser({ + publicKey: signedMessage.publicKey, + accountId: signedMessage.accountId, + network: this.selector.options.network, + }); + + const isMessageVerified = verifiedFullKeyBelongsToUser && verifiedSignature; + + const alertMessage = isMessageVerified + ? "Successfully verified" + : "Failed to verify"; + + alert( + `${alertMessage} signed message: '${ + message.message + }': \n ${JSON.stringify(signedMessage)}` + ); + } + + async verifyMessageBrowserWallet() { + const urlParams = new URLSearchParams( + window.location.hash.substring(1) // skip the first char (#) + ); + + const accId = urlParams.get("accountId") as string; + const publicKey = urlParams.get("publicKey") as string; + const signature = urlParams.get("signature") as string; + + if (!accId && !publicKey && !signature) { + return; + } + + const message: SignMessageParams = JSON.parse( + localStorage.getItem("message") as string + ); + + const signedMessage = { + accountId: accId, + publicKey, + signature, + }; + + await this.verifyMessage(message, signedMessage); + + const url = new URL(location.href); + url.hash = ""; + url.search = ""; + window.history.replaceState({}, document.title, url); + localStorage.removeItem("message"); + } + async onSignMessage() { const wallet = await this.selector.wallet(); const message = "test message to sign"; const nonce = Buffer.from(Array.from(Array(32).keys())); const recipient = "guest-book.testnet"; + if (wallet.type === "browser") { + localStorage.setItem( + "message", + JSON.stringify({ + message, + nonce: [...nonce], + recipient, + callbackUrl: location.href, + }) + ); + } + try { const signedMessage = await wallet.signMessage({ message, @@ -178,32 +259,7 @@ export class ContentComponent implements OnInit, OnDestroy { recipient, }); if (signedMessage) { - const verifiedSignature = verifySignature({ - message, - nonce, - recipient, - publicKey: signedMessage.publicKey, - signature: signedMessage.signature, - }); - const verifiedFullKeyBelongsToUser = await verifyFullKeyBelongsToUser({ - publicKey: signedMessage.publicKey, - accountId: signedMessage.accountId, - network: this.selector.options.network, - }); - - if (verifiedFullKeyBelongsToUser && verifiedSignature) { - alert( - `Successfully verify signed message: '${message}': \n ${JSON.stringify( - signedMessage - )}` - ); - } else { - alert( - `Failed to verify signed message '${message}': \n ${JSON.stringify( - signedMessage - )}` - ); - } + await this.verifyMessage({ message, nonce, recipient }, signedMessage); } } catch (err) { const errMsg = diff --git a/examples/react/components/Content.tsx b/examples/react/components/Content.tsx index 9cb715922..68d60c6c6 100644 --- a/examples/react/components/Content.tsx +++ b/examples/react/components/Content.tsx @@ -4,7 +4,11 @@ import type { AccountView, CodeResult, } from "near-api-js/lib/providers/provider"; -import type { Transaction } from "@near-wallet-selector/core"; +import type { + SignedMessage, + SignMessageParams, + Transaction, +} from "@near-wallet-selector/core"; import { verifyFullKeyBelongsToUser } from "@near-wallet-selector/core"; import { verifySignature } from "@near-wallet-selector/core"; import BN from "bn.js"; @@ -103,6 +107,14 @@ const Content: React.FC = () => { useEffect(() => { // TODO: don't just fetch once; subscribe! getMessages().then(setMessages); + + const timeoutId = setTimeout(() => { + verifyMessageBrowserWallet(); + }, 500); + + return () => { + clearTimeout(timeoutId); + }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); @@ -224,6 +236,69 @@ const Content: React.FC = () => { } }; + const verifyMessage = async ( + message: SignMessageParams, + signedMessage: SignedMessage + ) => { + const verifiedSignature = verifySignature({ + message: message.message, + nonce: message.nonce, + recipient: message.recipient, + publicKey: signedMessage.publicKey, + signature: signedMessage.signature, + callbackUrl: message.callbackUrl, + }); + const verifiedFullKeyBelongsToUser = await verifyFullKeyBelongsToUser({ + publicKey: signedMessage.publicKey, + accountId: signedMessage.accountId, + network: selector.options.network, + }); + + const isMessageVerified = verifiedFullKeyBelongsToUser && verifiedSignature; + + const alertMessage = isMessageVerified + ? "Successfully verified" + : "Failed to verify"; + + alert( + `${alertMessage} signed message: '${ + message.message + }': \n ${JSON.stringify(signedMessage)}` + ); + }; + + const verifyMessageBrowserWallet = useCallback(async () => { + const urlParams = new URLSearchParams( + window.location.hash.substring(1) // skip the first char (#) + ); + const accId = urlParams.get("accountId") as string; + const publicKey = urlParams.get("publicKey") as string; + const signature = urlParams.get("signature") as string; + + if (!accId && !publicKey && !signature) { + return; + } + + const message: SignMessageParams = JSON.parse( + localStorage.getItem("message")! + ); + + const signedMessage = { + accountId: accId, + publicKey, + signature, + }; + + await verifyMessage(message, signedMessage); + + const url = new URL(location.href); + url.hash = ""; + url.search = ""; + window.history.replaceState({}, document.title, url); + localStorage.removeItem("message"); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const handleSubmit = useCallback( async (e: Submitted) => { e.preventDefault(); @@ -266,6 +341,18 @@ const Content: React.FC = () => { const nonce = Buffer.from(Array.from(Array(32).keys())); const recipient = "guest-book.testnet"; + if (wallet.type === "browser") { + localStorage.setItem( + "message", + JSON.stringify({ + message, + nonce: [...nonce], + recipient, + callbackUrl: location.href, + }) + ); + } + try { const signedMessage = await wallet.signMessage({ message, @@ -273,32 +360,7 @@ const Content: React.FC = () => { recipient, }); if (signedMessage) { - const verifiedSignature = verifySignature({ - message, - nonce, - recipient, - publicKey: signedMessage.publicKey, - signature: signedMessage.signature, - }); - const verifiedFullKeyBelongsToUser = await verifyFullKeyBelongsToUser({ - publicKey: signedMessage.publicKey, - accountId: signedMessage.accountId, - network: selector.options.network, - }); - - if (verifiedFullKeyBelongsToUser && verifiedSignature) { - alert( - `Successfully verify signed message: '${message}': \n ${JSON.stringify( - signedMessage - )}` - ); - } else { - alert( - `Failed to verify signed message '${message}': \n ${JSON.stringify( - signedMessage - )}` - ); - } + await verifyMessage({ message, nonce, recipient }, signedMessage); } } catch (err) { const errMsg = diff --git a/package.json b/package.json index 418518652..300741f35 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "near-wallet-selector", - "version": "8.5.4", + "version": "8.6.0", "description": "NEAR Wallet Selector makes it easy for users to interact with your dApp by providing an abstraction over various wallets within the NEAR ecosystem", "keywords": [ "near", diff --git a/packages/account-export/package.json b/packages/account-export/package.json index 426925cd3..3b5d4d6d7 100644 --- a/packages/account-export/package.json +++ b/packages/account-export/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/account-export", - "version": "8.5.4", + "version": "8.6.0", "description": "This is the Export Selector UI package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/coin98-wallet/package.json b/packages/coin98-wallet/package.json index 40cf62641..b8310fdab 100644 --- a/packages/coin98-wallet/package.json +++ b/packages/coin98-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/coin98-wallet", - "version": "8.5.4", + "version": "8.6.0", "description": "Coin 98 wallet package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/core/package.json b/packages/core/package.json index dfa687e79..fe152c9f6 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/core", - "version": "8.5.4", + "version": "8.6.0", "description": "This is the core package for NEAR Wallet Selector.", "keywords": [ "near", 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 d6438f5e6..61f37f585 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 @@ -7,6 +7,7 @@ import type { WalletModuleFactory, Account, InstantLinkWallet, + SignMessageParams, } from "../../wallet"; import type { StorageService } from "../storage/storage.service.types"; import type { Options } from "../../options.types"; @@ -254,6 +255,26 @@ export class WalletModules { return emitter; } + private validateSignMessageParams({ + message, + nonce, + recipient, + }: SignMessageParams) { + if (!message || message.trim() === "") { + throw new Error("Invalid message. It must be a non-empty string."); + } + + if (!Buffer.isBuffer(nonce) || nonce.length !== 32) { + throw new Error( + "Invalid nonce. It must be a Buffer with a length of 32 bytes." + ); + } + + if (!recipient || recipient.trim() === "") { + throw new Error("Invalid recipient. It must be a non-empty string."); + } + } + private decorateWallet(wallet: Wallet): Wallet { const _signIn = wallet.signIn; const _signOut = wallet.signOut; @@ -284,6 +305,8 @@ export class WalletModules { ); } + this.validateSignMessageParams(params); + return await _signMessage(params); }; diff --git a/packages/default-wallets/package.json b/packages/default-wallets/package.json index bfc76de0d..d81c021a2 100644 --- a/packages/default-wallets/package.json +++ b/packages/default-wallets/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/default-wallets", - "version": "8.5.4", + "version": "8.6.0", "description": "Default wallets package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/finer-wallet/package.json b/packages/finer-wallet/package.json index 59caeeb87..1aa54a84a 100644 --- a/packages/finer-wallet/package.json +++ b/packages/finer-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/finer-wallet", - "version": "8.5.4", + "version": "8.6.0", "description": "FiNER Wallet package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/here-wallet/package.json b/packages/here-wallet/package.json index 2b6e07861..91dc5622c 100644 --- a/packages/here-wallet/package.json +++ b/packages/here-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/here-wallet", - "version": "8.5.4", + "version": "8.6.0", "description": "Here wallet package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/ledger/package.json b/packages/ledger/package.json index fa18a02a9..d80a2e317 100644 --- a/packages/ledger/package.json +++ b/packages/ledger/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/ledger", - "version": "8.5.4", + "version": "8.6.0", "description": "Ledger package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/math-wallet/package.json b/packages/math-wallet/package.json index 06d4b489d..903d039e4 100644 --- a/packages/math-wallet/package.json +++ b/packages/math-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/math-wallet", - "version": "8.5.4", + "version": "8.6.0", "description": "Math wallet package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/meteor-wallet/package.json b/packages/meteor-wallet/package.json index e5caed946..d03add0ef 100644 --- a/packages/meteor-wallet/package.json +++ b/packages/meteor-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/meteor-wallet", - "version": "8.5.4", + "version": "8.6.0", "description": "Meteor wallet package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/modal-ui-js/package.json b/packages/modal-ui-js/package.json index 948a32bc2..7c50ed102 100644 --- a/packages/modal-ui-js/package.json +++ b/packages/modal-ui-js/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/modal-ui-js", - "version": "8.5.4", + "version": "8.6.0", "description": "Modal UI package for NEAR wallet Selector", "keywords": [ "near", diff --git a/packages/modal-ui/package.json b/packages/modal-ui/package.json index cebb5e260..15759a10e 100644 --- a/packages/modal-ui/package.json +++ b/packages/modal-ui/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/modal-ui", - "version": "8.5.4", + "version": "8.6.0", "description": "Modal UI package for NEAR wallet Selector", "keywords": [ "near", diff --git a/packages/my-near-wallet/package.json b/packages/my-near-wallet/package.json index 18a9f3ede..3921e03a1 100644 --- a/packages/my-near-wallet/package.json +++ b/packages/my-near-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/my-near-wallet", - "version": "8.5.4", + "version": "8.6.0", "description": "My Near Wallet package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/my-near-wallet/src/lib/my-near-wallet.spec.ts b/packages/my-near-wallet/src/lib/my-near-wallet.spec.ts index 1cee4c83e..94b32b37b 100644 --- a/packages/my-near-wallet/src/lib/my-near-wallet.spec.ts +++ b/packages/my-near-wallet/src/lib/my-near-wallet.spec.ts @@ -132,3 +132,31 @@ describe("buildImportAccountsUrl", () => { ); }); }); + +describe("signMessage", () => { + it("sign message", async () => { + const { wallet } = await createMyNearWallet(); + + const replace = window.location.replace; + + Object.defineProperty(window, "location", { + value: { replace: jest.fn() }, + }); + + const attributes = { + message: "test message", + nonce: Buffer.from("30990309-30990309-390A303-292090"), + recipient: "test.app", + callbackUrl: "https://test.app", + }; + + const result = await wallet.signMessage!(attributes); + + expect(result).toBe(undefined); + expect(window.location.replace).toHaveBeenCalledWith( + "https://testnet.mynearwallet.com/sign-message?message=test+message&nonce=30990309-30990309-390A303-292090&recipient=test.app&callbackUrl=https%3A%2F%2Ftest.app" + ); + + window.location.replace = replace; + }); +}); 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 d9e6ca35a..4095d4a1c 100644 --- a/packages/my-near-wallet/src/lib/my-near-wallet.ts +++ b/packages/my-near-wallet/src/lib/my-near-wallet.ts @@ -160,6 +160,33 @@ const MyNearWallet: WalletBehaviourFactory< throw new Error(`Method not supported by ${metadata.name}`); }, + async signMessage({ message, nonce, recipient, callbackUrl, state }) { + logger.log("sign message", { message }); + + 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 href = new URL(params.walletUrl); + href.pathname = "sign-message"; + href.searchParams.append("message", message); + href.searchParams.append("nonce", nonce.toString()); + href.searchParams.append("recipient", recipient); + href.searchParams.append("callbackUrl", url); + if (state) { + href.searchParams.append("state", state); + } + + window.location.replace(href.toString()); + + return; + }, + async signAndSendTransaction({ signerId, receiverId, diff --git a/packages/narwallets/package.json b/packages/narwallets/package.json index e187fc585..775879037 100644 --- a/packages/narwallets/package.json +++ b/packages/narwallets/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/narwallets", - "version": "8.5.4", + "version": "8.6.0", "description": "This is the Narwallets package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/near-snap/package.json b/packages/near-snap/package.json index 1577ca3b7..052699fb8 100644 --- a/packages/near-snap/package.json +++ b/packages/near-snap/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/near-snap", - "version": "8.5.4", + "version": "8.6.0", "description": "Metamask snap to interact with Near dapps.", "keywords": [ "near", diff --git a/packages/near-wallet/package.json b/packages/near-wallet/package.json index 6f270ddfc..1bbe1d5a9 100644 --- a/packages/near-wallet/package.json +++ b/packages/near-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/near-wallet", - "version": "8.5.4", + "version": "8.6.0", "description": "Near Wallet package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/nearfi/package.json b/packages/nearfi/package.json index 39ddc9dad..7c37379dc 100644 --- a/packages/nearfi/package.json +++ b/packages/nearfi/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/nearfi", - "version": "8.5.4", + "version": "8.6.0", "description": "Nearfi package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/neth/package.json b/packages/neth/package.json index c539605b3..4c6fef846 100644 --- a/packages/neth/package.json +++ b/packages/neth/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/neth", - "version": "8.5.4", + "version": "8.6.0", "description": "Control NEAR accounts with ETH accounts", "author": "mattlockyer", "keywords": [ diff --git a/packages/nightly-connect/package.json b/packages/nightly-connect/package.json index 41ef8bf6c..c8356dbf4 100644 --- a/packages/nightly-connect/package.json +++ b/packages/nightly-connect/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/nightly-connect", - "version": "8.5.4", + "version": "8.6.0", "description": "Nightly connect package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/nightly/package.json b/packages/nightly/package.json index 238621b40..a75dc6009 100644 --- a/packages/nightly/package.json +++ b/packages/nightly/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/nightly", - "version": "8.5.4", + "version": "8.6.0", "description": "Nightly wallet package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/opto-wallet/package.json b/packages/opto-wallet/package.json index 0dfc97af5..4526c1a7c 100644 --- a/packages/opto-wallet/package.json +++ b/packages/opto-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/opto-wallet", - "version": "8.5.4", + "version": "8.6.0", "description": "Opto wallet package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/ramper-wallet/package.json b/packages/ramper-wallet/package.json index f1e2128f9..4e8708060 100644 --- a/packages/ramper-wallet/package.json +++ b/packages/ramper-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/ramper-wallet", - "version": "8.5.4", + "version": "8.6.0", "description": "Ramper wallet package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/sender/package.json b/packages/sender/package.json index a468a7c82..fe295dd07 100644 --- a/packages/sender/package.json +++ b/packages/sender/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/sender", - "version": "8.5.4", + "version": "8.6.0", "description": "Sender wallet package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/wallet-connect/package.json b/packages/wallet-connect/package.json index 4e0745403..4e289b059 100644 --- a/packages/wallet-connect/package.json +++ b/packages/wallet-connect/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/wallet-connect", - "version": "8.5.4", + "version": "8.6.0", "description": "Wallet Connect package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/wallet-connect/src/lib/wallet-connect.ts b/packages/wallet-connect/src/lib/wallet-connect.ts index 7544326c9..5f5351d2f 100644 --- a/packages/wallet-connect/src/lib/wallet-connect.ts +++ b/packages/wallet-connect/src/lib/wallet-connect.ts @@ -12,6 +12,8 @@ import type { EventEmitterService, VerifiedOwner, Account, + SignMessageParams, + SignedMessage, } from "@near-wallet-selector/core"; import { getActiveAccount } from "@near-wallet-selector/core"; import { createAction } from "@near-wallet-selector/wallet-utils"; @@ -57,6 +59,13 @@ interface WalletConnectState { subscriptions: Array; } +interface ConnectParams { + state: WalletConnectState; + chainId: string; + qrCodeModal: boolean; + projectId: string; +} + const WC_METHODS = [ "near_signIn", "near_signOut", @@ -64,6 +73,7 @@ const WC_METHODS = [ "near_signTransaction", "near_signTransactions", "near_verifyOwner", + "near_signMessage", ]; const WC_EVENTS = ["chainChanged", "accountsChanged"]; @@ -99,6 +109,38 @@ const setupWalletConnectState = async ( }; }; +const connect = async ({ + state, + chainId, + qrCodeModal, + projectId, +}: ConnectParams) => { + return await state.client.connect( + { + requiredNamespaces: { + near: { + chains: [chainId], + methods: WC_METHODS, + events: WC_EVENTS, + }, + }, + }, + qrCodeModal, + projectId, + chainId + ); +}; + +const disconnect = async ({ state }: { state: WalletConnectState }) => { + await state.client.disconnect({ + topic: state.session!.topic, + reason: { + code: 5900, + message: "User disconnected", + }, + }); +}; + const WalletConnect: WalletBehaviourFactory< BridgeWallet, { params: WalletConnectExtraOptions } @@ -248,6 +290,26 @@ const WalletConnect: WalletBehaviourFactory< }); }; + const requestSignMessage = async ( + messageParams: SignMessageParams & { accountId?: string } + ) => { + const { message, nonce, recipient, callbackUrl, accountId } = messageParams; + return _state.client.request({ + topic: _state.session!.topic, + chainId: getChainId(), + request: { + method: "near_signMessage", + params: { + message, + nonce, + recipient, + ...(callbackUrl && { callbackUrl }), + ...(accountId && { accountId }), + }, + }, + }); + }; + const requestSignTransaction = async (transaction: Transaction) => { const accounts = await requestAccounts(); const account = accounts.find((x) => x.accountId === transaction.signerId); @@ -428,13 +490,7 @@ const WalletConnect: WalletBehaviourFactory< if (_state.session) { await requestSignOut(); - await _state.client.disconnect({ - topic: _state.session.topic, - reason: { - code: 5900, - message: "User disconnected", - }, - }); + await disconnect({ state: _state }); } await cleanup(); @@ -474,35 +530,27 @@ const WalletConnect: WalletBehaviourFactory< return { async signIn({ contractId, methodNames = [], qrCodeModal = true }) { - const existingAccounts = await getAccounts(); - - if (existingAccounts.length) { - return existingAccounts; - } - try { + const { contract } = store.getState(); + if (_state.session && !contract) { + await disconnect({ state: _state }); + await cleanup(); + } + const chainId = getChainId(); - _state.session = await _state.client.connect( - { - requiredNamespaces: { - near: { - chains: [getChainId()], - methods: WC_METHODS, - events: WC_EVENTS, - }, - }, - }, + _state.session = await connect({ + state: _state, + chainId, qrCodeModal, - params.projectId, - chainId - ); + projectId: params.projectId, + }); await requestSignIn({ receiverId: contractId, methodNames }); await setupEvents(); - return getAccounts(); + return await getAccounts(); } catch (err) { await signOut(); @@ -534,6 +582,38 @@ const WalletConnect: WalletBehaviourFactory< return requestVerifyOwner(account.accountId, message); }, + async signMessage({ message, nonce, recipient, callbackUrl }) { + logger.log("WalletConnect:signMessage", { message, nonce, recipient }); + + try { + const chainId = getChainId(); + + if (!_state.session) { + _state.session = _state.session = await connect({ + state: _state, + chainId, + qrCodeModal: true, + projectId: params.projectId, + }); + } + + const account = getActiveAccount(store.getState()); + + return await requestSignMessage({ + message, + nonce, + recipient, + callbackUrl, + accountId: account?.accountId, + }); + } catch (err) { + await disconnect({ state: _state }); + await cleanup(); + + throw err; + } + }, + async signAndSendTransaction({ signerId, receiverId, actions }) { logger.log("signAndSendTransaction", { signerId, receiverId, actions }); diff --git a/packages/wallet-utils/package.json b/packages/wallet-utils/package.json index 21420697a..2598cbab8 100644 --- a/packages/wallet-utils/package.json +++ b/packages/wallet-utils/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/wallet-utils", - "version": "8.5.4", + "version": "8.6.0", "description": "Wallet utils package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/welldone-wallet/package.json b/packages/welldone-wallet/package.json index 6c178f621..50ec2157e 100644 --- a/packages/welldone-wallet/package.json +++ b/packages/welldone-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/welldone-wallet", - "version": "8.5.4", + "version": "8.6.0", "description": "Welldone wallet package for NEAR Wallet Selector.", "keywords": [ "near", diff --git a/packages/xdefi/package.json b/packages/xdefi/package.json index 9dd4c1fdf..ce4248b28 100644 --- a/packages/xdefi/package.json +++ b/packages/xdefi/package.json @@ -1,6 +1,6 @@ { "name": "@near-wallet-selector/xdefi", - "version": "8.5.4", + "version": "8.6.0", "description": "This is the XDEFI package for NEAR Wallet Selector.", "keywords": [ "near",