# NEP-413 Message Signing & Verification NEP-413 message signing/verification. ## Table of Contents 1. [NEP-413 Message Verification](#nep-413-message-verification) 2. [NEP-413 Message Signing](#nep-413-message-signing) --- ## NEP-413 Message Verification ### verifyMessage() ```typescript import { verifyMessage } from "near-api-js/nep413"; import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://test.rpc.fastnear.com", }); // The challenge given to the user to sign const MESSAGE = "log me in"; const APP = "http://localhost:3000"; const CHALLENGE = Buffer.from(Array.from(Array(32).keys())); // Example object that could have been returned by a wallet after logging in const walletReturn = { signature: "IfModLa3g3czlyPhkg/LSkTFSy7XCGreStZJTDIO1m3viEnYFLdXfpz1gYUVKYv3W2vwcV77TmGEzc9y0Nz+AA==", accountId: "alice.near", publicKey: "ed25519:AtH7GEjv2qmBVoT8qoRhWXizXM5CC12DC6tiqY9iNoRm", }; // Throws an error if verification fails await verifyMessage({ signerAccountId: walletReturn.accountId, signerPublicKey: walletReturn.publicKey, signature: new Uint8Array(Buffer.from(walletReturn.signature, "base64")), payload: { message: MESSAGE, recipient: APP, nonce: CHALLENGE, }, provider, }); ``` --- ## NEP-413 Message Signing ### signMessage() ```typescript import { signMessage } from "near-api-js/nep413"; import { Account, KeyPairSigner, KeyPair } from "near-api-js"; const account = new Account("bob.near", provider, new KeyPairSigner(keyPair)); const signedMessage = await signMessage({ signerAccount: account, payload: { message: "Hello, world!", recipient: "alice.near", nonce: new Uint8Array(new Array(32)), // random 32 bytes }, }); // signedMessage contains the signature that can be passed to verifyMessage ``` ### Authentication Flow ```typescript // 1. Server generates nonce const nonce = crypto.getRandomValues(new Uint8Array(32)); // 2. Client signs with signMessage const signedMessage = await signMessage({ signerAccount: account, payload: { message: `Sign in to MyApp`, recipient: "myapp.com", nonce, }, }); // 3. Send to server for verification await fetch("/api/auth/verify", { method: "POST", body: JSON.stringify({ accountId: account.accountId, publicKey: (await account.signer.getPublicKey()).toString(), signature: Array.from(signedMessage.signature), nonce: Array.from(nonce), }), }); // 4. Server verifies await verifyMessage({ signerAccountId: body.accountId, signerPublicKey: body.publicKey, signature: new Uint8Array(body.signature), payload: { message: "Sign in to MyApp", recipient: "myapp.com", nonce: Buffer.from(body.nonce), }, provider, }); ```