Skip to content

Commit

Permalink
Merge pull request #971 from near/dev
Browse files Browse the repository at this point in the history
v8.6.0 Release (dev -> main)
  • Loading branch information
erditkurteshiSQA authored Oct 18, 2023
2 parents dabc8b5 + 6824621 commit 11aa921
Show file tree
Hide file tree
Showing 33 changed files with 384 additions and 108 deletions.
110 changes: 83 additions & 27 deletions examples/angular/src/app/components/content/content.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -52,6 +57,7 @@ export class ContentComponent implements OnInit, OnDestroy {
this.messages = messages;

this.subscribeToEvents();
await this.verifyMessageBrowserWallet();
}

async getAccountBalance({ provider, accountId }: GetAccountBalanceProps) {
Expand Down Expand Up @@ -165,45 +171,95 @@ 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,
nonce,
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 =
Expand Down
116 changes: 89 additions & 27 deletions examples/react/components/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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
}, []);

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -266,39 +341,26 @@ 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,
nonce,
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 =
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
2 changes: 1 addition & 1 deletion packages/account-export/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
2 changes: 1 addition & 1 deletion packages/coin98-wallet/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -284,6 +305,8 @@ export class WalletModules {
);
}

this.validateSignMessageParams(params);

return await _signMessage(params);
};

Expand Down
2 changes: 1 addition & 1 deletion packages/default-wallets/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
2 changes: 1 addition & 1 deletion packages/finer-wallet/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
2 changes: 1 addition & 1 deletion packages/here-wallet/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
Loading

0 comments on commit 11aa921

Please sign in to comment.