Picket Docs
Search…
✍
Signatures
In order to verify that a user has ownership of a wallet address, Picket requires users to sign a nonce with the wallet's private key. This signed nonce is referred to as a signature. A signature can be decrypted to prove that the user signed it with the private key associated with their wallet address.
Obtaining a signature for a given user is the basis for authentication and authorization in Picket.

Why use Picket for this?

Poorly handled signatures are not secure. Since signatures are obtained client side, the risk of a signature being stolen needs to be considered non-zero. Asking a user to sign the same text repeatedly for example, presents a security risk for your users because anyone who gets access to the signature can then masquerade as the owner of the wallet.
Picket handles generating secure and randomized nonces for you. Each nonce is scoped to a given project and has a limited time to live. This allows for a secure wallet verification experience for your users without any work or maintenance from you.
In addition to security, Picket provides a human-readable message with every nonce. These messages help users understand what they are doing when prompted by their wallet provider to sign the nonce. Messages can be scoped to a project to give the best possible experience to users within your app.

Fetch user nonce

If you’d like to sign the user nonce manually, you can fetch the nonce for signing via this endpoint. Given the resulting nonce, you can proceed to sign the nonce with the user’s private key via any existing convenience library.

Signing Nonces

If you are using Picket's client-side SDKs, then obtaining a user's signature is handled for you as part of the authorization flow.
However, if you want to handle obtaining user signatures yourself Picket makes that possible too.

Using a Picket SDK (Connect Wallet)

This is the recommended and easiest way to obtain a signature. The connect method fetches a nonce as well as initiating a signature request via a connected wallet on the client side. Returns the connected wallet address and a signature. This operation is done via a picket client library.​​

Steps for Manually Obtaining Signatures

Using the connect method via a picket SDK for obtaining a signature is the recommended and easier route. However, if you would like to manually sign a nonce for some reasons that may include your use of a language that currently lacks picket SDK support or a desire for more control over the wallet conneciton operation then you can follow these steps to do so.
  1. 1.
    Connect your user to a wallet provider
  2. 2.
    Use the nonce endpoint to fetch the random nonce for a given wallet address
  3. 3.
    Sign the nonce with the signMessage method on the wallet provider
EVM
Solana
import { ethers } from "ethers";
import Picket from "@picketapi/picket-node";
​
const picket = new Picket("YOUR_SECRET_KEY_HERE");
​
const { provider } = await picket.connect();
​
const wallet = await new ethers.providers.Web3Provider(provider);
const signer = await wallet.getSigner();
// Get user's connected wallet address
const walletAddress = await signer.getAddress();
​
const { nonce } = await picket.nonce({ walletAddress });
// Prompt user to click to sign the nonce with their private key
const signature = await signer.signMessage(nonce);
import bs58 from "bs58";
import Picket from "@picketapi/picket-js";
​
const picket = new Picket("YOUR_PUBLISHABLE_KEY_HERE");
​
const chain = "solana";
​
const { provider } = await picket.connect({ chain });
​
const { publicKey } = provider;
const walletAddress = publicKey.toString();
​
const { nonce } = await picket.nonce({ chain, walletAddress });
​
const message = new TextEncoder().encode(nonce);
const signatureBytes = await provider.signMessage(message);
const signature = bs58.encode(signatureBytes);
  1. 1.
    Use the nonce endpoint to fetch the current nonce for a given wallet address
  2. 2.
    Use a web3 utilities library to verify the signature is signed by the intended wallet address
EVM
Solana
import { ethers } from "ethers";
import Picket from "@picketapi/picket-node";
​
const picket = new Picket("YOUR_SECRET_KEY_HERE");
​
// Insert wallet address to verify as signer of message here
const walletAddress = "0x...abc";
const signature = "SUPER_SECRET_SIGNATURE";
​
const { nonce } = await picket.nonce({ walletAddress })
​
const signer = ethers.utils.verifyMessage(nonce, signature);
​
// check if the walletAddress is the signer
if (signer !== walletAddress) {
console.error(`invalid signature: want signer ${walletAddress}; got signer ${signer}`);
}
​
import { ethers } from "ethers";
import Picket from "@picketapi/picket-node";
​
const picket = new Picket("YOUR_SECRET_KEY_HERE");
​
const chain = "solana";
​
// Insert wallet address to verify as signer of message here
const walletAddress = "0x...abc";
const signature = "SUPER_SECRET_SIGNATURE";
​
const { nonce } = await picket.nonce({ chain, walletAddress })
​
const messageBytes = new TextEncoder().encode(nonce);
const walletAddressBytes = bs58.decode(walletAddress);
const signatureBytes = bs58.decode(signature);
const success = nacl.sign.detached.verify(
messageBytes,
signatureBytes,
walletAddressBytes
);
​
// check if the walletAddress is the signer
if (!success) {
console.error("invalid signature");
}
Copy link
On this page
Why use Picket for this?
Fetch user nonce
Signing Nonces