@perkos/agent-sdk 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/x402.d.ts ADDED
@@ -0,0 +1,60 @@
1
+ import { decodePaymentRequiredHeader, decodePaymentResponseHeader, decodePaymentSignatureHeader, encodePaymentRequiredHeader, encodePaymentResponseHeader, encodePaymentSignatureHeader } from "@x402/core/http";
2
+ import type { PaymentPayload, PaymentPayloadResult, PaymentRequired, PaymentRequirements, ResourceInfo, SchemeNetworkClient, SettleResponse } from "@x402/core/types";
3
+ import type { AmountLike, ConfirmationOptions, ContractId, FundJobInput, JobRecord, PaymentAsset, PerkOSNetwork, ResolvedPerkOSConfig, TransactionConfirmation, TransactionReceipt } from "./types.js";
4
+ export declare const X402_VERSION = 2;
5
+ export declare const PERKOS_X402_SCHEME = "exact";
6
+ export declare const PERKOS_X402_ASSET_TRANSFER_METHOD = "perkos-escrow-v1";
7
+ export declare const PERKOS_X402_PAYMENT_FLOW = "upfront";
8
+ export declare const STACKS_X402_NETWORKS: {
9
+ readonly mainnet: "stacks:1";
10
+ readonly testnet: "stacks:2147483648";
11
+ };
12
+ export interface PerkOSX402ClientLike {
13
+ readonly config: ResolvedPerkOSConfig;
14
+ getJob(asset: PaymentAsset, jobId: AmountLike): Promise<JobRecord | null>;
15
+ fundJob(input: FundJobInput): Promise<TransactionReceipt>;
16
+ confirm(receiptOrTxid: TransactionReceipt | string, options?: ConfirmationOptions): Promise<TransactionConfirmation>;
17
+ }
18
+ export interface PerkOSX402PaymentRequiredInput {
19
+ readonly resource: ResourceInfo;
20
+ readonly asset: PaymentAsset;
21
+ readonly jobId: AmountLike;
22
+ readonly amount: AmountLike;
23
+ readonly maxTimeoutSeconds?: number;
24
+ readonly error?: string;
25
+ }
26
+ export interface ParsedPerkOSX402Requirement {
27
+ readonly network: PerkOSNetwork;
28
+ readonly asset: PaymentAsset;
29
+ readonly jobId: bigint;
30
+ readonly amount: bigint;
31
+ readonly commerceContract: ContractId;
32
+ readonly assetIdentifier: string;
33
+ readonly maxTimeoutSeconds: number;
34
+ }
35
+ export interface PerkOSX402PaymentProof extends ParsedPerkOSX402Requirement {
36
+ readonly transaction: string;
37
+ readonly payer: string;
38
+ readonly blockHeight?: number;
39
+ readonly blockHash?: string;
40
+ }
41
+ export interface PerkOSX402SchemeClientOptions {
42
+ readonly client: PerkOSX402ClientLike;
43
+ readonly confirmation?: ConfirmationOptions;
44
+ }
45
+ export declare function toStacksX402Network(network: PerkOSNetwork): (typeof STACKS_X402_NETWORKS)[PerkOSNetwork];
46
+ export declare function fromStacksX402Network(network: string): PerkOSNetwork;
47
+ export declare function createPerkOSX402PaymentRequired(config: ResolvedPerkOSConfig, input: PerkOSX402PaymentRequiredInput): PaymentRequired;
48
+ export declare function parsePerkOSX402Requirement(config: ResolvedPerkOSConfig, paymentRequirements: PaymentRequirements): ParsedPerkOSX402Requirement;
49
+ export declare function parsePerkOSX402PaymentPayload(config: ResolvedPerkOSConfig, paymentPayload: PaymentPayload): PerkOSX402PaymentProof;
50
+ export declare class PerkOSX402SchemeClient implements SchemeNetworkClient {
51
+ readonly scheme = "exact";
52
+ private readonly client;
53
+ private readonly confirmation;
54
+ constructor(options: PerkOSX402SchemeClientOptions);
55
+ createPaymentPayload(x402Version: number, paymentRequirements: PaymentRequirements): Promise<PaymentPayloadResult>;
56
+ private assertReceipt;
57
+ }
58
+ export { decodePaymentRequiredHeader, decodePaymentResponseHeader, decodePaymentSignatureHeader, encodePaymentRequiredHeader, encodePaymentResponseHeader, encodePaymentSignatureHeader, };
59
+ export type { PaymentPayload, PaymentRequired, PaymentRequirements, ResourceInfo, SettleResponse, };
60
+ //# sourceMappingURL=x402.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402.d.ts","sourceRoot":"","sources":["../src/x402.ts"],"names":[],"mappings":"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"}
package/dist/x402.js ADDED
@@ -0,0 +1,306 @@
1
+ import { decodePaymentRequiredHeader, decodePaymentResponseHeader, decodePaymentSignatureHeader, encodePaymentRequiredHeader, encodePaymentResponseHeader, encodePaymentSignatureHeader, } from "@x402/core/http";
2
+ import { validatePaymentPayload, validatePaymentRequired, validatePaymentRequirements, } from "@x402/core/schemas";
3
+ import { PerkOSError } from "./errors.js";
4
+ import { normalizeTxid } from "./txid.js";
5
+ import { assertPrincipal, toUint } from "./validation.js";
6
+ export const X402_VERSION = 2;
7
+ export const PERKOS_X402_SCHEME = "exact";
8
+ export const PERKOS_X402_ASSET_TRANSFER_METHOD = "perkos-escrow-v1";
9
+ export const PERKOS_X402_PAYMENT_FLOW = "upfront";
10
+ export const STACKS_X402_NETWORKS = {
11
+ mainnet: "stacks:1",
12
+ testnet: "stacks:2147483648",
13
+ };
14
+ const X402_NETWORK_TO_PERKOS = {
15
+ "stacks:1": "mainnet",
16
+ "stacks:2147483648": "testnet",
17
+ };
18
+ const DEFAULT_TIMEOUT_SECONDS = 600;
19
+ const MAX_TIMEOUT_SECONDS = 3_600;
20
+ function x402Error(message, details) {
21
+ return new PerkOSError("X402_INVALID", message, details);
22
+ }
23
+ function commerceContract(config, asset) {
24
+ return asset === "sbtc" ? config.contracts.sbtcCommerce : config.contracts.stxCommerce;
25
+ }
26
+ function assetIdentifier(config, asset) {
27
+ return asset === "sbtc"
28
+ ? `${config.contracts.sbtcToken}::${config.contracts.sbtcAssetName}`
29
+ : "STX";
30
+ }
31
+ function parseProtocolObject(label, parser) {
32
+ try {
33
+ return parser();
34
+ }
35
+ catch (cause) {
36
+ throw x402Error(`${label} is not a valid x402 v2 object.`, { cause });
37
+ }
38
+ }
39
+ function requireExtraString(extra, field) {
40
+ const value = extra[field];
41
+ if (typeof value !== "string" || value.length === 0) {
42
+ throw x402Error(`paymentRequirements.extra.${field} must be a non-empty string.`, {
43
+ field,
44
+ value,
45
+ });
46
+ }
47
+ return value;
48
+ }
49
+ function parseTimeout(value) {
50
+ if (!Number.isSafeInteger(value) || value <= 0 || value > MAX_TIMEOUT_SECONDS) {
51
+ throw x402Error(`maxTimeoutSeconds must be an integer between 1 and ${MAX_TIMEOUT_SECONDS}.`, { value });
52
+ }
53
+ return value;
54
+ }
55
+ function parseResource(resource) {
56
+ let url;
57
+ try {
58
+ url = new URL(resource.url);
59
+ }
60
+ catch (cause) {
61
+ throw x402Error("resource.url must be a valid HTTP or HTTPS URL.", { cause });
62
+ }
63
+ if (url.protocol !== "https:" && url.protocol !== "http:") {
64
+ throw x402Error("resource.url must use HTTP or HTTPS.", { protocol: url.protocol });
65
+ }
66
+ return resource;
67
+ }
68
+ export function toStacksX402Network(network) {
69
+ return STACKS_X402_NETWORKS[network];
70
+ }
71
+ export function fromStacksX402Network(network) {
72
+ const resolved = X402_NETWORK_TO_PERKOS[network];
73
+ if (!resolved) {
74
+ throw x402Error("network must be a supported Stacks CAIP-2 identifier.", { network });
75
+ }
76
+ return resolved;
77
+ }
78
+ export function createPerkOSX402PaymentRequired(config, input) {
79
+ const jobId = toUint(input.jobId, "jobId");
80
+ const amount = toUint(input.amount, "amount");
81
+ const contract = commerceContract(config, input.asset);
82
+ const timeout = parseTimeout(input.maxTimeoutSeconds ?? DEFAULT_TIMEOUT_SECONDS);
83
+ const paymentRequired = {
84
+ x402Version: X402_VERSION,
85
+ ...(input.error ? { error: input.error } : {}),
86
+ resource: parseResource(input.resource),
87
+ accepts: [
88
+ {
89
+ scheme: PERKOS_X402_SCHEME,
90
+ network: toStacksX402Network(config.network),
91
+ amount: amount.toString(),
92
+ asset: assetIdentifier(config, input.asset),
93
+ payTo: contract,
94
+ maxTimeoutSeconds: timeout,
95
+ extra: {
96
+ assetTransferMethod: PERKOS_X402_ASSET_TRANSFER_METHOD,
97
+ paymentFlow: PERKOS_X402_PAYMENT_FLOW,
98
+ paymentAsset: input.asset,
99
+ jobId: jobId.toString(),
100
+ commerceContract: contract,
101
+ },
102
+ },
103
+ ],
104
+ extensions: {},
105
+ };
106
+ return parseProtocolObject("paymentRequired", () => {
107
+ validatePaymentRequired(paymentRequired);
108
+ return paymentRequired;
109
+ });
110
+ }
111
+ export function parsePerkOSX402Requirement(config, paymentRequirements) {
112
+ const requirements = parseProtocolObject("paymentRequirements", () => {
113
+ validatePaymentRequirements(paymentRequirements);
114
+ return paymentRequirements;
115
+ });
116
+ if (requirements.scheme !== PERKOS_X402_SCHEME) {
117
+ throw x402Error(`scheme must be ${PERKOS_X402_SCHEME}.`, {
118
+ scheme: requirements.scheme,
119
+ });
120
+ }
121
+ const network = fromStacksX402Network(requirements.network);
122
+ if (network !== config.network) {
123
+ throw x402Error("The x402 requirement network does not match the SDK client network.", {
124
+ requirementNetwork: network,
125
+ clientNetwork: config.network,
126
+ });
127
+ }
128
+ const extra = requirements.extra ?? {};
129
+ if (requireExtraString(extra, "assetTransferMethod") !== PERKOS_X402_ASSET_TRANSFER_METHOD) {
130
+ throw x402Error(`assetTransferMethod must be ${PERKOS_X402_ASSET_TRANSFER_METHOD}.`);
131
+ }
132
+ if (requireExtraString(extra, "paymentFlow") !== PERKOS_X402_PAYMENT_FLOW) {
133
+ throw x402Error(`paymentFlow must be ${PERKOS_X402_PAYMENT_FLOW}.`);
134
+ }
135
+ const paymentAsset = requireExtraString(extra, "paymentAsset");
136
+ if (paymentAsset !== "sbtc" && paymentAsset !== "stx") {
137
+ throw x402Error('paymentAsset must be "sbtc" or "stx".', { paymentAsset });
138
+ }
139
+ const asset = paymentAsset;
140
+ const expectedContract = commerceContract(config, asset);
141
+ const declaredContract = requireExtraString(extra, "commerceContract");
142
+ if (requirements.payTo !== expectedContract || declaredContract !== expectedContract) {
143
+ throw x402Error("payTo and commerceContract must match the configured escrow contract.", {
144
+ payTo: requirements.payTo,
145
+ declaredContract,
146
+ expectedContract,
147
+ });
148
+ }
149
+ const expectedAsset = assetIdentifier(config, asset);
150
+ if (requirements.asset !== expectedAsset) {
151
+ throw x402Error("The x402 asset does not match the configured settlement asset.", {
152
+ asset: requirements.asset,
153
+ expectedAsset,
154
+ });
155
+ }
156
+ const jobId = toUint(requireExtraString(extra, "jobId"), "jobId");
157
+ const amount = toUint(requirements.amount, "amount");
158
+ return {
159
+ network,
160
+ asset,
161
+ jobId,
162
+ amount,
163
+ commerceContract: expectedContract,
164
+ assetIdentifier: expectedAsset,
165
+ maxTimeoutSeconds: parseTimeout(requirements.maxTimeoutSeconds),
166
+ };
167
+ }
168
+ export function parsePerkOSX402PaymentPayload(config, paymentPayload) {
169
+ const parsed = parseProtocolObject("paymentPayload", () => {
170
+ validatePaymentPayload(paymentPayload);
171
+ return paymentPayload;
172
+ });
173
+ if (parsed.x402Version !== X402_VERSION) {
174
+ throw x402Error(`x402Version must be ${X402_VERSION}.`, {
175
+ x402Version: parsed.x402Version,
176
+ });
177
+ }
178
+ const requirement = parsePerkOSX402Requirement(config, parsed.accepted);
179
+ const transactionValue = parsed.payload.transaction;
180
+ const payer = parsed.payload.payer;
181
+ const jobId = parsed.payload.jobId;
182
+ const amount = parsed.payload.amount;
183
+ const paymentAsset = parsed.payload.asset;
184
+ const contract = parsed.payload.commerceContract;
185
+ if (typeof transactionValue !== "string") {
186
+ throw x402Error("payload.transaction must be a Stacks transaction ID.");
187
+ }
188
+ const transaction = normalizeTxid(transactionValue);
189
+ if (typeof payer !== "string") {
190
+ throw x402Error("payload.payer must be a Stacks principal.");
191
+ }
192
+ assertPrincipal(payer, "payload.payer", config.network);
193
+ if (jobId !== requirement.jobId.toString()) {
194
+ throw x402Error("payload.jobId does not match the accepted requirement.", {
195
+ jobId,
196
+ expectedJobId: requirement.jobId.toString(),
197
+ });
198
+ }
199
+ if (amount !== requirement.amount.toString()) {
200
+ throw x402Error("payload.amount does not match the accepted requirement.", {
201
+ amount,
202
+ expectedAmount: requirement.amount.toString(),
203
+ });
204
+ }
205
+ if (paymentAsset !== requirement.asset || contract !== requirement.commerceContract) {
206
+ throw x402Error("The payment proof asset or contract does not match the requirement.", {
207
+ paymentAsset,
208
+ contract,
209
+ });
210
+ }
211
+ const blockHeight = parsed.payload.blockHeight;
212
+ const blockHash = parsed.payload.blockHash;
213
+ if (blockHeight !== undefined &&
214
+ (typeof blockHeight !== "number" ||
215
+ !Number.isSafeInteger(blockHeight) ||
216
+ blockHeight < 0)) {
217
+ throw x402Error("payload.blockHeight must be a non-negative safe integer.");
218
+ }
219
+ if (blockHash !== undefined && typeof blockHash !== "string") {
220
+ throw x402Error("payload.blockHash must be a string.");
221
+ }
222
+ return {
223
+ ...requirement,
224
+ transaction,
225
+ payer,
226
+ ...(typeof blockHeight === "number" ? { blockHeight } : {}),
227
+ ...(typeof blockHash === "string" ? { blockHash } : {}),
228
+ };
229
+ }
230
+ export class PerkOSX402SchemeClient {
231
+ scheme = PERKOS_X402_SCHEME;
232
+ client;
233
+ confirmation;
234
+ constructor(options) {
235
+ this.client = options.client;
236
+ this.confirmation = options.confirmation ?? {};
237
+ }
238
+ async createPaymentPayload(x402Version, paymentRequirements) {
239
+ if (x402Version !== X402_VERSION) {
240
+ throw x402Error(`x402Version must be ${X402_VERSION}.`, { x402Version });
241
+ }
242
+ const requirement = parsePerkOSX402Requirement(this.client.config, paymentRequirements);
243
+ const job = await this.client.getJob(requirement.asset, requirement.jobId);
244
+ if (!job) {
245
+ throw x402Error(`Job ${requirement.jobId} does not exist.`, {
246
+ jobId: requirement.jobId,
247
+ asset: requirement.asset,
248
+ });
249
+ }
250
+ if (job.status !== "open") {
251
+ throw x402Error(`Job ${requirement.jobId} must be open before x402 funding.`, {
252
+ status: job.status,
253
+ });
254
+ }
255
+ if (job.budget !== requirement.amount) {
256
+ throw x402Error("The on-chain job budget does not match the x402 amount.", {
257
+ jobBudget: job.budget,
258
+ requirementAmount: requirement.amount,
259
+ });
260
+ }
261
+ const receipt = await this.client.fundJob({
262
+ asset: requirement.asset,
263
+ jobId: requirement.jobId,
264
+ amount: requirement.amount,
265
+ sender: job.client,
266
+ });
267
+ this.assertReceipt(receipt, requirement);
268
+ const confirmation = await this.client.confirm(receipt, this.confirmation);
269
+ if (confirmation.txid !== receipt.txid || confirmation.status !== "success") {
270
+ throw new PerkOSError("X402_PAYMENT_FAILED", "The Stacks escrow funding transaction did not confirm successfully.", {
271
+ receiptTxid: receipt.txid,
272
+ confirmationTxid: confirmation.txid,
273
+ status: confirmation.status,
274
+ });
275
+ }
276
+ return {
277
+ x402Version: X402_VERSION,
278
+ payload: {
279
+ transaction: receipt.txid,
280
+ payer: job.client,
281
+ jobId: requirement.jobId.toString(),
282
+ amount: requirement.amount.toString(),
283
+ asset: requirement.asset,
284
+ commerceContract: requirement.commerceContract,
285
+ ...(confirmation.blockHeight !== undefined
286
+ ? { blockHeight: confirmation.blockHeight }
287
+ : {}),
288
+ ...(confirmation.blockHash ? { blockHash: confirmation.blockHash } : {}),
289
+ },
290
+ };
291
+ }
292
+ assertReceipt(receipt, requirement) {
293
+ const valid = receipt.operation === "fund-job" &&
294
+ receipt.network === requirement.network &&
295
+ receipt.contract === requirement.commerceContract &&
296
+ receipt.asset === requirement.asset &&
297
+ receipt.amount === requirement.amount &&
298
+ receipt.jobId === requirement.jobId;
299
+ if (!valid) {
300
+ throw new PerkOSError("X402_PAYMENT_FAILED", "The SDK funding receipt does not match the accepted x402 requirement.", { receipt, requirement });
301
+ }
302
+ normalizeTxid(receipt.txid);
303
+ }
304
+ }
305
+ export { decodePaymentRequiredHeader, decodePaymentResponseHeader, decodePaymentSignatureHeader, encodePaymentRequiredHeader, encodePaymentResponseHeader, encodePaymentSignatureHeader, };
306
+ //# sourceMappingURL=x402.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402.js","sourceRoot":"","sources":["../src/x402.ts"],"names":[],"mappings":"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"}
@@ -97,6 +97,29 @@ post-conditions:
97
97
  This difference stays inside the builder so frameworks do not duplicate asset-specific Clarity
98
98
  logic.
99
99
 
100
+ ## x402 v2 client adapter
101
+
102
+ The x402 adapter uses the official v2 schemas and HTTP header codecs. It maps mainnet and testnet
103
+ to their Stacks CAIP-2 identifiers and binds every payment requirement to the configured commerce
104
+ contract, settlement asset, job ID, and exact atomic budget. `PerkOSX402SchemeClient` then reuses
105
+ the normal read path, spending policy, signer, exact post-conditions, and confirmation tracker to
106
+ produce a confirmed escrow-funding proof.
107
+
108
+ `PerkOSX402Facilitator` closes the server-side observation boundary. It uses current Hiro v3
109
+ transaction and event responses plus the Stacks chain tip, decodes the commerce contract's
110
+ `job-funded` Clarity print event, matches the exact asset transfer, and atomically consumes the
111
+ network-prefixed transaction ID through an injected replay store. The facilitator broadcasts no
112
+ second transaction because the declared x402 payment flow is upfront.
113
+
114
+ The included in-memory replay store is process-local and not production durability. A deployed
115
+ resource server must inject shared atomic storage. The existing custom application headers are
116
+ outside the SDK and are not implicitly treated as x402 v2.
117
+
118
+ The confirmed funding transaction is public before its proof reaches the resource server. Replay
119
+ consumption and a short freshness window do not cryptographically bind that bearer proof to one
120
+ HTTP request, so a later request-bound signature/challenge or facilitator-submitted transaction is
121
+ required before a high-value production paywall migration.
122
+
100
123
  ## Settlement safety
101
124
 
102
125
  Completion, rejection, and expiry may transfer funds held by the escrow contract rather than by
@@ -106,6 +129,7 @@ exact amount expected to leave it.
106
129
 
107
130
  ## Future adapters
108
131
 
109
- - x402 v2 resource-server and client adapters.
132
+ - Durable replay-store and hosted HTTP adapters for the x402 Stacks facilitator.
133
+ - Request-bound payer authorization for front-running resistance.
110
134
  - MCP tools with typed inputs, allowlists, and the same spending policy.
111
135
  - Optional framework-specific integrations and higher-confirmation settlement policies.
@@ -0,0 +1,143 @@
1
+ # Paying Nayori x402 resources
2
+
3
+ Nayori's payer flow prepares a standard, non-sponsored Stacks transaction for direct STX, sBTC,
4
+ or USDCx payment. It binds the payment to the exact HTTP request and returns a body suitable for the
5
+ hosted facilitator. The SDK does not broadcast the transaction.
6
+
7
+ The public Nayori Platform deployment is currently quote-only. Payment verification, settlement,
8
+ reconciliation, and delivery remain runtime-disabled until the testnet release gates and external
9
+ review are complete. The APIs below are developer foundations, not a claim that production
10
+ settlement is live.
11
+
12
+ ## Safe offline quickstart
13
+
14
+ The included quickstart creates a testnet USDCx quote, deterministic payment intent, policy
15
+ reservation, and canonical unsigned transaction. It contains no private key, requests no wallet
16
+ approval, performs no network call, and releases the reservation without signing:
17
+
18
+ ```bash
19
+ npm run quickstart:x402:payer
20
+ ```
21
+
22
+ ## Shared payment policy
23
+
24
+ Both interactive and automated signers use the same mandatory, fail-closed policy:
25
+
26
+ ```ts
27
+ import { NayoriX402PaymentPolicy } from "@perkos/agent-sdk";
28
+
29
+ const policy = new NayoriX402PaymentPolicy({
30
+ allowedNetworks: ["mainnet"],
31
+ allowedAssets: ["sbtc", "usdcx"],
32
+ allowedRecipients: [merchantStacksAddress],
33
+ allowedOrigins: ["https://merchant.example"],
34
+ allowedMerchantIds: ["merchant-research"],
35
+ maxPerTransaction: { sbtc: 25_000n, usdcx: 5_000_000n },
36
+ maxPerSession: { sbtc: 100_000n, usdcx: 20_000_000n },
37
+ maxFeePerTransaction: 5_000n,
38
+ maxFeePerSession: 25_000n,
39
+ minQuoteValiditySeconds: 30,
40
+ });
41
+ ```
42
+
43
+ All values are atomic units: micro-STX, satoshis, or 10^-6 USDCx. Fee limits are micro-STX.
44
+ Authorization reserves amount and fee before asynchronous signing. A valid signature commits that
45
+ usage even if settlement later becomes ambiguous. Failed or cancelled signing releases it. Active
46
+ reservations count toward session limits, so concurrent agents cannot oversubscribe the budget.
47
+
48
+ ## Interactive Leather signing
49
+
50
+ Connect the wallet with the official `@stacks/connect` package and select its STX address and
51
+ compressed public key. Pass the package's `request` function to `LeatherSigner`:
52
+
53
+ ```ts
54
+ import { connect, request } from "@stacks/connect";
55
+ import {
56
+ LeatherSigner,
57
+ NayoriX402PaymentClient,
58
+ } from "@perkos/agent-sdk";
59
+
60
+ const connection = await connect();
61
+ const account = connection.addresses.find(
62
+ (candidate) => candidate.symbol === "STX" || candidate.address.startsWith("S")
63
+ );
64
+ if (!account) throw new Error("The wallet did not return a Stacks account");
65
+
66
+ const signer = new LeatherSigner({
67
+ network: "mainnet",
68
+ address: account.address,
69
+ publicKey: account.publicKey,
70
+ request,
71
+ });
72
+ const payer = new NayoriX402PaymentClient({ signer, policy });
73
+
74
+ const prepared = await payer.preparePayment({
75
+ signedQuote: quoteResponse.signedQuote,
76
+ quote: quoteResponse.quote,
77
+ paymentRequirements: quoteResponse.paymentRequirements,
78
+ request: protectedRequest,
79
+ fee: quotedFeeMicroStx,
80
+ nonce: currentAccountNonce,
81
+ });
82
+ ```
83
+
84
+ `LeatherSigner` calls only `stx_signTransaction` with `broadcast: false`. It rejects a wallet result
85
+ that contains only a txid because the Nayori facilitator must receive, reserve, and broadcast the
86
+ signed bytes exactly once.
87
+
88
+ ## Automated agent signing
89
+
90
+ `PolicySigner` delegates the cryptographic operation to an application-owned service. The callback
91
+ receives the immutable intent and unsigned transaction, never a key:
92
+
93
+ ```ts
94
+ import {
95
+ NayoriX402PaymentClient,
96
+ PolicySigner,
97
+ } from "@perkos/agent-sdk";
98
+
99
+ const signer = new PolicySigner({
100
+ network: "mainnet",
101
+ address: agentStacksAddress,
102
+ publicKey: agentCompressedPublicKey,
103
+ sign: async ({ intent, transaction }) => {
104
+ const response = await fetch("https://signer.internal/v1/stacks/sign", {
105
+ method: "POST",
106
+ headers: { "content-type": "application/json" },
107
+ body: JSON.stringify({ intent, transaction }),
108
+ });
109
+ if (!response.ok) throw new Error("The custody policy denied signing");
110
+ return response.json() as Promise<{ transaction: string }>;
111
+ },
112
+ });
113
+ const payer = new NayoriX402PaymentClient({ signer, policy });
114
+ ```
115
+
116
+ Keep the signing service on a private, mutually authenticated boundary. It must independently
117
+ validate the intent, enforce its own durable limits and nonce policy, and call a KMS/HSM or isolated
118
+ wallet. Do not send a private key to the SDK callback or load one into an LLM/agent process. The
119
+ in-process SDK policy is defense in depth; the custody service is the final authorization boundary.
120
+
121
+ ## Submit to the facilitator
122
+
123
+ After local verification, `prepared.settlementRequest` is exactly the JSON body expected by
124
+ `POST /v1/x402/settle`:
125
+
126
+ ```ts
127
+ const response = await fetch(`${facilitatorOrigin}/v1/x402/settle`, {
128
+ method: "POST",
129
+ headers: {
130
+ authorization: `Bearer ${merchantCredential}`,
131
+ "content-type": "application/json",
132
+ },
133
+ body: JSON.stringify(prepared.settlementRequest),
134
+ });
135
+ ```
136
+
137
+ The merchant credential belongs to the protected resource or its trusted backend, not to the payer
138
+ agent. In the normal x402 exchange, the payer returns its payment payload to the resource server and
139
+ that server calls or proxies the authenticated facilitator operation.
140
+
141
+ Before releasing a resource, require confirmed settlement and a valid signed settlement receipt.
142
+ Do not treat wallet approval, a local txid, a broadcast response, or an unconfirmed mempool entry as
143
+ completed payment.
@@ -0,0 +1,68 @@
1
+ # Nayori direct x402 Stacks profile
2
+
3
+ Date: 2026-08-25
4
+ Status: approved for implementation
5
+
6
+ ## Boundary
7
+
8
+ This is an additive Milestone 2 SDK capability. It does not change the approved M1 contracts,
9
+ broadcast transactions, host a facilitator, persist replay state, sponsor fees, or replace the
10
+ existing `perkos-escrow-v1` job-funding mechanism. The direct mechanism is for an immediate paid
11
+ resource; the existing mechanism remains for jobs with escrow, delivery, evaluation, payout, and
12
+ reputation.
13
+
14
+ ## Decision
15
+
16
+ Add a versioned `stacks-signed-tx-v1` mechanism for direct STX, sBTC, and USDCx payments using the
17
+ official x402 v2 `exact` scheme and explicit `upfront` flow. The client signs the real Stacks
18
+ transaction, and a later hosted facilitator validates and broadcasts it before the resource runs.
19
+
20
+ The approved compatibility-first wire profile emits:
21
+
22
+ - `STX` for native STX;
23
+ - the canonical `address.contract` principal for sBTC and USDCx;
24
+ - a full internal CAIP-19 identifier in `extra.nayoriAssetId` for every asset;
25
+ - `extra.assetTransferMethod: "stacks-signed-tx-v1"`;
26
+ - `extra.paymentFlow: "upfront"`.
27
+
28
+ Unknown networks, assets, contracts, or token names fail closed. There is no fallback to STX.
29
+
30
+ ## Request binding
31
+
32
+ A normalized trusted quote covers quote and merchant IDs, HTTP method, canonical absolute URL,
33
+ SHA-256 body digest, network, canonical asset, exact atomic amount, recipient, issue time, and
34
+ expiry. The canonical representation has fixed keys and version 1. Its SHA-256 digest is truncated
35
+ to 20 bytes and encoded as `ny1_<base64url>`: 31 ASCII characters that fit both the 34-byte native
36
+ STX memo and SIP-010 optional memo.
37
+
38
+ The pure verifier receives the trusted quote and actual request, recomputes the fingerprint, and
39
+ requires the signed transaction memo to match. The future hosted layer must authenticate the
40
+ merchant and verify the quote signature before treating the quote as trusted.
41
+
42
+ ## Pure verifier
43
+
44
+ The verifier has no network, database, replay, or broadcast side effects. It:
45
+
46
+ 1. validates the official x402 payload and requirement;
47
+ 2. requires payload `accepted` to equal the server requirement;
48
+ 3. matches requirement, trusted quote, and actual request;
49
+ 4. deserializes one canonical transaction with bounded size and no trailing bytes;
50
+ 5. verifies chain ID, transaction version, authorization type, and origin signature;
51
+ 6. derives the payer from the origin spending condition;
52
+ 7. permits only an exact STX token transfer or canonical SIP-010 `transfer` call;
53
+ 8. checks amount, sender, recipient, memo, contract, function, arguments, and asset;
54
+ 9. requires `PostConditionMode.Deny`; SIP-010 requires exactly one equal FT post-condition from
55
+ the payer for the canonical token and amount;
56
+ 10. returns a typed verified plan for a later settlement layer.
57
+
58
+ Standard and origin-signed sponsored transactions are accepted. Sponsor signing, fee policy,
59
+ nonce queues, balance checks, simulation, replay, idempotency, broadcast, confirmation, and
60
+ delivery remain required hosted-service controls.
61
+
62
+ ## Testing
63
+
64
+ Deterministic signed fixtures cover STX, sBTC, USDCx, mainnet/testnet registry values, canonical
65
+ fingerprints, and sponsored origin signatures. Negative tests mutate the request, quote,
66
+ requirement, network, signature, transaction template, recipient, amount, memo, contract,
67
+ function arguments, post-condition mode, post-condition asset, and serialized bytes. No test calls
68
+ a live RPC or broadcasts a transaction.