@agent-score/commerce 1.0.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/LICENSE +21 -0
- package/README.md +306 -0
- package/dist/_response-DmziuJz6.d.mts +137 -0
- package/dist/_response-rbK0zM7y.d.ts +137 -0
- package/dist/api/index.d.mts +1 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +37 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/index.mjs +14 -0
- package/dist/api/index.mjs.map +1 -0
- package/dist/challenge/index.d.mts +523 -0
- package/dist/challenge/index.d.ts +523 -0
- package/dist/challenge/index.js +354 -0
- package/dist/challenge/index.js.map +1 -0
- package/dist/challenge/index.mjs +318 -0
- package/dist/challenge/index.mjs.map +1 -0
- package/dist/core.d.mts +252 -0
- package/dist/core.d.ts +252 -0
- package/dist/core.js +500 -0
- package/dist/core.js.map +1 -0
- package/dist/core.mjs +472 -0
- package/dist/core.mjs.map +1 -0
- package/dist/discovery/index.d.mts +382 -0
- package/dist/discovery/index.d.ts +382 -0
- package/dist/discovery/index.js +675 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/index.mjs +630 -0
- package/dist/discovery/index.mjs.map +1 -0
- package/dist/identity/express.d.mts +44 -0
- package/dist/identity/express.d.ts +44 -0
- package/dist/identity/express.js +777 -0
- package/dist/identity/express.js.map +1 -0
- package/dist/identity/express.mjs +738 -0
- package/dist/identity/express.mjs.map +1 -0
- package/dist/identity/fastify.d.mts +63 -0
- package/dist/identity/fastify.d.ts +63 -0
- package/dist/identity/fastify.js +780 -0
- package/dist/identity/fastify.js.map +1 -0
- package/dist/identity/fastify.mjs +741 -0
- package/dist/identity/fastify.mjs.map +1 -0
- package/dist/identity/hono.d.mts +83 -0
- package/dist/identity/hono.d.ts +83 -0
- package/dist/identity/hono.js +779 -0
- package/dist/identity/hono.js.map +1 -0
- package/dist/identity/hono.mjs +740 -0
- package/dist/identity/hono.mjs.map +1 -0
- package/dist/identity/nextjs.d.mts +62 -0
- package/dist/identity/nextjs.d.ts +62 -0
- package/dist/identity/nextjs.js +784 -0
- package/dist/identity/nextjs.js.map +1 -0
- package/dist/identity/nextjs.mjs +747 -0
- package/dist/identity/nextjs.mjs.map +1 -0
- package/dist/identity/policy.d.mts +115 -0
- package/dist/identity/policy.d.ts +115 -0
- package/dist/identity/policy.js +81 -0
- package/dist/identity/policy.js.map +1 -0
- package/dist/identity/policy.mjs +53 -0
- package/dist/identity/policy.mjs.map +1 -0
- package/dist/identity/web.d.mts +82 -0
- package/dist/identity/web.d.ts +82 -0
- package/dist/identity/web.js +775 -0
- package/dist/identity/web.js.map +1 -0
- package/dist/identity/web.mjs +738 -0
- package/dist/identity/web.mjs.map +1 -0
- package/dist/index.d.mts +252 -0
- package/dist/index.d.ts +252 -0
- package/dist/index.js +432 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +388 -0
- package/dist/index.mjs.map +1 -0
- package/dist/payment/index.d.mts +716 -0
- package/dist/payment/index.d.ts +716 -0
- package/dist/payment/index.js +691 -0
- package/dist/payment/index.js.map +1 -0
- package/dist/payment/index.mjs +639 -0
- package/dist/payment/index.mjs.map +1 -0
- package/dist/signer-Cvdwn6Cs.d.mts +48 -0
- package/dist/signer-Cvdwn6Cs.d.ts +48 -0
- package/dist/stripe-multichain/index.d.mts +221 -0
- package/dist/stripe-multichain/index.d.ts +221 -0
- package/dist/stripe-multichain/index.js +243 -0
- package/dist/stripe-multichain/index.js.map +1 -0
- package/dist/stripe-multichain/index.mjs +199 -0
- package/dist/stripe-multichain/index.mjs.map +1 -0
- package/dist/wwwauthenticate-CU1eNvMQ.d.mts +37 -0
- package/dist/wwwauthenticate-CU1eNvMQ.d.ts +37 -0
- package/package.json +172 -0
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
import { AgentMemoryHint } from '../core.mjs';
|
|
2
|
+
export { buildAgentMemoryHint } from '../core.mjs';
|
|
3
|
+
import { P as PaymentRequiredHeaderInput } from '../wwwauthenticate-CU1eNvMQ.mjs';
|
|
4
|
+
|
|
5
|
+
interface TempoMethodEntry {
|
|
6
|
+
method: 'tempo/charge';
|
|
7
|
+
network: string;
|
|
8
|
+
chain_id: number;
|
|
9
|
+
token: string;
|
|
10
|
+
symbol: string;
|
|
11
|
+
decimals: number;
|
|
12
|
+
pay_to: string;
|
|
13
|
+
}
|
|
14
|
+
interface X402MethodEntry {
|
|
15
|
+
method: 'x402/exact';
|
|
16
|
+
network: string;
|
|
17
|
+
chain_id?: number;
|
|
18
|
+
token: string;
|
|
19
|
+
symbol: string;
|
|
20
|
+
decimals: number;
|
|
21
|
+
pay_to: string;
|
|
22
|
+
}
|
|
23
|
+
interface StripeMethodEntry {
|
|
24
|
+
method: 'stripe/charge';
|
|
25
|
+
rails: ('card' | 'link' | 'shared_payment_token')[];
|
|
26
|
+
profile_id: string | null;
|
|
27
|
+
}
|
|
28
|
+
type AcceptedMethodEntry = TempoMethodEntry | X402MethodEntry | StripeMethodEntry;
|
|
29
|
+
interface BuildAcceptedMethodsInput {
|
|
30
|
+
tempo?: {
|
|
31
|
+
recipient: string;
|
|
32
|
+
network?: string;
|
|
33
|
+
chainId?: number;
|
|
34
|
+
token?: string;
|
|
35
|
+
symbol?: string;
|
|
36
|
+
decimals?: number;
|
|
37
|
+
};
|
|
38
|
+
x402_base?: {
|
|
39
|
+
recipient: string;
|
|
40
|
+
network?: string;
|
|
41
|
+
chainId?: number;
|
|
42
|
+
token?: string;
|
|
43
|
+
symbol?: string;
|
|
44
|
+
decimals?: number;
|
|
45
|
+
};
|
|
46
|
+
x402_solana?: {
|
|
47
|
+
recipient: string;
|
|
48
|
+
network?: string;
|
|
49
|
+
token?: string;
|
|
50
|
+
symbol?: string;
|
|
51
|
+
decimals?: number;
|
|
52
|
+
};
|
|
53
|
+
stripe?: {
|
|
54
|
+
profileId?: string | null;
|
|
55
|
+
rails?: ('card' | 'link' | 'shared_payment_token')[];
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Build the `accepted_methods[]` array for an enriched 402 body. Each rail entry is
|
|
60
|
+
* conditionally included based on whether the vendor passed it. Per-rail shapes follow
|
|
61
|
+
* the conventions established in martin-estate's reference 402.
|
|
62
|
+
*/
|
|
63
|
+
declare function buildAcceptedMethods(input: BuildAcceptedMethodsInput): AcceptedMethodEntry[];
|
|
64
|
+
|
|
65
|
+
type IdentityMode = 'wallet' | 'operator_token';
|
|
66
|
+
interface SignerMatchResultLike {
|
|
67
|
+
kind: 'pass' | 'wallet_signer_mismatch' | 'wallet_auth_requires_wallet_signing' | string;
|
|
68
|
+
expectedSigner?: string;
|
|
69
|
+
actualSigner?: string;
|
|
70
|
+
linkedWallets?: string[];
|
|
71
|
+
}
|
|
72
|
+
interface IdentityMetadataInput {
|
|
73
|
+
/** Current request's identity mode. */
|
|
74
|
+
mode: IdentityMode;
|
|
75
|
+
/** Claimed wallet address (when mode === 'wallet'). */
|
|
76
|
+
wallet?: string;
|
|
77
|
+
/** Result of a prior verifyWalletSignerMatch call. */
|
|
78
|
+
signerMatchResult?: SignerMatchResultLike;
|
|
79
|
+
/** Same-operator linked wallets (from assess response). */
|
|
80
|
+
linkedWallets?: string[];
|
|
81
|
+
/** Optional explicit constraint description (overrides the auto-generated one). */
|
|
82
|
+
signerConstraint?: string;
|
|
83
|
+
}
|
|
84
|
+
interface IdentityMetadataBlock {
|
|
85
|
+
identity_mode: IdentityMode;
|
|
86
|
+
required_signer?: string;
|
|
87
|
+
linked_wallets?: string[];
|
|
88
|
+
signer_constraint?: string;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Build the identity-metadata block for an enriched 402 body. Echoes the agent's
|
|
92
|
+
* identity context (wallet vs. operator-token mode) so the agent can self-correct
|
|
93
|
+
* before signing — specifically, on wallet-auth rails the agent MUST sign with one
|
|
94
|
+
* of the wallets in linked_wallets (all resolve to the same operator).
|
|
95
|
+
*/
|
|
96
|
+
declare function buildIdentityMetadata(input: IdentityMetadataInput): IdentityMetadataBlock;
|
|
97
|
+
|
|
98
|
+
interface HowToPayRailEntry {
|
|
99
|
+
setup?: string[];
|
|
100
|
+
prerequisite?: string;
|
|
101
|
+
command: string;
|
|
102
|
+
alternative_command?: string;
|
|
103
|
+
what_it_does: string;
|
|
104
|
+
}
|
|
105
|
+
interface HowToPayStripeEntry {
|
|
106
|
+
prerequisite: string;
|
|
107
|
+
instructions: string;
|
|
108
|
+
setup_link_cli?: string[];
|
|
109
|
+
command_link_cli?: string[];
|
|
110
|
+
what_it_does_link_cli?: string;
|
|
111
|
+
note?: string;
|
|
112
|
+
}
|
|
113
|
+
interface HowToPayBlock {
|
|
114
|
+
tempo?: HowToPayRailEntry;
|
|
115
|
+
x402_base?: HowToPayRailEntry;
|
|
116
|
+
x402_solana?: HowToPayRailEntry;
|
|
117
|
+
stripe?: HowToPayStripeEntry;
|
|
118
|
+
}
|
|
119
|
+
interface BuildHowToPayInput {
|
|
120
|
+
/** The merchant's full URL (e.g., 'https://agents.merchant.example/api/buy'). */
|
|
121
|
+
url: string;
|
|
122
|
+
/** JSON string of the body the agent should retry with — typically the original request body. */
|
|
123
|
+
retryBodyJson: string;
|
|
124
|
+
/** Total amount in USD (string or number). Used to compute max-spend defaults and stripe context. */
|
|
125
|
+
totalUsd: string | number;
|
|
126
|
+
/** Per-rail config — each is optional. Pass only the rails you support. */
|
|
127
|
+
rails: {
|
|
128
|
+
tempo?: {
|
|
129
|
+
recipient: string;
|
|
130
|
+
networkName?: string;
|
|
131
|
+
chainId?: number;
|
|
132
|
+
recommend?: 'tempo' | 'agentscore-pay' | 'both';
|
|
133
|
+
};
|
|
134
|
+
x402_base?: {
|
|
135
|
+
recipient: string;
|
|
136
|
+
network?: string;
|
|
137
|
+
};
|
|
138
|
+
x402_solana?: {
|
|
139
|
+
recipient: string;
|
|
140
|
+
network?: string;
|
|
141
|
+
};
|
|
142
|
+
stripe?: {
|
|
143
|
+
profileId?: string | null;
|
|
144
|
+
productName?: string;
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
/** Placeholder text for the operator token in commands. Defaults to '<your_opc_token>'. */
|
|
148
|
+
opTokenPlaceholder?: string;
|
|
149
|
+
/** Override max-spend value used in commands. Default: ceil(totalUsd) + 1. */
|
|
150
|
+
maxSpend?: string | number;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Build the agent_instructions.how_to_pay block. Generates per-rail setup/command/what_it_does
|
|
154
|
+
* boilerplate so agents see concrete commands per rail in the 402 body. Vendors pass the rails
|
|
155
|
+
* they support; the helper produces the right command for each.
|
|
156
|
+
*
|
|
157
|
+
* Tool recommendations (tempo CLI vs agentscore-pay vs link-cli) are configurable per rail.
|
|
158
|
+
*/
|
|
159
|
+
declare function buildHowToPay(input: BuildHowToPayInput): HowToPayBlock;
|
|
160
|
+
|
|
161
|
+
/** Map of rail key (e.g. 'x402_base', 'tempo_mpp', 'stripe') → list of client identifiers
|
|
162
|
+
* that have been smoke-verified by the merchant against the protocol shape they emit.
|
|
163
|
+
* Strings are display labels, not install commands — agents already get install commands
|
|
164
|
+
* via `how_to_pay.<rail>.setup`. Use these as a "what's known to work" hint. */
|
|
165
|
+
type CompatibleClients = Record<string, string[]>;
|
|
166
|
+
interface BuildAgentInstructionsInput {
|
|
167
|
+
/** Per-rail commands. Build with `buildHowToPay`. */
|
|
168
|
+
howToPay: HowToPayBlock;
|
|
169
|
+
/** Tool recommendations as human-readable strings. Defaults to a sensible set covering tempo + agentscore-pay. */
|
|
170
|
+
recommendedTools?: string[];
|
|
171
|
+
/** Wallet-stack compatibility note for the agent. Default: rail-neutral, no specific wallet stack required. */
|
|
172
|
+
walletCompatibility?: string;
|
|
173
|
+
/** How long the merchant will wait for payment after the 402. Default 300 (5 minutes). */
|
|
174
|
+
timeoutSeconds?: number;
|
|
175
|
+
/** Warnings about common footguns. Defaults include tempo wallet transfer + raw on-chain x402 deposits. */
|
|
176
|
+
warnings?: string[];
|
|
177
|
+
/** Recommended rail (e.g., 'tempo', 'x402_base'). Surfaced for agents to default to. */
|
|
178
|
+
recommended?: string;
|
|
179
|
+
/** Per-rail list of client names the merchant has verified work end-to-end. Vendors set
|
|
180
|
+
* this from their own smoke matrix — defaults to none (avoids vouching for clients the
|
|
181
|
+
* merchant has not tested). When omitted, the field is not emitted. */
|
|
182
|
+
compatibleClients?: CompatibleClients;
|
|
183
|
+
/** Arbitrary additional fields the vendor wants merged into the agent_instructions object. */
|
|
184
|
+
extra?: Record<string, unknown>;
|
|
185
|
+
}
|
|
186
|
+
interface AgentInstructions {
|
|
187
|
+
how_to_pay: HowToPayBlock;
|
|
188
|
+
recommended_tools: string[];
|
|
189
|
+
wallet_compatibility: string;
|
|
190
|
+
timeout_seconds: number;
|
|
191
|
+
warnings: string[];
|
|
192
|
+
recommended?: string;
|
|
193
|
+
compatible_clients?: CompatibleClients;
|
|
194
|
+
[key: string]: unknown;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Build the agent_instructions object for the 402 body. Combines how_to_pay with
|
|
198
|
+
* recommended tools, warnings, wallet-compatibility note, and timeout.
|
|
199
|
+
*
|
|
200
|
+
* Defaults adapt to the rails declared in `howToPay`: only tempo-relevant warnings/tools
|
|
201
|
+
* appear if `howToPay.tempo` is set, only x402-relevant ones if `x402_base`/`x402_solana`
|
|
202
|
+
* are set. Stripe-only merchants get neither rail-specific warning. Vendors override
|
|
203
|
+
* `warnings`/`recommendedTools` for full control.
|
|
204
|
+
*/
|
|
205
|
+
declare function buildAgentInstructions(input: BuildAgentInstructionsInput): AgentInstructions;
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Helpers for emitting the cross-merchant `agent_memory` hint on merchant 402 responses.
|
|
209
|
+
*
|
|
210
|
+
* The gate (`@agent-score/commerce/identity/*`) emits `agent_memory` on identity-related
|
|
211
|
+
* responses (sessions, credentials, missing_identity bootstraps). Merchants can ALSO
|
|
212
|
+
* include the hint in their own 402 challenge bodies on first-encounter requests so
|
|
213
|
+
* agents persist the cross-merchant pattern even when entering the ecosystem through a
|
|
214
|
+
* merchant-side endpoint rather than a direct AgentScore API call.
|
|
215
|
+
*
|
|
216
|
+
* Usage pattern:
|
|
217
|
+
* - Merchant tracks per-operator (or per-IP / per-fingerprint) "have I seen this agent
|
|
218
|
+
* before?" in their own DB
|
|
219
|
+
* - On first encounter (no prior request from this operator/wallet/IP), include the hint
|
|
220
|
+
* so the agent saves the pattern
|
|
221
|
+
* - On subsequent encounters, skip — the agent already has it (or never will)
|
|
222
|
+
*
|
|
223
|
+
* The hint contents come from `buildAgentMemoryHint` (re-exported here for convenience).
|
|
224
|
+
* Keep it stateless: AgentScore's pattern doesn't depend on the merchant's identity, so
|
|
225
|
+
* every merchant emits the same shape.
|
|
226
|
+
*/
|
|
227
|
+
|
|
228
|
+
interface FirstEncounterAgentMemoryInput {
|
|
229
|
+
/**
|
|
230
|
+
* Whether this is a first encounter for this operator/wallet/IP at this merchant.
|
|
231
|
+
* Merchant-determined (DB lookup, cache flag, etc.). Pass `false` to suppress emission
|
|
232
|
+
* cleanly without wrapping the call in an `if`.
|
|
233
|
+
*/
|
|
234
|
+
firstEncounter: boolean;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Returns the `agent_memory` hint when this is a first encounter, otherwise `undefined`.
|
|
238
|
+
* Use directly with the `agentMemory` field of `build402Body`:
|
|
239
|
+
*
|
|
240
|
+
* ```ts
|
|
241
|
+
* const body = build402Body({
|
|
242
|
+
* acceptedMethods,
|
|
243
|
+
* agentInstructions,
|
|
244
|
+
* pricing,
|
|
245
|
+
* agentMemory: firstEncounterAgentMemory({ firstEncounter: !this.hasSeenOperator(opToken) }),
|
|
246
|
+
* });
|
|
247
|
+
* ```
|
|
248
|
+
*
|
|
249
|
+
* Returning `undefined` means `build402Body` cleanly skips the field instead of emitting
|
|
250
|
+
* `agent_memory: null` (which would imply "I tried but failed" rather than "didn't apply").
|
|
251
|
+
*/
|
|
252
|
+
declare function firstEncounterAgentMemory(input: FirstEncounterAgentMemoryInput): AgentMemoryHint | undefined;
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Pricing block builder + canonical type.
|
|
256
|
+
*
|
|
257
|
+
* Composes the cents-denominated price components into the dollar-string shape that
|
|
258
|
+
* 402 challenge bodies advertise. Lifts the inline pattern from martin-estate's
|
|
259
|
+
* `purchase.ts` so every merchant — current and future commerce-platform plugins
|
|
260
|
+
* (Commerce7, WooCommerce, Shopify) — surfaces the same shape to agents.
|
|
261
|
+
*
|
|
262
|
+
* Shipping is included by default because most physical-goods merchants carry it; pass
|
|
263
|
+
* `shippingCents: 0` (or omit) for digital goods / services. Tax is optional for
|
|
264
|
+
* merchants outside taxable jurisdictions.
|
|
265
|
+
*/
|
|
266
|
+
interface PricingBlock {
|
|
267
|
+
/** Pre-tax, pre-shipping subtotal as a dollar-string (e.g. `"250.00"`). */
|
|
268
|
+
subtotal: string;
|
|
269
|
+
/** Tax amount as a dollar-string. Always present even if `"0.00"`. */
|
|
270
|
+
tax: string;
|
|
271
|
+
/** Shipping cost as a dollar-string. Always present even if `"0.00"`. */
|
|
272
|
+
shipping?: string;
|
|
273
|
+
/** Final total = subtotal + tax + shipping, dollar-string. */
|
|
274
|
+
total: string;
|
|
275
|
+
/** Tax rate as a decimal fraction (e.g. `0.0775` for 7.75%). Optional — omit for tax-free merchants. */
|
|
276
|
+
tax_rate?: number;
|
|
277
|
+
/** ISO-3166-2 state code or jurisdiction name used for tax calc. Optional. */
|
|
278
|
+
tax_state?: string;
|
|
279
|
+
/** ISO-4217 currency code. Default `"USD"`. */
|
|
280
|
+
currency?: string;
|
|
281
|
+
}
|
|
282
|
+
interface BuildPricingBlockInput {
|
|
283
|
+
/** Pre-tax, pre-shipping subtotal in the smallest currency unit (cents, satoshi, etc.). */
|
|
284
|
+
subtotalCents: number;
|
|
285
|
+
/** Tax amount in the smallest currency unit. Default `0`. */
|
|
286
|
+
taxCents?: number;
|
|
287
|
+
/** Shipping cost in the smallest currency unit. Default `0`. */
|
|
288
|
+
shippingCents?: number;
|
|
289
|
+
/** Override the computed total. By default `subtotalCents + taxCents + shippingCents`. */
|
|
290
|
+
totalCents?: number;
|
|
291
|
+
/** Tax rate as a decimal fraction (e.g. `0.0775`). */
|
|
292
|
+
taxRate?: number;
|
|
293
|
+
/** Tax jurisdiction (state code, country, etc.). */
|
|
294
|
+
taxState?: string;
|
|
295
|
+
/** ISO-4217 currency. Default `"USD"`. */
|
|
296
|
+
currency?: string;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Compose a `PricingBlock` from cents-denominated inputs. Handles the cents → dollar-string
|
|
300
|
+
* conversion (always 2 decimals) and computes the total when not explicitly provided.
|
|
301
|
+
*
|
|
302
|
+
* Example:
|
|
303
|
+
* ```ts
|
|
304
|
+
* const pricing = buildPricingBlock({
|
|
305
|
+
* subtotalCents: 25000,
|
|
306
|
+
* taxCents: 1875,
|
|
307
|
+
* shippingCents: 999,
|
|
308
|
+
* taxRate: 0.075,
|
|
309
|
+
* taxState: 'CA',
|
|
310
|
+
* });
|
|
311
|
+
* // → { subtotal: '250.00', tax: '18.75', shipping: '9.99', total: '278.74', tax_rate: 0.075, tax_state: 'CA' }
|
|
312
|
+
* ```
|
|
313
|
+
*
|
|
314
|
+
* Pass `shippingCents: 0` for digital goods if you want the field present (it's then `"0.00"`);
|
|
315
|
+
* omit entirely if you don't want shipping in the response shape at all.
|
|
316
|
+
*/
|
|
317
|
+
declare function buildPricingBlock(input: BuildPricingBlockInput): PricingBlock;
|
|
318
|
+
|
|
319
|
+
interface Build402BodyInput {
|
|
320
|
+
/** From buildAcceptedMethods — list of MPP method entries. */
|
|
321
|
+
acceptedMethods: AcceptedMethodEntry[];
|
|
322
|
+
/** From buildAgentInstructions — wraps how_to_pay + warnings + recommended_tools. */
|
|
323
|
+
agentInstructions?: AgentInstructions;
|
|
324
|
+
/** From buildIdentityMetadata — wallet-mode echoer. Spread into the body when present. */
|
|
325
|
+
identityMetadata?: IdentityMetadataBlock;
|
|
326
|
+
/** Cross-merchant agent_memory hint (from gate). */
|
|
327
|
+
agentMemory?: unknown;
|
|
328
|
+
/** Pricing breakdown. */
|
|
329
|
+
pricing?: PricingBlock;
|
|
330
|
+
/** Total amount in USD as a string (e.g., '250.00'). */
|
|
331
|
+
amountUsd?: string;
|
|
332
|
+
/** Currency code. Default 'USD'. */
|
|
333
|
+
currency?: string;
|
|
334
|
+
/** Order id for retry correlation. */
|
|
335
|
+
orderId?: string | null;
|
|
336
|
+
/** Product info — surfaced on the 402 so agents can confirm what they're buying. */
|
|
337
|
+
product?: {
|
|
338
|
+
id: string;
|
|
339
|
+
name: string;
|
|
340
|
+
};
|
|
341
|
+
/** The body the agent should retry with after payment (e.g., the original request body). */
|
|
342
|
+
retryBody?: unknown;
|
|
343
|
+
/** Recommended rail — agent's default if multiple are listed. */
|
|
344
|
+
recommended?: string;
|
|
345
|
+
/** x402-compliance fields (paired with the PAYMENT-REQUIRED header from `payment/wwwauthenticate`). */
|
|
346
|
+
x402?: {
|
|
347
|
+
accepts: unknown[];
|
|
348
|
+
version?: 1 | 2;
|
|
349
|
+
};
|
|
350
|
+
/** Vendor-specific extra fields merged at the top level. */
|
|
351
|
+
extra?: Record<string, unknown>;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Assemble the full enriched 402 response body. Combines accepted_methods, agent_instructions,
|
|
355
|
+
* identity metadata, pricing, x402 compliance fields, and any vendor-specific extras into a
|
|
356
|
+
* single object suitable for `JSON.stringify`. Vendors pass only what they have; the builder
|
|
357
|
+
* conditionally includes each section.
|
|
358
|
+
*
|
|
359
|
+
* Pair this with a Response that sets:
|
|
360
|
+
* - 'content-type: application/json'
|
|
361
|
+
* - 'www-authenticate: <wwwAuthenticateHeader([...])>' from `payment/wwwauthenticate`
|
|
362
|
+
* - 'PAYMENT-REQUIRED: <paymentRequiredHeader({...})>' for x402 clients
|
|
363
|
+
*/
|
|
364
|
+
declare function build402Body(input: Build402BodyInput): Record<string, unknown>;
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Canonical order-receipt shape returned to agents on the 200 after a successful settlement.
|
|
368
|
+
*
|
|
369
|
+
* Merchants own their order schema, but converging on this shape across every AgentScore-gated
|
|
370
|
+
* merchant (Martin Estate today; Commerce7 / WooCommerce / Shopify plugins tomorrow) means
|
|
371
|
+
* agents can render and post-process orders consistently. Lift this type, fill the fields you
|
|
372
|
+
* care about, and ignore (or extend via `extras`) what you don't.
|
|
373
|
+
*
|
|
374
|
+
* All money fields are dollar-strings (e.g. `"250.00"`). Use `buildPricingBlock` from
|
|
375
|
+
* `@agent-score/commerce/challenge` to compose the pricing fields from cents.
|
|
376
|
+
*/
|
|
377
|
+
|
|
378
|
+
interface OrderReceipt {
|
|
379
|
+
/** Stable order id — UUID, slug, or platform-native (Commerce7 order id, etc.). */
|
|
380
|
+
id: string;
|
|
381
|
+
/** ISO-8601 timestamp of order creation. */
|
|
382
|
+
created_at: string;
|
|
383
|
+
/** Quantity purchased. */
|
|
384
|
+
quantity?: number;
|
|
385
|
+
/** Product info — the agent confirmed they were buying this in the 402, surface again on receipt. */
|
|
386
|
+
product?: {
|
|
387
|
+
id?: string;
|
|
388
|
+
name?: string;
|
|
389
|
+
slug?: string;
|
|
390
|
+
};
|
|
391
|
+
/** Pricing block — same shape as the 402 advertised. Use `buildPricingBlock` to compose. */
|
|
392
|
+
pricing?: PricingBlock;
|
|
393
|
+
/** Buyer email if provided. */
|
|
394
|
+
email?: string;
|
|
395
|
+
/** Payment status — typically `"completed"`, `"pending"`, `"failed"`. */
|
|
396
|
+
payment_status?: string;
|
|
397
|
+
/** Fulfillment status — typically `"pending"`, `"shipped"`, `"delivered"`, `"cancelled"`. */
|
|
398
|
+
fulfillment_status?: string;
|
|
399
|
+
/** Carrier tracking number when fulfillment_status >= shipped. */
|
|
400
|
+
tracking_number?: string | null;
|
|
401
|
+
/** Shipping address — physical-goods merchants. Omit for digital goods. */
|
|
402
|
+
shipping?: {
|
|
403
|
+
name?: string;
|
|
404
|
+
address_1?: string;
|
|
405
|
+
address_2?: string | null;
|
|
406
|
+
city?: string;
|
|
407
|
+
state?: string;
|
|
408
|
+
zip?: string;
|
|
409
|
+
country?: string;
|
|
410
|
+
};
|
|
411
|
+
/** Optional gift note / order memo. */
|
|
412
|
+
gift_note?: string | null;
|
|
413
|
+
/** Vendor-specific extras merged at the top level (loyalty points, warranty, etc.). */
|
|
414
|
+
extras?: Record<string, unknown>;
|
|
415
|
+
/** Next-steps block guiding the agent on what to do post-purchase. */
|
|
416
|
+
next_steps?: {
|
|
417
|
+
user_message?: string;
|
|
418
|
+
order_status_url?: string;
|
|
419
|
+
fulfillment_eta?: string;
|
|
420
|
+
[key: string]: unknown;
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* `respond402` — single-call 402 emit for merchants who use both `mppx` (for tempo + stripe
|
|
426
|
+
* MPP rails) AND x402 (for Base + Solana).
|
|
427
|
+
*
|
|
428
|
+
* The seam is fiddly enough to get wrong by hand:
|
|
429
|
+
* - mppx's `compose()(req)` returns a 402 Response with WWW-Authenticate directives
|
|
430
|
+
* whose ids mppx's server-side validator REMEMBERS — they round-trip in client
|
|
431
|
+
* credentials. Overwriting that header (e.g. with `buildPaymentHeaders` output)
|
|
432
|
+
* breaks the round-trip.
|
|
433
|
+
* - x402 needs the binary-friendly `PAYMENT-REQUIRED` header (base64-encoded JSON
|
|
434
|
+
* of `{x402Version, accepts, resource}`) — mppx doesn't emit it.
|
|
435
|
+
* - Merchants want a richer JSON body (pricing, identity metadata, agent_instructions,
|
|
436
|
+
* agent_memory, retry_body, accepted_methods cross-reference) than the bare mppx body.
|
|
437
|
+
*
|
|
438
|
+
* `respond402` composes all three in one call:
|
|
439
|
+
* - PRESERVES mppx's WWW-Authenticate verbatim
|
|
440
|
+
* - ADDS PAYMENT-REQUIRED when x402 entries are present
|
|
441
|
+
* - REPLACES the body with the rich body via `build402Body`
|
|
442
|
+
*
|
|
443
|
+
* Usage:
|
|
444
|
+
* ```ts
|
|
445
|
+
* const result = await m.compose(['tempo/charge', {...}], ['stripe/charge', {...}])(c.req.raw);
|
|
446
|
+
* if (result.status === 402) {
|
|
447
|
+
* return commerce.respond402({
|
|
448
|
+
* mppxChallenge: result.challenge,
|
|
449
|
+
* x402: { version: 2, accepts: x402Accepts, resource: { url: c.req.url, mimeType: 'application/json' } },
|
|
450
|
+
* body: { acceptedMethods, agentInstructions, identityMetadata, pricing, agentMemory, retryBody, ... },
|
|
451
|
+
* });
|
|
452
|
+
* }
|
|
453
|
+
* ```
|
|
454
|
+
*/
|
|
455
|
+
|
|
456
|
+
interface Respond402Input {
|
|
457
|
+
/** The 402 Response returned by `mppx.compose()(req)`. Its WWW-Authenticate header
|
|
458
|
+
* is preserved verbatim — mppx's server-side validator matches credentials to the
|
|
459
|
+
* directive ids it generated, so overwriting breaks the round-trip. */
|
|
460
|
+
mppxChallenge: Response;
|
|
461
|
+
/** Inputs to `build402Body` — the rich JSON body sent to the agent. */
|
|
462
|
+
body: Build402BodyInput;
|
|
463
|
+
/** When set, layers on the x402 PAYMENT-REQUIRED header (base64-encoded JSON).
|
|
464
|
+
* Omit for merchants that don't accept x402 (Base/Solana) — mppx-only setups. */
|
|
465
|
+
x402?: PaymentRequiredHeaderInput;
|
|
466
|
+
}
|
|
467
|
+
declare function respond402(input: Respond402Input): Response;
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Build a structured 4xx validation-error body that pairs cleanly with the
|
|
471
|
+
* existing 402 / 403 builders. Every commerce merchant returning helpful
|
|
472
|
+
* `bad_request` / `not_found` / `out_of_stock` / etc. errors converges on the
|
|
473
|
+
* same shape: `{ error: {code, message}, ...optional_hints, next_steps? }`.
|
|
474
|
+
*
|
|
475
|
+
* This builder doesn't choose the HTTP status — vendors wrap the returned
|
|
476
|
+
* body in their framework's response (`c.json(body, 400)` in Hono,
|
|
477
|
+
* `Response.json(body, {status: 400})` for the Web Fetch path, etc.). Status
|
|
478
|
+
* stays the merchant's call because the same shape works for 400/404/409/422.
|
|
479
|
+
*/
|
|
480
|
+
interface BuildValidationErrorInput {
|
|
481
|
+
/** Machine-readable error code (e.g. 'bad_request', 'not_found', 'out_of_stock'). */
|
|
482
|
+
code: string;
|
|
483
|
+
/** Human-readable message — surfaced directly to the user via the agent. */
|
|
484
|
+
message: string;
|
|
485
|
+
/** Optional schema description of required body fields, keyed by field name. Surfaced
|
|
486
|
+
* so agents can self-correct without fetching docs. */
|
|
487
|
+
requiredFields?: Record<string, string>;
|
|
488
|
+
/** Optional concrete example body. Pairs with `requiredFields` for max self-serve. */
|
|
489
|
+
exampleBody?: unknown;
|
|
490
|
+
/** Optional next-step hint block (`{action, user_message?, ...vendor_extras}`). */
|
|
491
|
+
nextSteps?: Record<string, unknown>;
|
|
492
|
+
/** Vendor-specific top-level fields merged into the body (e.g. `available`,
|
|
493
|
+
* `blocked_states`, `max_length`). */
|
|
494
|
+
extra?: Record<string, unknown>;
|
|
495
|
+
}
|
|
496
|
+
interface ValidationErrorBody {
|
|
497
|
+
error: {
|
|
498
|
+
code: string;
|
|
499
|
+
message: string;
|
|
500
|
+
};
|
|
501
|
+
required_fields?: Record<string, string>;
|
|
502
|
+
example_body?: unknown;
|
|
503
|
+
next_steps?: Record<string, unknown>;
|
|
504
|
+
[key: string]: unknown;
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Compose a 4xx body that vendors return via their framework's response helper.
|
|
508
|
+
* Combine with the merchant's chosen HTTP status (400 for body shape errors,
|
|
509
|
+
* 404 for missing entities, 409 for stock conflicts, 403 for policy denials, etc.).
|
|
510
|
+
*
|
|
511
|
+
* Example:
|
|
512
|
+
* ```ts
|
|
513
|
+
* return c.json(buildValidationError({
|
|
514
|
+
* code: 'bad_request',
|
|
515
|
+
* message: 'product_id, email, and shipping are required',
|
|
516
|
+
* requiredFields: { product_id: 'uuid', email: 'string', shipping: 'object' },
|
|
517
|
+
* nextSteps: { action: 'retry_with_complete_body' },
|
|
518
|
+
* }), 400);
|
|
519
|
+
* ```
|
|
520
|
+
*/
|
|
521
|
+
declare function buildValidationError(input: BuildValidationErrorInput): ValidationErrorBody;
|
|
522
|
+
|
|
523
|
+
export { type AcceptedMethodEntry, type AgentInstructions, AgentMemoryHint, type Build402BodyInput, type BuildAcceptedMethodsInput, type BuildAgentInstructionsInput, type BuildHowToPayInput, type BuildPricingBlockInput, type BuildValidationErrorInput, type CompatibleClients, type FirstEncounterAgentMemoryInput, type HowToPayBlock, type HowToPayRailEntry, type HowToPayStripeEntry, type IdentityMetadataBlock, type IdentityMetadataInput, type IdentityMode, type OrderReceipt, type PricingBlock, type Respond402Input, type SignerMatchResultLike, type StripeMethodEntry, type TempoMethodEntry, type ValidationErrorBody, type X402MethodEntry, build402Body, buildAcceptedMethods, buildAgentInstructions, buildHowToPay, buildIdentityMetadata, buildPricingBlock, buildValidationError, firstEncounterAgentMemory, respond402 };
|