Signed Request Reference
Sign the resource ID, content, price and deadline separately from a purchase voucher.
SessionRequest typed data#
SessionRequest uses EIP-712 domain Fuyu Session Requests, version 1, for the configured chain and core contract. Its fields identify the session, hashed request ID, content digest, amount and deadline.
Voucher uses another domain and signs cumulativeAmount. Keep these formats separate when carrying requests over a transport, logging them or checking authentication.
| Field | Format | Use |
|---|---|---|
| sessionId | bytes32 | Identifies the funded session |
| requestIdHash | bytes32 | keccak256 of the UTF-8 request ID |
| requestDigest | bytes32 | Identifies the resource and content |
| amount | Unsigned atomic-unit integer | Sets the request price |
| deadline | Unsigned Unix-second integer | Sets when the request expires |
Define the content digest#
Publish a codec covering every option that affects the result: method and route, body, model and other relevant parameters. Recompute it on the server from the request you receive. Do not accept the client's digest without that comparison.
This example combines a route identifier with a hash of the body bytes. The application defines that resource codec separately from the EIP-712 signing domain.
const { ethers } = require("ethers");
const routeId = ethers.utils.id("fuyu.example/inference/v1");
const requestBodyBytes = ethers.utils.toUtf8Bytes('{"prompt":"hello"}');
const requestDigest = ethers.utils.keccak256(
ethers.utils.defaultAbiCoder.encode(
["bytes32", "bytes32"],
[routeId, ethers.utils.keccak256(requestBodyBytes)],
),
);
console.log(requestDigest);Choose stable request IDs#
A Session request ID is a nonempty string of at most 1024 JavaScript characters. The signature covers keccak256 of its UTF-8 bytes. Reuse the ID for a retry of one job; choose a fresh ID for new work.
After expiry, obtain a fresh signed deadline for the same ID, digest and price. It can retrieve the existing debit receipt without charging again. Your job ledger still needs to prevent repeated provider execution.
Recompute the merchant context#
For consume or receive, calculate requestId, requestDigest and amount from the actual route and server pricing. Copying them from the customer's envelope would skip the check that the authorization matches the requested work.
Associate the payment receipt with a durable job record. Use provider idempotency when available and return cached output for an already accepted request.