@bosonprotocol/x402-core 0.1.0-alpha-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.
Files changed (36) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +26 -0
  3. package/dist/cjs/eip712/index.d.ts +142 -0
  4. package/dist/cjs/eip712/index.js +224 -0
  5. package/dist/cjs/eip712/index.js.map +1 -0
  6. package/dist/cjs/eip712/token-auth/index.d.ts +259 -0
  7. package/dist/cjs/eip712/token-auth/index.js +221 -0
  8. package/dist/cjs/eip712/token-auth/index.js.map +1 -0
  9. package/dist/cjs/index.d.ts +15 -0
  10. package/dist/cjs/index.js +8 -0
  11. package/dist/cjs/index.js.map +1 -0
  12. package/dist/cjs/package.json +3 -0
  13. package/dist/cjs/schemes/escrow/index.d.ts +1262 -0
  14. package/dist/cjs/schemes/escrow/index.js +228 -0
  15. package/dist/cjs/schemes/escrow/index.js.map +1 -0
  16. package/dist/cjs/state-machine/index.d.ts +86 -0
  17. package/dist/cjs/state-machine/index.js +146 -0
  18. package/dist/cjs/state-machine/index.js.map +1 -0
  19. package/dist/cjs/states-Q2FJASHh.d.ts +38 -0
  20. package/dist/esm/chunk-7IY3WEFZ.js +10 -0
  21. package/dist/esm/chunk-7IY3WEFZ.js.map +1 -0
  22. package/dist/esm/eip712/index.js +213 -0
  23. package/dist/esm/eip712/index.js.map +1 -0
  24. package/dist/esm/eip712/token-auth/index.js +189 -0
  25. package/dist/esm/eip712/token-auth/index.js.map +1 -0
  26. package/dist/esm/index.js +6 -0
  27. package/dist/esm/index.js.map +1 -0
  28. package/dist/esm/package.json +3 -0
  29. package/dist/esm/schemes/escrow/index.js +202 -0
  30. package/dist/esm/schemes/escrow/index.js.map +1 -0
  31. package/dist/esm/state-machine/index.js +127 -0
  32. package/dist/esm/state-machine/index.js.map +1 -0
  33. package/dist/schemas/next_actions.schema.json +87 -0
  34. package/dist/schemas/payment_payload.schema.json +156 -0
  35. package/dist/schemas/payment_requirements.schema.json +135 -0
  36. package/package.json +84 -0
@@ -0,0 +1,202 @@
1
+ import { ExchangeState, DisputeState } from '../../chunk-7IY3WEFZ.js';
2
+ import { z } from 'zod';
3
+
4
+ // src/schemes/escrow/types.ts
5
+ var TOKEN_AUTH_STRATEGIES = [
6
+ "none",
7
+ "erc3009",
8
+ "permit",
9
+ "permit2"
10
+ ];
11
+ var ACTION_CHANNELS = [
12
+ "server",
13
+ "facilitator",
14
+ "onchain",
15
+ "mcp",
16
+ "xmtp"
17
+ ];
18
+ var HEX = /^0x[a-fA-F0-9]+$/;
19
+ var HEX_BYTES = /^0x[a-fA-F0-9]*$/;
20
+ var HEX32 = /^0x[a-fA-F0-9]{64}$/;
21
+ var ADDRESS = /^0x[a-fA-F0-9]{40}$/;
22
+ var DECIMAL_UINT = /^(0|[1-9][0-9]*)$/;
23
+ var EVM_NETWORK = /^eip155:[1-9][0-9]*$/;
24
+ var addressSchema = z.string().regex(ADDRESS);
25
+ var hexSchema = z.string().regex(HEX);
26
+ var hexBytesSchema = z.string().regex(HEX_BYTES);
27
+ var hex32Schema = z.string().regex(HEX32);
28
+ var decimalUintSchema = z.string().regex(DECIMAL_UINT);
29
+ var evmNetworkSchema = z.string().regex(EVM_NETWORK);
30
+
31
+ // src/schemes/escrow/shared-schemas.ts
32
+ var actionDeadlineSchema = z.string().datetime({ offset: true });
33
+ var actionChannelsSchema = z.array(z.enum(ACTION_CHANNELS)).min(1).refine((channels) => new Set(channels).size === channels.length, {
34
+ message: "channels must contain unique items"
35
+ });
36
+ var actionEntrySchema = z.object({
37
+ id: z.string().min(1),
38
+ channels: actionChannelsSchema,
39
+ endpoints: z.record(z.string()).optional(),
40
+ deadline: actionDeadlineSchema.optional()
41
+ }).strict();
42
+ var metaTxEntrypointsSchema = z.object({
43
+ none: z.string().min(1),
44
+ erc3009: z.string().min(1),
45
+ permit: z.string().min(1),
46
+ permit2: z.string().min(1)
47
+ }).strict();
48
+ var onchainHintsSchema = z.object({
49
+ escrow: addressSchema,
50
+ metaTxFacet: z.string().min(1),
51
+ metaTxEntrypoints: metaTxEntrypointsSchema,
52
+ actionFacets: z.record(z.string())
53
+ }).strict();
54
+ var actionsFallbackSchema = z.object({
55
+ xmtp: z.string().optional(),
56
+ mcp: z.string().optional(),
57
+ onchainHints: onchainHintsSchema.optional()
58
+ }).strict();
59
+
60
+ // src/schemes/escrow/payment-requirements.ts
61
+ var offerRefSchema = z.object({
62
+ fullOffer: z.record(z.unknown()),
63
+ sellerSig: hexSchema,
64
+ creator: addressSchema
65
+ }).strict();
66
+ var tokenAuthStrategySchema = z.enum(
67
+ TOKEN_AUTH_STRATEGIES
68
+ );
69
+ var fulfillmentSchema = z.object({
70
+ required: z.boolean(),
71
+ options: z.array(
72
+ z.object({
73
+ id: z.string().min(1),
74
+ schema: z.union([z.record(z.unknown()), z.null()]),
75
+ metadata: z.unknown().optional()
76
+ }).strict()
77
+ )
78
+ }).strict();
79
+ var actionsSchema = z.object({
80
+ next: z.array(actionEntrySchema).min(1),
81
+ fallback: actionsFallbackSchema.optional()
82
+ }).strict();
83
+ var escrowPaymentRequirementsSchema = z.object({
84
+ scheme: z.literal("escrow"),
85
+ network: evmNetworkSchema,
86
+ asset: addressSchema,
87
+ amount: decimalUintSchema,
88
+ escrowAddress: addressSchema,
89
+ recipientId: z.string().min(1),
90
+ maxTimeoutSeconds: z.number().int().positive(),
91
+ offer: offerRefSchema,
92
+ tokenAuthStrategies: z.array(tokenAuthStrategySchema).min(1).refine((strategies) => new Set(strategies).size === strategies.length, {
93
+ message: "tokenAuthStrategies must not contain duplicates"
94
+ }),
95
+ fulfillment: fulfillmentSchema.optional(),
96
+ actions: actionsSchema
97
+ }).strict();
98
+ function parseEscrowPaymentRequirements(value) {
99
+ return escrowPaymentRequirementsSchema.parse(value);
100
+ }
101
+ var sigSchema = z.object({
102
+ v: z.number().int(),
103
+ r: hex32Schema,
104
+ s: hex32Schema
105
+ }).strict();
106
+ var metaTxSchema = z.object({
107
+ from: addressSchema,
108
+ nonce: decimalUintSchema,
109
+ functionName: z.string().min(1),
110
+ functionSignature: hexBytesSchema,
111
+ sig: sigSchema
112
+ }).strict();
113
+ var erc3009DataSchema = z.object({
114
+ from: addressSchema,
115
+ to: addressSchema,
116
+ value: decimalUintSchema,
117
+ validAfter: z.number().int().nonnegative(),
118
+ validBefore: z.number().int().nonnegative(),
119
+ nonce: hex32Schema,
120
+ v: z.number().int(),
121
+ r: hex32Schema,
122
+ s: hex32Schema
123
+ }).strict();
124
+ var permitDataSchema = z.object({
125
+ owner: addressSchema,
126
+ spender: addressSchema,
127
+ value: decimalUintSchema,
128
+ deadline: z.number().int().nonnegative(),
129
+ nonce: decimalUintSchema,
130
+ v: z.number().int(),
131
+ r: hex32Schema,
132
+ s: hex32Schema
133
+ }).strict();
134
+ var permit2DataSchema = z.object({
135
+ permitted: z.object({
136
+ token: addressSchema,
137
+ amount: decimalUintSchema
138
+ }).strict(),
139
+ spender: addressSchema,
140
+ nonce: decimalUintSchema,
141
+ deadline: z.number().int().nonnegative(),
142
+ signature: hexSchema
143
+ }).strict();
144
+ var tokenAuthSchema = z.discriminatedUnion("kind", [
145
+ z.object({ kind: z.literal("erc3009"), data: erc3009DataSchema }).strict(),
146
+ z.object({ kind: z.literal("permit"), data: permitDataSchema }).strict(),
147
+ z.object({ kind: z.literal("permit2"), data: permit2DataSchema }).strict()
148
+ ]);
149
+ var tokenAuthStrategySchema2 = z.enum(
150
+ TOKEN_AUTH_STRATEGIES
151
+ );
152
+ var escrowPaymentPayloadSchema = z.object({
153
+ x402Version: z.number().int(),
154
+ scheme: z.literal("escrow"),
155
+ network: evmNetworkSchema,
156
+ payload: z.object({
157
+ action: z.string().min(1),
158
+ tokenAuthStrategy: tokenAuthStrategySchema2,
159
+ offerRef: z.object({
160
+ fullOffer: z.record(z.unknown()),
161
+ sellerSig: hexSchema
162
+ }).strict(),
163
+ buyer: addressSchema,
164
+ metaTx: metaTxSchema,
165
+ tokenAuth: tokenAuthSchema.optional()
166
+ }).strict(),
167
+ fulfillment: z.object({
168
+ option: z.string().min(1),
169
+ // `data` is action-conditional (Flow B only). The structural
170
+ // schema accepts both shapes; the server validator enforces
171
+ // presence vs absence based on `payload.action`.
172
+ data: z.union([z.record(z.unknown()), z.null()]).optional()
173
+ }).strict().optional()
174
+ }).strict();
175
+ function parseEscrowPaymentPayload(value) {
176
+ return escrowPaymentPayloadSchema.parse(value);
177
+ }
178
+ var exchangeStateSchema = z.nativeEnum(ExchangeState);
179
+ var disputeStateSchema = z.nativeEnum(DisputeState);
180
+ var escrowNextActionsSchema = z.object({
181
+ exchangeId: z.string().min(1),
182
+ exchangeState: exchangeStateSchema,
183
+ disputeState: disputeStateSchema.optional(),
184
+ next: z.array(actionEntrySchema),
185
+ fallback: actionsFallbackSchema.optional()
186
+ }).strict().refine(
187
+ (envelope) => envelope.exchangeState === ExchangeState.DISPUTED ? envelope.disputeState !== void 0 : envelope.disputeState === void 0,
188
+ {
189
+ message: "disputeState is required iff exchangeState === DISPUTED",
190
+ path: ["disputeState"]
191
+ }
192
+ );
193
+ function parseEscrowNextActions(value) {
194
+ return escrowNextActionsSchema.parse(value);
195
+ }
196
+
197
+ // src/schemes/escrow/index.ts
198
+ var ESCROW_SCHEME = "escrow";
199
+
200
+ export { ACTION_CHANNELS, ADDRESS, DECIMAL_UINT, ESCROW_SCHEME, EVM_NETWORK, HEX, HEX32, HEX_BYTES, TOKEN_AUTH_STRATEGIES, addressSchema, decimalUintSchema, escrowNextActionsSchema, escrowPaymentPayloadSchema, escrowPaymentRequirementsSchema, evmNetworkSchema, hex32Schema, hexBytesSchema, hexSchema, parseEscrowNextActions, parseEscrowPaymentPayload, parseEscrowPaymentRequirements };
201
+ //# sourceMappingURL=index.js.map
202
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/schemes/escrow/types.ts","../../../../src/schemes/escrow/validators.ts","../../../../src/schemes/escrow/shared-schemas.ts","../../../../src/schemes/escrow/payment-requirements.ts","../../../../src/schemes/escrow/payment-payload.ts","../../../../src/schemes/escrow/next-actions.ts","../../../../src/schemes/escrow/index.ts"],"names":["z","tokenAuthStrategySchema"],"mappings":"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","file":"index.js","sourcesContent":["// Shared wire-format types for the `escrow` scheme.\n// Source of truth: docs/boson-impl-01-escrow-scheme.md.\n\n/**\n * CAIP-2 network identifier for an EVM chain. Constrained to `eip155:<chainId>`\n * shape at runtime by the JSON Schema and zod regex; aliased to `string` here\n * for the same reason as `Address` / `Hex` — the wire format is JSON, where\n * everything is a string, and template-literal types cause friction with\n * zod's regex-based validators.\n */\nexport type EvmNetwork = string;\n\n/** BPIP-12 token-authorization strategies. */\nexport type TokenAuthStrategy = \"none\" | \"erc3009\" | \"permit\" | \"permit2\";\nexport const TOKEN_AUTH_STRATEGIES: readonly TokenAuthStrategy[] = [\n \"none\",\n \"erc3009\",\n \"permit\",\n \"permit2\",\n] as const;\n\n/** Boson commit-time action ids advertised by the server. */\nexport type BosonCommitActionId = \"boson-createOfferAndCommit\" | \"boson-createOfferCommitAndRedeem\";\n\n/** Channels through which a `nextAction` can be performed. */\nexport type ActionChannel = \"server\" | \"facilitator\" | \"onchain\" | \"mcp\" | \"xmtp\";\nexport const ACTION_CHANNELS: readonly ActionChannel[] = [\n \"server\",\n \"facilitator\",\n \"onchain\",\n \"mcp\",\n \"xmtp\",\n] as const;\n\n/**\n * BPIP-10 FullOffer. Treated as opaque at this layer — the on-chain shape lives\n * in `@bosonprotocol/core-sdk`, and validation against the protocol struct is\n * the EIP-712 builder's job. Here it's just \"an object echoed verbatim\".\n */\nexport type FullOffer = Record<string, unknown>;\n\n/**\n * 0x-prefixed hex string. Aliased to `string` in the wire format so JSON\n * shapes are easy to construct; runtime validation is handled by the JSON\n * Schema and zod regex. The strongly-typed `\\`0x${string}\\`` form is reserved\n * for the EIP-712 builder layer where viem's brands matter.\n */\nexport type Hex = string;\n/** 0x-prefixed 40-char hex string. See `Hex` for typing rationale. */\nexport type Address = string;\n\n/** Off-chain offer reference signed by the seller. */\nexport interface BosonOfferRef {\n fullOffer: FullOffer;\n sellerSig: Hex;\n creator: Address;\n}\n\nexport interface FulfillmentOption {\n id: string;\n /** JSON-Schema-shaped `type: object` description of the data the buyer must supply, or `null` for schemaless channels. */\n schema: Record<string, unknown> | null;\n /** Channel-specific hints advertised to the client, such as endpoint URLs or public keys. */\n metadata?: unknown;\n}\n\nexport interface FulfillmentRequirements {\n required: boolean;\n options: FulfillmentOption[];\n}\n\nexport interface NextAction {\n id: string;\n channels: ActionChannel[];\n endpoints?: Record<string, string>;\n /**\n * ISO 8601 absolute timestamp by which the action must be invoked.\n * Relevant for dispute-window-bounded actions like\n * `boson-resolveDispute`, `boson-escalateDispute`,\n * `boson-retractDispute`, and (post-commit) `boson-completeExchange`.\n */\n deadline?: string;\n}\n\nexport interface OnchainHints {\n /** Address of the Boson escrow contract. */\n escrow: Address;\n metaTxFacet: string;\n /**\n * Per-`tokenAuthStrategy` meta-tx entry points on `metaTxFacet`. The\n * Boson Diamond exposes two functions on `MetaTransactionsHandlerFacet`:\n *\n * - `executeMetaTransaction` — legacy BPIP-9 entry point. Used when\n * the buyer's `tokenAuthStrategy` is `none` (the buyer has\n * pre-approved the Diamond, so no token-transfer authorization\n * queue is needed). Also the right entry point for any\n * post-commit action that doesn't move tokens (`redeem`,\n * `complete`, dispute transitions).\n * - `executeMetaTransactionWithTokenTransferAuthorization` — BPIP-12\n * entry point. Carries the buyer's signed `MetaTransaction` *and*\n * a queue of token-transfer authorizations. Used when\n * `tokenAuthStrategy` is `erc3009`, `permit`, or `permit2`.\n *\n * Clients select the entry point by their chosen strategy at\n * dispatch time.\n */\n metaTxEntrypoints: Record<TokenAuthStrategy, string>;\n actionFacets: Record<string, string>;\n}\n\nexport interface ActionsFallback {\n xmtp?: string;\n /**\n * Identifier within the Boson MCP server (e.g. the\n * `bosonprotocol/agentic-commerce` server) that the buyer's\n * MCP-aware agent dispatches against. The MCP *server* is escrow-\n * level (one BosonMCP serving every Boson seller); this value is the\n * URI/identifier the BosonMCP routes to the right exchange / seller.\n */\n mcp?: string;\n onchainHints?: OnchainHints;\n}\n\nexport interface ActionsEnvelope {\n next: NextAction[];\n fallback?: ActionsFallback;\n}\n\n/** Boson protocol meta-transaction envelope (signed by the buyer). */\nexport interface BosonMetaTx {\n from: Address;\n /** Decimal string. */\n nonce: string;\n functionName: string;\n /**\n * ABI-encoded function-call data as a `0x`-prefixed hex string. Named\n * `functionSignature` to match the on-chain `MetaTransactionsHandlerFacet`\n * struct field — the value is the encoded calldata, not just the function\n * selector.\n */\n functionSignature: Hex;\n sig: { v: number; r: Hex; s: Hex };\n}\n\nexport interface Erc3009AuthData {\n from: Address;\n to: Address;\n /** Atomic units, decimal string. */\n value: string;\n validAfter: number;\n validBefore: number;\n /** 32-byte hex string. */\n nonce: Hex;\n v: number;\n r: Hex;\n s: Hex;\n}\n\nexport interface PermitAuthData {\n owner: Address;\n spender: Address;\n /** Atomic units, decimal string. */\n value: string;\n deadline: number;\n /** Token-internal sequential nonce, decimal string. */\n nonce: string;\n v: number;\n r: Hex;\n s: Hex;\n}\n\nexport interface Permit2AuthData {\n permitted: { token: Address; amount: string };\n spender: Address;\n /** Permit2 word-bitmap nonce, decimal string. */\n nonce: string;\n deadline: number;\n /** Concatenated 65-byte ECDSA signature. */\n signature: Hex;\n}\n\n/** Discriminated union of all token-authorization payloads. `none` is encoded by the absence of this field on the payload. */\nexport type BosonTokenAuth =\n | { kind: \"erc3009\"; data: Erc3009AuthData }\n | { kind: \"permit\"; data: PermitAuthData }\n | { kind: \"permit2\"; data: Permit2AuthData };\n","// Shared regex patterns + scalar zod schemas used across the `escrow`\n// scheme's payment-requirements and payment-payload validators. Keeping\n// them in one place ensures the JSON Schema's patterns and the zod regexes\n// stay in sync (see `schemas/*.json` for the JSON Schema source of truth).\n\nimport { z } from \"zod\";\n\n/** 0x-prefixed hex string, at least one nibble. */\nexport const HEX = /^0x[a-fA-F0-9]+$/;\n\n/** 0x-prefixed hex string, allowing the empty `0x` form for empty bytes. */\nexport const HEX_BYTES = /^0x[a-fA-F0-9]*$/;\n\n/** 0x-prefixed 32-byte (64-nibble) hex string. */\nexport const HEX32 = /^0x[a-fA-F0-9]{64}$/;\n\n/** 0x-prefixed 20-byte (40-nibble) hex address. */\nexport const ADDRESS = /^0x[a-fA-F0-9]{40}$/;\n\n/** Decimal unsigned integer string, no leading zeros (except \"0\" itself). */\nexport const DECIMAL_UINT = /^(0|[1-9][0-9]*)$/;\n\n/** CAIP-2 EVM network identifier: `eip155:<chainId>`. */\nexport const EVM_NETWORK = /^eip155:[1-9][0-9]*$/;\n\nexport const addressSchema = z.string().regex(ADDRESS);\nexport const hexSchema = z.string().regex(HEX);\nexport const hexBytesSchema = z.string().regex(HEX_BYTES);\nexport const hex32Schema = z.string().regex(HEX32);\nexport const decimalUintSchema = z.string().regex(DECIMAL_UINT);\nexport const evmNetworkSchema = z.string().regex(EVM_NETWORK);\n","// Shared zod fragments used by both `payment-requirements.ts` (the\n// pre-commit / 402 envelope) and `next-actions.ts` (the post-commit\n// envelope). Centralised here so the two wire-format validators can't\n// drift on shared sub-shapes like an action entry, the `fallback` block,\n// or the `onchainHints` block.\n\nimport { z } from \"zod\";\n\nimport { ACTION_CHANNELS, type ActionChannel } from \"./types.js\";\nimport { addressSchema } from \"./validators.js\";\n\n/** ISO 8601 absolute timestamp with timezone offset. */\nexport const actionDeadlineSchema = z.string().datetime({ offset: true });\n\n/** Non-empty unique `ActionChannel[]` for `next[i].channels`. */\nexport const actionChannelsSchema = z\n .array(z.enum(ACTION_CHANNELS as readonly [ActionChannel, ...ActionChannel[]]))\n .min(1)\n .refine((channels) => new Set(channels).size === channels.length, {\n message: \"channels must contain unique items\",\n });\n\n/** Single entry in the `next[]` array of any `nextActions` envelope. */\nexport const actionEntrySchema = z\n .object({\n id: z.string().min(1),\n channels: actionChannelsSchema,\n endpoints: z.record(z.string()).optional(),\n deadline: actionDeadlineSchema.optional(),\n })\n .strict();\n\n/**\n * Per-`tokenAuthStrategy` meta-tx entry points on\n * `onchainHints.metaTxFacet`. All four strategies are required so\n * clients can resolve any strategy they happen to advertise.\n */\nexport const metaTxEntrypointsSchema = z\n .object({\n none: z.string().min(1),\n erc3009: z.string().min(1),\n permit: z.string().min(1),\n permit2: z.string().min(1),\n })\n .strict();\n\n/** `fallback.onchainHints` block. */\nexport const onchainHintsSchema = z\n .object({\n escrow: addressSchema,\n metaTxFacet: z.string().min(1),\n metaTxEntrypoints: metaTxEntrypointsSchema,\n actionFacets: z.record(z.string()),\n })\n .strict();\n\n/** `fallback` block embedded in any `nextActions` envelope. */\nexport const actionsFallbackSchema = z\n .object({\n xmtp: z.string().optional(),\n mcp: z.string().optional(),\n onchainHints: onchainHintsSchema.optional(),\n })\n .strict();\n","// `escrow` scheme PaymentRequirements (server -> client, in 402 body).\n// Source of truth: docs/boson-impl-01-escrow-scheme.md §2.\n\nimport { z } from \"zod\";\n\nimport { actionEntrySchema, actionsFallbackSchema } from \"./shared-schemas.js\";\nimport {\n TOKEN_AUTH_STRATEGIES,\n type ActionsEnvelope,\n type Address,\n type BosonOfferRef,\n type EvmNetwork,\n type FulfillmentRequirements,\n type TokenAuthStrategy,\n} from \"./types.js\";\nimport { addressSchema, decimalUintSchema, evmNetworkSchema, hexSchema } from \"./validators.js\";\n\nconst offerRefSchema = z\n .object({\n fullOffer: z.record(z.unknown()),\n sellerSig: hexSchema,\n creator: addressSchema,\n })\n .strict();\n\nconst tokenAuthStrategySchema = z.enum(\n TOKEN_AUTH_STRATEGIES as readonly [TokenAuthStrategy, ...TokenAuthStrategy[]],\n);\n\nconst fulfillmentSchema = z\n .object({\n required: z.boolean(),\n options: z.array(\n z\n .object({\n id: z.string().min(1),\n schema: z.union([z.record(z.unknown()), z.null()]),\n metadata: z.unknown().optional(),\n })\n .strict(),\n ),\n })\n .strict();\n\n// Pre-commit (initial 402) `actions` envelope: `next[]` must be\n// non-empty (the buyer needs at least one path to commit) and the\n// `fallback` block is optional.\nconst actionsSchema = z\n .object({\n next: z.array(actionEntrySchema).min(1),\n fallback: actionsFallbackSchema.optional(),\n })\n .strict();\n\n/**\n * Wire-format type for the `escrow` PaymentRequirements that a server emits\n * inside a 402 `accepts[]` entry. See docs/boson-impl-01-escrow-scheme.md §2\n * for field semantics.\n */\nexport interface EscrowPaymentRequirements {\n scheme: \"escrow\";\n network: EvmNetwork;\n asset: Address;\n /** Atomic units, decimal string. */\n amount: string;\n /** Address of the Boson escrow contract — the custodian. */\n escrowAddress: Address;\n /** Routing-only seller identifier. May be a numeric `sellerId`, a `did:boson:seller:N`, or a wallet address. */\n recipientId: string;\n maxTimeoutSeconds: number;\n offer: BosonOfferRef;\n tokenAuthStrategies: TokenAuthStrategy[];\n fulfillment?: FulfillmentRequirements;\n actions: ActionsEnvelope;\n}\n\n/** Zod validator paired with `payment_requirements.schema.json`. */\nexport const escrowPaymentRequirementsSchema = z\n .object({\n scheme: z.literal(\"escrow\"),\n network: evmNetworkSchema,\n asset: addressSchema,\n amount: decimalUintSchema,\n escrowAddress: addressSchema,\n recipientId: z.string().min(1),\n maxTimeoutSeconds: z.number().int().positive(),\n offer: offerRefSchema,\n tokenAuthStrategies: z\n .array(tokenAuthStrategySchema)\n .min(1)\n .refine((strategies) => new Set(strategies).size === strategies.length, {\n message: \"tokenAuthStrategies must not contain duplicates\",\n }),\n fulfillment: fulfillmentSchema.optional(),\n actions: actionsSchema,\n })\n .strict();\n\n/** Type-guard form. Returns the parsed value on success, throws on failure (with a `ZodError` carrying the field path). */\nexport function parseEscrowPaymentRequirements(value: unknown): EscrowPaymentRequirements {\n return escrowPaymentRequirementsSchema.parse(value);\n}\n","// `escrow` scheme PaymentPayload (client -> server, base64'd in `X-PAYMENT`).\n// Source of truth: docs/boson-impl-01-escrow-scheme.md §3.\n\nimport { z } from \"zod\";\n\nimport {\n TOKEN_AUTH_STRATEGIES,\n type Address,\n type BosonMetaTx,\n type BosonTokenAuth,\n type EvmNetwork,\n type FullOffer,\n type Hex,\n type TokenAuthStrategy,\n} from \"./types.js\";\nimport {\n addressSchema,\n decimalUintSchema,\n evmNetworkSchema,\n hex32Schema,\n hexBytesSchema,\n hexSchema,\n} from \"./validators.js\";\n\nconst sigSchema = z\n .object({\n v: z.number().int(),\n r: hex32Schema,\n s: hex32Schema,\n })\n .strict();\n\nconst metaTxSchema = z\n .object({\n from: addressSchema,\n nonce: decimalUintSchema,\n functionName: z.string().min(1),\n functionSignature: hexBytesSchema,\n sig: sigSchema,\n })\n .strict();\n\nconst erc3009DataSchema = z\n .object({\n from: addressSchema,\n to: addressSchema,\n value: decimalUintSchema,\n validAfter: z.number().int().nonnegative(),\n validBefore: z.number().int().nonnegative(),\n nonce: hex32Schema,\n v: z.number().int(),\n r: hex32Schema,\n s: hex32Schema,\n })\n .strict();\n\nconst permitDataSchema = z\n .object({\n owner: addressSchema,\n spender: addressSchema,\n value: decimalUintSchema,\n deadline: z.number().int().nonnegative(),\n nonce: decimalUintSchema,\n v: z.number().int(),\n r: hex32Schema,\n s: hex32Schema,\n })\n .strict();\n\nconst permit2DataSchema = z\n .object({\n permitted: z\n .object({\n token: addressSchema,\n amount: decimalUintSchema,\n })\n .strict(),\n spender: addressSchema,\n nonce: decimalUintSchema,\n deadline: z.number().int().nonnegative(),\n signature: hexSchema,\n })\n .strict();\n\nconst tokenAuthSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"erc3009\"), data: erc3009DataSchema }).strict(),\n z.object({ kind: z.literal(\"permit\"), data: permitDataSchema }).strict(),\n z.object({ kind: z.literal(\"permit2\"), data: permit2DataSchema }).strict(),\n]);\n\nconst tokenAuthStrategySchema = z.enum(\n TOKEN_AUTH_STRATEGIES as readonly [TokenAuthStrategy, ...TokenAuthStrategy[]],\n);\n\n/** Inner `payload` field of `EscrowPaymentPayload`. */\nexport interface EscrowPaymentPayloadInner {\n action: string;\n tokenAuthStrategy: TokenAuthStrategy;\n offerRef: { fullOffer: FullOffer; sellerSig: Hex };\n buyer: Address;\n metaTx: BosonMetaTx;\n /** Required iff `tokenAuthStrategy !== \"none\"`. */\n tokenAuth?: BosonTokenAuth;\n}\n\n/**\n * Wire-format type for the `escrow` PaymentPayload that a client base64's into\n * the `X-PAYMENT` header. See docs/boson-impl-01-escrow-scheme.md §3.\n *\n * `fulfillment.option` is always the buyer's pick from the server-advertised\n * option set (capability negotiation). `fulfillment.data` is action-conditional:\n *\n * - For atomic Flow B (`boson-createOfferCommitAndRedeem`), `data` MUST be\n * present (or `null` when the option's schema is `null`). Atomic Flow B\n * completes the redeem on-chain inside the commit transaction, so there's\n * no later round trip in which the buyer could hand the seller delivery\n * data — it must travel with `X-PAYMENT`.\n * - For two-step Flow A (`boson-createOfferAndCommit`), `data` MUST be\n * omitted. The buyer attaches it to the redeem-time POST body that\n * accompanies `boson-redeem`, after a successful commit. See\n * `docs/boson-impl-03-fulfillment-channels.md`.\n *\n * The Zod schema parses both shapes structurally; the action-conditional\n * presence/absence rule is enforced by the server-side validator (rule 13).\n */\nexport interface EscrowPaymentPayload {\n x402Version: number;\n scheme: \"escrow\";\n network: EvmNetwork;\n payload: EscrowPaymentPayloadInner;\n fulfillment?: { option: string; data?: Record<string, unknown> | null };\n}\n\n/**\n * Zod validator paired with `payment_payload.schema.json`. Note: this only\n * validates structural shape; cross-field rules (per docs/boson-impl-01 §5)\n * such as \"tokenAuth must be omitted iff tokenAuthStrategy === 'none'\" are\n * enforced server-side and are not part of this schema.\n */\nexport const escrowPaymentPayloadSchema = z\n .object({\n x402Version: z.number().int(),\n scheme: z.literal(\"escrow\"),\n network: evmNetworkSchema,\n payload: z\n .object({\n action: z.string().min(1),\n tokenAuthStrategy: tokenAuthStrategySchema,\n offerRef: z\n .object({\n fullOffer: z.record(z.unknown()),\n sellerSig: hexSchema,\n })\n .strict(),\n buyer: addressSchema,\n metaTx: metaTxSchema,\n tokenAuth: tokenAuthSchema.optional(),\n })\n .strict(),\n fulfillment: z\n .object({\n option: z.string().min(1),\n // `data` is action-conditional (Flow B only). The structural\n // schema accepts both shapes; the server validator enforces\n // presence vs absence based on `payload.action`.\n data: z.union([z.record(z.unknown()), z.null()]).optional(),\n })\n .strict()\n .optional(),\n })\n .strict();\n\nexport function parseEscrowPaymentPayload(value: unknown): EscrowPaymentPayload {\n return escrowPaymentPayloadSchema.parse(value);\n}\n","// Post-commit `nextActions` envelope (top level of every response after\n// the initial 402). The pre-commit variant lives nested inside\n// `EscrowPaymentRequirements.actions` — see `payment-requirements.ts`.\n//\n// Source of truth: docs/boson-impl-04-state-machine-and-next-actions.md\n// §\"`nextActions` envelope\" and `schemas/next_actions.schema.json`.\n\nimport { z } from \"zod\";\n\nimport { DisputeState, ExchangeState } from \"../../state-machine/states.js\";\nimport { actionEntrySchema, actionsFallbackSchema } from \"./shared-schemas.js\";\nimport { type ActionsFallback, type NextAction } from \"./types.js\";\n\n/**\n * Wire-format type for the post-commit `nextActions` envelope.\n *\n * The `exchangeState === DISPUTED ↔ disputeState present` invariant is\n * encoded structurally: `exchangeState: DISPUTED` requires\n * `disputeState`, and any other `exchangeState` forbids it. The zod\n * validator below enforces the same invariant at runtime.\n *\n * The wire field is named `exchangeState` (not `state`) for symmetry\n * with `disputeState` and to remove ambiguity with the `state` field\n * the subgraph entity itself carries.\n */\nexport type EscrowNextActions = {\n exchangeId: string;\n next: NextAction[];\n fallback?: ActionsFallback;\n} & (\n | {\n exchangeState: Exclude<ExchangeState, typeof ExchangeState.DISPUTED>;\n disputeState?: never;\n }\n | { exchangeState: typeof ExchangeState.DISPUTED; disputeState: DisputeState }\n);\n\nconst exchangeStateSchema = z.nativeEnum(ExchangeState);\nconst disputeStateSchema = z.nativeEnum(DisputeState);\n\n/** Zod validator paired with `next_actions.schema.json`. */\nexport const escrowNextActionsSchema = z\n .object({\n exchangeId: z.string().min(1),\n exchangeState: exchangeStateSchema,\n disputeState: disputeStateSchema.optional(),\n next: z.array(actionEntrySchema),\n fallback: actionsFallbackSchema.optional(),\n })\n .strict()\n .refine(\n (envelope) =>\n envelope.exchangeState === ExchangeState.DISPUTED\n ? envelope.disputeState !== undefined\n : envelope.disputeState === undefined,\n {\n message: \"disputeState is required iff exchangeState === DISPUTED\",\n path: [\"disputeState\"],\n },\n );\n\n/** Type-guard form. Returns the parsed value on success, throws on failure. */\nexport function parseEscrowNextActions(value: unknown): EscrowNextActions {\n return escrowNextActionsSchema.parse(value) as EscrowNextActions;\n}\n","// Public surface for the `escrow` scheme.\n// See docs/boson-impl-01-escrow-scheme.md for the wire format.\n\nexport * from \"./types.js\";\nexport * from \"./payment-requirements.js\";\nexport * from \"./payment-payload.js\";\nexport * from \"./next-actions.js\";\nexport * from \"./validators.js\";\n\n/** Stable identifier for the scheme. Use this in place of the raw string `\"escrow\"` to avoid typos. */\nexport const ESCROW_SCHEME = \"escrow\" as const;\nexport type EscrowScheme = typeof ESCROW_SCHEME;\n"]}
@@ -0,0 +1,127 @@
1
+ import { DisputeState, ExchangeState, PRE_COMMIT } from '../chunk-7IY3WEFZ.js';
2
+ export { DisputeState, ExchangeState, PRE_COMMIT } from '../chunk-7IY3WEFZ.js';
3
+
4
+ // src/state-machine/action-ids.ts
5
+ var ACTION_ID_PREFIX = "boson-";
6
+ var EXCHANGE_ACTION_IDS = [
7
+ "boson-createOfferAndCommit",
8
+ "boson-createOfferCommitAndRedeem",
9
+ "boson-redeem",
10
+ "boson-cancelVoucher",
11
+ "boson-revokeVoucher",
12
+ "boson-completeExchange",
13
+ "boson-raiseDispute",
14
+ "boson-resolveDispute",
15
+ "boson-escalateDispute",
16
+ "boson-retractDispute"
17
+ ];
18
+ var ENTITY_ACTION_IDS = ["boson-withdrawFunds"];
19
+ var ACTION_IDS = [
20
+ ...EXCHANGE_ACTION_IDS,
21
+ ...ENTITY_ACTION_IDS
22
+ ];
23
+ var ENTITY_ACTION_SET = new Set(ENTITY_ACTION_IDS);
24
+ function isEntityKeyedAction(action) {
25
+ return ENTITY_ACTION_SET.has(action);
26
+ }
27
+ var ACTION_POST_STATE = {
28
+ "boson-createOfferAndCommit": { exchange: ExchangeState.COMMITTED },
29
+ "boson-createOfferCommitAndRedeem": { exchange: ExchangeState.REDEEMED },
30
+ "boson-redeem": { exchange: ExchangeState.REDEEMED },
31
+ "boson-cancelVoucher": { exchange: ExchangeState.CANCELLED },
32
+ "boson-revokeVoucher": { exchange: ExchangeState.REVOKED },
33
+ "boson-completeExchange": { exchange: ExchangeState.COMPLETED },
34
+ "boson-raiseDispute": {
35
+ exchange: ExchangeState.DISPUTED,
36
+ dispute: DisputeState.RESOLVING
37
+ },
38
+ "boson-resolveDispute": {
39
+ exchange: ExchangeState.DISPUTED,
40
+ dispute: DisputeState.RESOLVED
41
+ },
42
+ "boson-escalateDispute": {
43
+ exchange: ExchangeState.DISPUTED,
44
+ dispute: DisputeState.ESCALATED
45
+ },
46
+ "boson-retractDispute": {
47
+ exchange: ExchangeState.DISPUTED,
48
+ dispute: DisputeState.RETRACTED
49
+ }
50
+ };
51
+ var ACTION_FACETS = {
52
+ "boson-createOfferAndCommit": "ExchangeCommitFacet",
53
+ "boson-createOfferCommitAndRedeem": "OrchestrationHandlerFacet2",
54
+ "boson-redeem": "ExchangeHandlerFacet",
55
+ "boson-cancelVoucher": "ExchangeHandlerFacet",
56
+ "boson-revokeVoucher": "ExchangeHandlerFacet",
57
+ "boson-completeExchange": "ExchangeHandlerFacet",
58
+ "boson-raiseDispute": "DisputeHandlerFacet",
59
+ "boson-resolveDispute": "DisputeHandlerFacet",
60
+ "boson-escalateDispute": "DisputeHandlerFacet",
61
+ "boson-retractDispute": "DisputeHandlerFacet",
62
+ "boson-withdrawFunds": "FundsHandlerFacet"
63
+ };
64
+
65
+ // src/state-machine/transitions.ts
66
+ var CLIENT_BY_EXCHANGE = {
67
+ [PRE_COMMIT]: ["boson-createOfferAndCommit", "boson-createOfferCommitAndRedeem"],
68
+ [ExchangeState.COMMITTED]: ["boson-redeem", "boson-cancelVoucher"],
69
+ [ExchangeState.REDEEMED]: ["boson-completeExchange", "boson-raiseDispute"],
70
+ [ExchangeState.DISPUTED]: [],
71
+ // branches on dispute sub-state.
72
+ [ExchangeState.CANCELLED]: [],
73
+ [ExchangeState.COMPLETED]: [],
74
+ [ExchangeState.REVOKED]: []
75
+ };
76
+ var CLIENT_BY_DISPUTE = {
77
+ [DisputeState.RESOLVING]: [
78
+ "boson-resolveDispute",
79
+ "boson-escalateDispute",
80
+ "boson-retractDispute"
81
+ ],
82
+ [DisputeState.ESCALATED]: [],
83
+ // resolver decides; buyer waits.
84
+ [DisputeState.RESOLVED]: ["boson-withdrawFunds"],
85
+ [DisputeState.RETRACTED]: [],
86
+ [DisputeState.DECIDED]: [],
87
+ [DisputeState.REFUSED]: []
88
+ };
89
+ var SERVER_BY_EXCHANGE = {
90
+ [PRE_COMMIT]: [],
91
+ [ExchangeState.COMMITTED]: ["boson-revokeVoucher"],
92
+ [ExchangeState.REDEEMED]: [],
93
+ [ExchangeState.DISPUTED]: [],
94
+ [ExchangeState.CANCELLED]: [],
95
+ [ExchangeState.COMPLETED]: [],
96
+ [ExchangeState.REVOKED]: []
97
+ };
98
+ var SERVER_BY_DISPUTE = {
99
+ [DisputeState.RESOLVING]: ["boson-resolveDispute"],
100
+ // mutual; seller-initiable.
101
+ [DisputeState.ESCALATED]: [],
102
+ [DisputeState.RESOLVED]: ["boson-withdrawFunds"],
103
+ [DisputeState.RETRACTED]: [],
104
+ [DisputeState.DECIDED]: [],
105
+ [DisputeState.REFUSED]: []
106
+ };
107
+ function lookup(state, byExchange, byDispute) {
108
+ if (state === PRE_COMMIT) return byExchange[PRE_COMMIT];
109
+ if (state.exchange === ExchangeState.DISPUTED) return byDispute[state.dispute];
110
+ return byExchange[state.exchange];
111
+ }
112
+ function clientLegalActions(state) {
113
+ return lookup(state, CLIENT_BY_EXCHANGE, CLIENT_BY_DISPUTE);
114
+ }
115
+ function serverLegalActions(state) {
116
+ return lookup(state, SERVER_BY_EXCHANGE, SERVER_BY_DISPUTE);
117
+ }
118
+ function legalActions(state, side) {
119
+ return side === "client" ? clientLegalActions(state) : serverLegalActions(state);
120
+ }
121
+ function isLegalTransition(state, actionId, side) {
122
+ return legalActions(state, side).includes(actionId);
123
+ }
124
+
125
+ export { ACTION_FACETS, ACTION_IDS, ACTION_ID_PREFIX, ACTION_POST_STATE, ENTITY_ACTION_IDS, EXCHANGE_ACTION_IDS, clientLegalActions, isEntityKeyedAction, isLegalTransition, legalActions, serverLegalActions };
126
+ //# sourceMappingURL=index.js.map
127
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/state-machine/action-ids.ts","../../../src/state-machine/transitions.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// Stable action-id constants for Boson exchange + dispute + funds transitions.\n//\n// Source of truth: docs/boson-impl-04-state-machine-and-next-actions.md §\"Action IDs\".\n// All Boson-specific ids carry the `boson-` prefix so the `escrow` scheme\n// can later host other escrow implementations without collision; clients\n// that don't recognize an action's prefix MUST skip it rather than\n// dispatch.\n//\n// Two flavours of action id live here:\n//\n// 1. **Exchange-keyed actions** (`EXCHANGE_ACTION_IDS`) — the bulk of\n// the list. Each invocation operates on a single `exchangeId`, has a\n// well-defined pre/post state pair (see `ACTION_POST_STATE`), and is\n// eligible for the `nextActions.next[]` envelope built by\n// `@bosonprotocol/x402-actions`.\n// 2. **Entity-keyed actions** (`ENTITY_ACTION_IDS`) — invocations that\n// target a Boson account `entityId` (buyer or seller) rather than a\n// specific exchange. They do not transition the exchange state\n// machine and are deliberately absent from `next[]`; they expose\n// their own server endpoints (e.g. `POST /x402B/withdraw-funds`).\n// See spec doc §\"Entity-keyed actions\".\n//\n// Scope: actions either the client (buyer) OR the server (seller) can\n// invoke. The buyer/seller split lives in `./transitions.ts` —\n// `clientLegalActions` vs `serverLegalActions`. Dispute-resolver-only\n// transitions (`decideDispute`, `refuseEscalatedDispute`) and pure\n// time-based transitions (voucher expiry, dispute timeout, escalation\n// timeout) are not exposed as actions here.\n//\n// Future additions tracked but not yet listed:\n// - `boson-commitToOffer` — commits to an existing offer (no fresh offer\n// creation). Adds COMMITTED as a post-state from PRE_COMMIT alongside\n// `createOfferAndCommit`.\n// - `boson-commitToConditionalOffer` — commits to an existing offer that\n// gates entry on a token-holding condition. Same post-state as\n// `commitToOffer`.\n// - `boson-commitToConditionalOfferAndRedeemVoucher` — the atomic\n// commit-and-redeem variant for conditional offers, parallel to\n// `createOfferCommitAndRedeem`.\n// These will land once the corresponding Boson Diamond facets stabilize.\n\nimport { DisputeState, ExchangeState } from \"./states.js\";\n\n/** Prefix used by every Boson-side action id. */\nexport const ACTION_ID_PREFIX = \"boson-\" as const;\n\n/**\n * Actions tied to the exchange / dispute state machine. Each entry has a\n * deterministic `ACTION_POST_STATE` entry and is consumed by\n * `@bosonprotocol/x402-actions` when deriving `next[]`.\n */\nexport const EXCHANGE_ACTION_IDS = [\n \"boson-createOfferAndCommit\",\n \"boson-createOfferCommitAndRedeem\",\n \"boson-redeem\",\n \"boson-cancelVoucher\",\n \"boson-revokeVoucher\",\n \"boson-completeExchange\",\n \"boson-raiseDispute\",\n \"boson-resolveDispute\",\n \"boson-escalateDispute\",\n \"boson-retractDispute\",\n] as const;\n\nexport type ExchangeActionId = (typeof EXCHANGE_ACTION_IDS)[number];\n\n/**\n * Actions targeting a Boson account `entityId` (buyer or seller) rather\n * than a specific exchange. They live alongside the exchange-keyed set\n * for naming / prefix reasons but follow a separate dispatch path: a\n * dedicated convenience endpoint per action, no `ACTION_POST_STATE`\n * entry, and no representation in `nextActions.next[]`.\n */\nexport const ENTITY_ACTION_IDS = [\"boson-withdrawFunds\"] as const;\n\nexport type EntityActionId = (typeof ENTITY_ACTION_IDS)[number];\n\nexport const ACTION_IDS = [\n ...EXCHANGE_ACTION_IDS,\n ...ENTITY_ACTION_IDS,\n] as const satisfies readonly (ExchangeActionId | EntityActionId)[];\n\nexport type ActionId = ExchangeActionId | EntityActionId;\n\nconst ENTITY_ACTION_SET = new Set<string>(ENTITY_ACTION_IDS);\n\n/** Type guard — `true` iff `action` targets an `entityId` rather than an `exchangeId`. */\nexport function isEntityKeyedAction(action: string): action is EntityActionId {\n return ENTITY_ACTION_SET.has(action);\n}\n\n/**\n * The post-state of an exchange (and its dispute, if applicable) after the\n * given action is invoked successfully on the protocol. Useful for clients\n * that want to predict the next state client-side before re-fetching from\n * the subgraph.\n *\n * Some transitions terminate via dispute settlement and the exchange may\n * remain `DISPUTED` while the `Dispute` entity moves on — that's modeled\n * here by setting both `exchange` and `dispute`.\n *\n * Keyed by `ExchangeActionId`: entity-keyed actions have no exchange\n * post-state and intentionally do not appear here.\n */\nexport interface ActionPostState {\n exchange: ExchangeState;\n dispute?: DisputeState;\n}\n\nexport const ACTION_POST_STATE: Record<ExchangeActionId, ActionPostState> = {\n \"boson-createOfferAndCommit\": { exchange: ExchangeState.COMMITTED },\n \"boson-createOfferCommitAndRedeem\": { exchange: ExchangeState.REDEEMED },\n \"boson-redeem\": { exchange: ExchangeState.REDEEMED },\n \"boson-cancelVoucher\": { exchange: ExchangeState.CANCELLED },\n \"boson-revokeVoucher\": { exchange: ExchangeState.REVOKED },\n \"boson-completeExchange\": { exchange: ExchangeState.COMPLETED },\n \"boson-raiseDispute\": {\n exchange: ExchangeState.DISPUTED,\n dispute: DisputeState.RESOLVING,\n },\n \"boson-resolveDispute\": {\n exchange: ExchangeState.DISPUTED,\n dispute: DisputeState.RESOLVED,\n },\n \"boson-escalateDispute\": {\n exchange: ExchangeState.DISPUTED,\n dispute: DisputeState.ESCALATED,\n },\n \"boson-retractDispute\": {\n exchange: ExchangeState.DISPUTED,\n dispute: DisputeState.RETRACTED,\n },\n};\n\n/**\n * Boson Diamond facet that exposes the on-chain primitive for each\n * `ActionId`. Used by `@bosonprotocol/x402-actions` to populate the\n * `fallback.onchainHints.actionFacets` block of a `nextActions`\n * envelope so buyers can reach the underlying contract method directly\n * via the `onchain` channel.\n *\n * Mapping rationale:\n * - `boson-createOfferAndCommit` lives on `ExchangeCommitFacet` (the\n * deferred-redeem entry point per spec doc 04).\n * - `boson-createOfferCommitAndRedeem` lives on\n * `OrchestrationHandlerFacet2` (the atomic-redeem entry point).\n * - `boson-redeem`, `boson-cancelVoucher`, `boson-revokeVoucher`, and\n * `boson-completeExchange` are exchange-lifecycle methods on\n * `ExchangeHandlerFacet`.\n * - All four dispute transitions (`raise` / `resolve` / `escalate` /\n * `retract`) live on `DisputeHandlerFacet`.\n * - `boson-withdrawFunds` lives on `FundsHandlerFacet`.\n *\n * The keys are intentionally exhaustive over `ActionId` so adding a\n * new action id at compile time forces a paired facet entry.\n */\nexport const ACTION_FACETS: Record<ActionId, string> = {\n \"boson-createOfferAndCommit\": \"ExchangeCommitFacet\",\n \"boson-createOfferCommitAndRedeem\": \"OrchestrationHandlerFacet2\",\n \"boson-redeem\": \"ExchangeHandlerFacet\",\n \"boson-cancelVoucher\": \"ExchangeHandlerFacet\",\n \"boson-revokeVoucher\": \"ExchangeHandlerFacet\",\n \"boson-completeExchange\": \"ExchangeHandlerFacet\",\n \"boson-raiseDispute\": \"DisputeHandlerFacet\",\n \"boson-resolveDispute\": \"DisputeHandlerFacet\",\n \"boson-escalateDispute\": \"DisputeHandlerFacet\",\n \"boson-retractDispute\": \"DisputeHandlerFacet\",\n \"boson-withdrawFunds\": \"FundsHandlerFacet\",\n};\n","// Legal transitions per (exchange, dispute) state, split by invoker.\n//\n// Source of truth: docs/boson-impl-04-state-machine-and-next-actions.md.\n// Two separate tables, each listing the actions that the named party can\n// directly invoke:\n//\n// - CLIENT — actions the buyer (the x402 client) can invoke. Drives\n// the `nextActions` envelope on every server response to the buyer.\n// - SERVER — actions the seller (the x402 resource server) can invoke.\n// Used by the seller-side SDK to know which seller-invokable actions\n// are legally available at the current state.\n//\n// `resolveDispute` is mutual — both parties' signatures are required — and\n// appears in BOTH tables: either side can initiate it once they hold the\n// counterparty's signature. `revokeVoucher` is seller-only and appears\n// only in SERVER. The other 8 exchange-keyed actions are buyer-only and\n// appear only in CLIENT.\n//\n// One entity-keyed action — `boson-withdrawFunds` — is carved into the\n// `(DISPUTED, RESOLVED)` row on both sides. A successful `resolveDispute`\n// releases the buyer's and seller's escrowed funds to their respective\n// available balances; surfacing withdraw on the very next `nextActions`\n// envelope lets either party drain those funds in one click without\n// needing to know about the standalone endpoint up-front. Other\n// fund-releasing transitions (`completeExchange`, `cancelVoucher`,\n// `revokeVoucher`, `retractDispute`, `decideDispute`, `refuseDispute`)\n// could receive the same treatment in follow-up work.\n//\n// Higher-level concerns (deadline math, channel selection, channel\n// fallback, the `nextActions` envelope) belong in\n// `@bosonprotocol/x402-actions`'s runtime, not here.\n\nimport { type ActionId } from \"./action-ids.js\";\nimport { DisputeState, ExchangeState, PRE_COMMIT, type ClientState } from \"./states.js\";\n\n/** Side of the protocol that's invoking the action. */\nexport type Side = \"client\" | \"server\";\n\ntype ExchangeTransitions = Record<ExchangeState | typeof PRE_COMMIT, readonly ActionId[]>;\ntype DisputeTransitions = Record<DisputeState, readonly ActionId[]>;\n\nconst CLIENT_BY_EXCHANGE: ExchangeTransitions = {\n [PRE_COMMIT]: [\"boson-createOfferAndCommit\", \"boson-createOfferCommitAndRedeem\"],\n [ExchangeState.COMMITTED]: [\"boson-redeem\", \"boson-cancelVoucher\"],\n [ExchangeState.REDEEMED]: [\"boson-completeExchange\", \"boson-raiseDispute\"],\n [ExchangeState.DISPUTED]: [], // branches on dispute sub-state.\n [ExchangeState.CANCELLED]: [],\n [ExchangeState.COMPLETED]: [],\n [ExchangeState.REVOKED]: [],\n};\n\nconst CLIENT_BY_DISPUTE: DisputeTransitions = {\n [DisputeState.RESOLVING]: [\n \"boson-resolveDispute\",\n \"boson-escalateDispute\",\n \"boson-retractDispute\",\n ],\n [DisputeState.ESCALATED]: [], // resolver decides; buyer waits.\n [DisputeState.RESOLVED]: [\"boson-withdrawFunds\"],\n [DisputeState.RETRACTED]: [],\n [DisputeState.DECIDED]: [],\n [DisputeState.REFUSED]: [],\n};\n\nconst SERVER_BY_EXCHANGE: ExchangeTransitions = {\n [PRE_COMMIT]: [],\n [ExchangeState.COMMITTED]: [\"boson-revokeVoucher\"],\n [ExchangeState.REDEEMED]: [],\n [ExchangeState.DISPUTED]: [],\n [ExchangeState.CANCELLED]: [],\n [ExchangeState.COMPLETED]: [],\n [ExchangeState.REVOKED]: [],\n};\n\nconst SERVER_BY_DISPUTE: DisputeTransitions = {\n [DisputeState.RESOLVING]: [\"boson-resolveDispute\"], // mutual; seller-initiable.\n [DisputeState.ESCALATED]: [],\n [DisputeState.RESOLVED]: [\"boson-withdrawFunds\"],\n [DisputeState.RETRACTED]: [],\n [DisputeState.DECIDED]: [],\n [DisputeState.REFUSED]: [],\n};\n\nfunction lookup(\n state: ClientState,\n byExchange: ExchangeTransitions,\n byDispute: DisputeTransitions,\n): readonly ActionId[] {\n if (state === PRE_COMMIT) return byExchange[PRE_COMMIT];\n if (state.exchange === ExchangeState.DISPUTED) return byDispute[state.dispute];\n return byExchange[state.exchange];\n}\n\n/**\n * Actions the client (buyer) can legally invoke from `state`.\n * Empty array means \"buyer must wait / exchange is over for the buyer\".\n */\nexport function clientLegalActions(state: ClientState): readonly ActionId[] {\n return lookup(state, CLIENT_BY_EXCHANGE, CLIENT_BY_DISPUTE);\n}\n\n/**\n * Actions the server (seller) can legally invoke from `state`.\n * Empty array means \"no counterparty action is available at this state\".\n */\nexport function serverLegalActions(state: ClientState): readonly ActionId[] {\n return lookup(state, SERVER_BY_EXCHANGE, SERVER_BY_DISPUTE);\n}\n\n/** Convenience: side-parametrized lookup. */\nexport function legalActions(state: ClientState, side: Side): readonly ActionId[] {\n return side === \"client\" ? clientLegalActions(state) : serverLegalActions(state);\n}\n\n/** True iff `actionId` is a legal transition for `side` out of `state`. */\nexport function isLegalTransition(state: ClientState, actionId: ActionId, side: Side): boolean {\n return legalActions(state, side).includes(actionId);\n}\n"]}
@@ -0,0 +1,87 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://bosonprotocol.io/schemas/x402-core/next_actions.schema.json",
4
+ "title": "x402B escrow nextActions envelope (post-commit)",
5
+ "description": "Wire-format `nextActions` envelope returned at the top level of every post-commit response. The pre-commit (initial 402) variant is the inner `actions` field of payment_requirements.schema.json. Enum value orderings mirror the on-chain `BosonTypes.sol` declarations (ExchangeState, DisputeState) so the wire format stays in lock-step with the protocol. Source: docs/boson-impl-04-state-machine-and-next-actions.md §`nextActions` envelope.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["exchangeId", "exchangeState", "next"],
9
+ "properties": {
10
+ "exchangeId": { "type": "string", "minLength": 1 },
11
+ "exchangeState": {
12
+ "enum": ["COMMITTED", "REVOKED", "CANCELLED", "REDEEMED", "COMPLETED", "DISPUTED"]
13
+ },
14
+ "disputeState": {
15
+ "enum": ["RESOLVING", "RETRACTED", "RESOLVED", "ESCALATED", "DECIDED", "REFUSED"]
16
+ },
17
+ "next": {
18
+ "type": "array",
19
+ "items": {
20
+ "type": "object",
21
+ "additionalProperties": false,
22
+ "required": ["id", "channels"],
23
+ "properties": {
24
+ "id": { "type": "string", "minLength": 1 },
25
+ "channels": {
26
+ "type": "array",
27
+ "minItems": 1,
28
+ "uniqueItems": true,
29
+ "items": {
30
+ "enum": ["server", "facilitator", "onchain", "mcp", "xmtp"]
31
+ }
32
+ },
33
+ "endpoints": {
34
+ "type": "object",
35
+ "additionalProperties": { "type": "string" }
36
+ },
37
+ "deadline": {
38
+ "type": "string",
39
+ "format": "date-time"
40
+ }
41
+ }
42
+ }
43
+ },
44
+ "fallback": {
45
+ "type": "object",
46
+ "additionalProperties": false,
47
+ "properties": {
48
+ "xmtp": { "type": "string" },
49
+ "mcp": { "type": "string" },
50
+ "onchainHints": {
51
+ "type": "object",
52
+ "additionalProperties": false,
53
+ "required": ["escrow", "metaTxFacet", "metaTxEntrypoints", "actionFacets"],
54
+ "properties": {
55
+ "escrow": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$" },
56
+ "metaTxFacet": { "type": "string", "minLength": 1 },
57
+ "metaTxEntrypoints": {
58
+ "type": "object",
59
+ "additionalProperties": false,
60
+ "required": ["none", "erc3009", "permit", "permit2"],
61
+ "properties": {
62
+ "none": { "type": "string", "minLength": 1 },
63
+ "erc3009": { "type": "string", "minLength": 1 },
64
+ "permit": { "type": "string", "minLength": 1 },
65
+ "permit2": { "type": "string", "minLength": 1 }
66
+ }
67
+ },
68
+ "actionFacets": {
69
+ "type": "object",
70
+ "additionalProperties": { "type": "string" }
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+ },
77
+ "allOf": [
78
+ {
79
+ "if": {
80
+ "properties": { "exchangeState": { "const": "DISPUTED" } },
81
+ "required": ["exchangeState"]
82
+ },
83
+ "then": { "required": ["disputeState"] },
84
+ "else": { "not": { "required": ["disputeState"] } }
85
+ }
86
+ ]
87
+ }