Signing Requests
How it works
Building the stamp
const nacl = require("tweetnacl");
const { randomUUID } = require("crypto");
function normalizeRoutePath(path) {
const withSlash = path.startsWith("/") ? path : `/${path}`;
return withSlash.length > 1 ? withSlash.replace(/\/+$/, "") : withSlash;
}
// Must match the server's route pattern exactly, e.g. "POST /waas/create-wallet"
function buildActionBinding(method, routePath) {
return `${method.toUpperCase()} ${normalizeRoutePath(routePath)}`;
}
function buildXStamp(binding, params, keypair) {
const canonical = JSON.stringify([binding, Object.entries(params)]);
const sigBytes = nacl.sign.detached(Buffer.from(canonical, "utf8"), keypair.secretKey);
const stamp = {
publicKey: Buffer.from(keypair.publicKey).toString("hex"),
signature: Buffer.from(sigBytes).toString("hex"),
};
return Buffer.from(JSON.stringify(stamp)).toString("base64url");
}