kawasekit 0.2.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.
Files changed (36) hide show
  1. package/dist/{chunk-VXZHS74W.js → chunk-5TTOAVHE.js} +9 -3
  2. package/dist/chunk-5TTOAVHE.js.map +1 -0
  3. package/dist/chunk-EUW7AZ4P.js +276 -0
  4. package/dist/chunk-EUW7AZ4P.js.map +1 -0
  5. package/dist/{chunk-SMAZUZFO.js → chunk-G3UC6SME.js} +3 -3
  6. package/dist/{chunk-SMAZUZFO.js.map → chunk-G3UC6SME.js.map} +1 -1
  7. package/dist/{chunk-XRSZTZVZ.js → chunk-RJLDKDWL.js} +2 -2
  8. package/dist/{chunk-XRSZTZVZ.js.map → chunk-RJLDKDWL.js.map} +1 -1
  9. package/dist/cli/index.cjs +1 -1
  10. package/dist/cli/index.js +5 -5
  11. package/dist/{index-f-Xg86P9.d.ts → index-C9tbaHPF.d.ts} +1 -1
  12. package/dist/{index-Cn6kg7KH.d.cts → index-CAmTA8xR.d.cts} +1 -1
  13. package/dist/index.cjs +222 -4
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.cts +4 -4
  16. package/dist/index.d.ts +4 -4
  17. package/dist/index.js +4 -4
  18. package/dist/policy/index.d.cts +2 -2
  19. package/dist/policy/index.d.ts +2 -2
  20. package/dist/signer/index.cjs +218 -0
  21. package/dist/signer/index.cjs.map +1 -1
  22. package/dist/signer/index.d.cts +220 -5
  23. package/dist/signer/index.d.ts +220 -5
  24. package/dist/signer/index.js +2 -2
  25. package/dist/{spending-policy-DKZN3Sg8.d.ts → spending-policy-BD2Mpm-L.d.ts} +1 -1
  26. package/dist/{spending-policy-DaajDg9B.d.cts → spending-policy-CGIaBpg-.d.cts} +1 -1
  27. package/dist/{types-IEl-iOIx.d.cts → types-BLJU67HZ.d.cts} +11 -3
  28. package/dist/{types-IEl-iOIx.d.ts → types-BLJU67HZ.d.ts} +11 -3
  29. package/dist/x402/index.cjs.map +1 -1
  30. package/dist/x402/index.d.cts +2 -2
  31. package/dist/x402/index.d.ts +2 -2
  32. package/dist/x402/index.js +2 -2
  33. package/package.json +1 -1
  34. package/dist/chunk-THTVJZ2Q.js +0 -71
  35. package/dist/chunk-THTVJZ2Q.js.map +0 -1
  36. package/dist/chunk-VXZHS74W.js.map +0 -1
@@ -1,7 +1,7 @@
1
- import { a as PolicyGatedSigner, N as NonBypassableEnforcement } from '../types-IEl-iOIx.cjs';
2
- export { E as EnforcementLevel, P as PaymentIntent, b as PolicyRejection, S as SignResult, c as SignerDescription } from '../types-IEl-iOIx.cjs';
3
- import { Account } from 'viem';
4
- import { a as SpendingPolicy, S as SpendState } from '../spending-policy-DaajDg9B.cjs';
1
+ import { a as PolicyGatedSigner, N as NonBypassableEnforcement, P as PaymentIntent } from '../types-BLJU67HZ.cjs';
2
+ export { E as EnforcementLevel, b as PolicyRejection, S as SignResult, c as SignerDescription } from '../types-BLJU67HZ.cjs';
3
+ import { Account, Hex, Address } from 'viem';
4
+ import { a as SpendingPolicy, S as SpendState } from '../spending-policy-CGIaBpg-.cjs';
5
5
  import { X as X402AssetParam } from '../asset-domain-4Ioxqn28.cjs';
6
6
 
7
7
  /**
@@ -39,6 +39,36 @@ declare class PolicyGatedSignerConfigError extends Error {
39
39
  cause?: unknown;
40
40
  });
41
41
  }
42
+ /**
43
+ * Thrown by the `mpc-2p` cryptographic adapter when the co-signer is
44
+ * **unreachable or the ceremony could not complete** — endpoint down, TLS
45
+ * failure, connection dropped mid-ceremony, timeout, a malformed/missing
46
+ * terminal frame, or an internal protocol anomaly. It is a transient / internal
47
+ * error on the throws channel (M6-0: throws are reserved for internal/config
48
+ * errors), **distinct from a policy denial**.
49
+ *
50
+ * This is the **no-silent-fallback** guarantee (RFC m6-3a constraint 3 / W8):
51
+ * the adapter has no local-signing path, so an unavailable wire NEVER yields an
52
+ * `{ ok: true }` signature and NEVER a {@link PolicyRejection}. A `rejection`
53
+ * means "the owner decided no" (audit-meaningful); a `CoSignUnavailableError`
54
+ * means "the owner did not decide" — the caller may retry the *same* intent
55
+ * (the backend's idempotency keeps a retry safe).
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * try {
60
+ * const result = await mpc2pSigner.sign(intent);
61
+ * if (!result.ok) handleDenial(result.rejection); // owner said no
62
+ * } catch (error) {
63
+ * if (error instanceof CoSignUnavailableError) retryLater(); // wire was down
64
+ * }
65
+ * ```
66
+ */
67
+ declare class CoSignUnavailableError extends Error {
68
+ constructor(message: string, options?: {
69
+ cause?: unknown;
70
+ });
71
+ }
42
72
 
43
73
  /**
44
74
  * The enforcement-level type-gate — the compile-time (and runtime) mechanism
@@ -128,4 +158,189 @@ interface CreateLocalPolicyGatedSignerParams {
128
158
  */
129
159
  declare function createLocalPolicyGatedSigner(params: CreateLocalPolicyGatedSignerParams): PolicyGatedSigner<"advisory">;
130
160
 
131
- export { type CreateLocalPolicyGatedSignerParams, NonBypassableEnforcement, PolicyGatedSigner, PolicyGatedSignerConfigError, assertNonBypassable, createLocalPolicyGatedSigner, requireNonBypassable };
161
+ /**
162
+ * The `mpc-2p` cross-process **wire** — the versioned `CoSignFrame` control
163
+ * envelope + the A3 canonical-request encoding, as TypeScript source-of-truth.
164
+ *
165
+ * This is the public, TS-interpreted half of the two-layer wire (RFC m6-3a §4.2):
166
+ * a small, versioned envelope carries the decoded {@link PaymentIntent} (never a
167
+ * digest — A4) plus the opaque DKLs round payloads (hex, produced/consumed only
168
+ * by the WASM crypto agent). The shapes here mirror the deployed
169
+ * `kawasekit-mpc-2p` Rust serde **byte-for-byte** (snake_case `wire_version`,
170
+ * `session_id`, `auth_tag`; the string-encoded {@link WireIntent}), so a frame the
171
+ * SDK builds round-trips through the backend's `serde_json`. The richer envelope
172
+ * (ceremonyId / ssid / A3 freshness) is a later slice.
173
+ *
174
+ * `canonicalIntentBytes` is the A3 analog of the EIP-712 digest corpus: it
175
+ * reproduces the backend's `auth::canonical_intent_bytes` exactly, so the
176
+ * injected authenticator's HMAC equals what the co-signer verifies.
177
+ *
178
+ * @packageDocumentation
179
+ */
180
+
181
+ /** The wire protocol version. A frame whose `wire_version` differs is rejected. */
182
+ declare const WIRE_VERSION: 1;
183
+ /**
184
+ * The string-encoded EIP-3009 intent as it crosses the wire — lowercase `0x`
185
+ * addresses, **decimal** integer strings, `0x` hex nonce. Decoupled from any
186
+ * library's native serde so a stdlib client reproduces it trivially; matches the
187
+ * Rust `WireIntent` field names + encoding exactly.
188
+ */
189
+ interface WireIntent {
190
+ readonly token: string;
191
+ readonly chain_id: number;
192
+ readonly from: string;
193
+ readonly to: string;
194
+ readonly value: string;
195
+ readonly valid_after: string;
196
+ readonly valid_before: string;
197
+ readonly nonce: string;
198
+ }
199
+ /** Encode a decoded {@link PaymentIntent} for the wire. */
200
+ declare function toWireIntent(intent: PaymentIntent): WireIntent;
201
+ /**
202
+ * A versioned control frame: the only cross-language content of the wire. The
203
+ * DKLs round bytes ride opaque inside `payload`; everything else is the small,
204
+ * pinned envelope. Internally tagged by `kind` (matches the Rust serde).
205
+ */
206
+ type CoSignFrame = {
207
+ readonly wire_version: typeof WIRE_VERSION;
208
+ } & ({
209
+ readonly kind: "request";
210
+ readonly session_id: string;
211
+ readonly intent: WireIntent;
212
+ /** A3 authenticator over {@link canonicalIntentBytes}, `0x`-hex. */
213
+ readonly auth_tag: Hex;
214
+ } | {
215
+ readonly kind: "round";
216
+ readonly payload: Hex;
217
+ } | {
218
+ readonly kind: "result";
219
+ readonly r: Hex;
220
+ readonly s: Hex;
221
+ readonly v: number;
222
+ } | {
223
+ readonly kind: "rejection";
224
+ readonly reason: string;
225
+ readonly detail: string;
226
+ } | {
227
+ readonly kind: "error";
228
+ readonly message: string;
229
+ });
230
+ /**
231
+ * The A3 canonical encoding of an intent — a byte-exact mirror of the backend's
232
+ * `auth::canonical_intent_bytes` (domain-tag `kawasekit-mpc-2p/cosign-request/v2`,
233
+ * one `key=value\n` line per field, lowercase `0x` addresses, decimal integers,
234
+ * `0x` hex nonce, trailing newline). The injected authenticator HMACs these bytes;
235
+ * because the encoding is shared, the tag equals the co-signer's.
236
+ */
237
+ declare function canonicalIntentBytes(intent: PaymentIntent): Uint8Array;
238
+
239
+ /**
240
+ * The `mpc-2p` PolicyGatedSigner adapter — `enforcement: "cryptographic"`.
241
+ *
242
+ * A 2-of-2 MPC co-signer: the agent holds ONE DKLs share, the owner backend holds
243
+ * the other + the authoritative policy gate. No valid signature exists without a
244
+ * **policy-passing co-sign**, so — unlike `local` — a single key-holder cannot
245
+ * bypass the policy. That is what earns the non-bypassable `"cryptographic"` label
246
+ * and lets the M6-0 type-gate (`requireNonBypassable`) reject an advisory signer at
247
+ * compile time in bounded flows.
248
+ *
249
+ * **Open-core / thin adapter.** This module is pure orchestration over injected
250
+ * interfaces — it ships in the public SDK with **no crypto, no socket, no key**:
251
+ *
252
+ * - {@link Mpc2pCoSignAgent} — the WASM DKLs share (the private package's compiled
253
+ * `crypto-core`); drives the agent's half of the ceremony round-by-round.
254
+ * - {@link CoSignTransport} — the authenticated, encrypted (wss/mTLS) frame channel
255
+ * to the owner backend (the private package's transport).
256
+ * - {@link CoSignRequestAuthenticator} — the A3 HMAC (the pre-shared key never
257
+ * enters this module).
258
+ *
259
+ * The adapter owns the protocol: it pins the EIP-712 domain, **re-derives the
260
+ * digest from the intent (A4)** via the shared `transferWithAuthorizationTypes`
261
+ * source-of-truth, computes the A3 canonical bytes, frames the versioned
262
+ * {@link CoSignFrame} envelope, pumps the ceremony, and maps the terminal frame to
263
+ * a {@link SignResult}. Crucially it has **no local-signing path**: any
264
+ * transport/availability failure throws {@link CoSignUnavailableError}, never an
265
+ * `{ ok: true }` and never a {@link PolicyRejection} (the no-silent-fallback
266
+ * guarantee, RFC m6-3a constraint 3 / W8).
267
+ *
268
+ * @packageDocumentation
269
+ */
270
+
271
+ /** The agent's half of the 2-of-2 ceremony (the injected WASM DKLs share). */
272
+ interface Mpc2pCoSignAgent {
273
+ /** The group 2-of-2 EOA this share controls — must equal the signer's `from`. */
274
+ groupEoa(): Address;
275
+ /** Begin signing the 32-byte EIP-712 `digest`; returns the first outbound round (hex). */
276
+ start(digest: Hex): Hex;
277
+ /** Feed one inbound round (hex); returns the next outbound round, or the final signature. */
278
+ step(incoming: Hex): Mpc2pStepOutcome;
279
+ }
280
+ /** The result of one {@link Mpc2pCoSignAgent.step}. */
281
+ type Mpc2pStepOutcome = {
282
+ readonly outbound: Hex;
283
+ } | {
284
+ readonly signature: {
285
+ readonly r: Hex;
286
+ readonly s: Hex;
287
+ readonly v: number;
288
+ };
289
+ };
290
+ /** One authenticated, encrypted ceremony connection to the owner backend. */
291
+ interface CoSignConnection {
292
+ /** Send one control frame. */
293
+ send(frame: CoSignFrame): Promise<void>;
294
+ /** Receive the next control frame (resolves per round). */
295
+ recv(): Promise<CoSignFrame>;
296
+ /** Release the connection (best-effort; errors here are ignored). */
297
+ close(): void | Promise<void>;
298
+ }
299
+ /** Opens a wss/mTLS {@link CoSignConnection} for a single co-sign ceremony. */
300
+ interface CoSignTransport {
301
+ connect(): Promise<CoSignConnection>;
302
+ }
303
+ /** The A3 request authenticator — HMAC (or signature) over the canonical request bytes. */
304
+ interface CoSignRequestAuthenticator {
305
+ /** Authenticator tag over {@link canonicalIntentBytes}; the key stays inside. */
306
+ tag(canonicalRequest: Uint8Array): Hex | Promise<Hex>;
307
+ }
308
+ /** Parameters for {@link createMpc2pPolicyGatedSigner}. */
309
+ interface Mpc2pSignerParams {
310
+ /** The group 2-of-2 EOA; every `intent.from` must equal this (asserted vs the agent). */
311
+ readonly from: Address;
312
+ /** Asset binding — pins the EIP-712 domain `name`/`version`/`verifyingContract` (A4). */
313
+ readonly asset: X402AssetParam;
314
+ /** The bound policy session, for `describe()` (the backend holds the authoritative policy). */
315
+ readonly session: {
316
+ readonly id: string;
317
+ readonly notAfter: bigint;
318
+ };
319
+ /** The injected WASM DKLs share (private package). */
320
+ readonly agent: Mpc2pCoSignAgent;
321
+ /** The injected wss/mTLS frame channel (private package). */
322
+ readonly transport: CoSignTransport;
323
+ /** The injected A3 authenticator (the pre-shared key never enters the SDK). */
324
+ readonly authenticator: CoSignRequestAuthenticator;
325
+ }
326
+ /**
327
+ * Construct an `mpc-2p` (cryptographic) PolicyGatedSigner over injected agent +
328
+ * transport + authenticator.
329
+ *
330
+ * @example
331
+ * ```ts
332
+ * // The agent, transport and authenticator come from the private `kawasekit-mpc-2p`
333
+ * // package (the WASM share, the wss/mTLS client, the HMAC key) — never bundled here.
334
+ * const signer = createMpc2pPolicyGatedSigner({
335
+ * from: groupEoa,
336
+ * asset: { kind: "known", id: "jpyc-v2" },
337
+ * session: { id: "sess-1", notAfter: 2_000_000_000n },
338
+ * agent, transport, authenticator,
339
+ * });
340
+ * requireNonBypassable(signer); // ✓ "cryptographic" — passes the type-gate
341
+ * const result = await signer.sign(intent);
342
+ * ```
343
+ */
344
+ declare function createMpc2pPolicyGatedSigner(params: Mpc2pSignerParams): PolicyGatedSigner<"cryptographic">;
345
+
346
+ export { type CoSignConnection, type CoSignFrame, type CoSignRequestAuthenticator, type CoSignTransport, CoSignUnavailableError, type CreateLocalPolicyGatedSignerParams, type Mpc2pCoSignAgent, type Mpc2pSignerParams, type Mpc2pStepOutcome, NonBypassableEnforcement, PaymentIntent, PolicyGatedSigner, PolicyGatedSignerConfigError, WIRE_VERSION, type WireIntent, assertNonBypassable, canonicalIntentBytes, createLocalPolicyGatedSigner, createMpc2pPolicyGatedSigner, requireNonBypassable, toWireIntent };
@@ -1,7 +1,7 @@
1
- import { a as PolicyGatedSigner, N as NonBypassableEnforcement } from '../types-IEl-iOIx.js';
2
- export { E as EnforcementLevel, P as PaymentIntent, b as PolicyRejection, S as SignResult, c as SignerDescription } from '../types-IEl-iOIx.js';
3
- import { Account } from 'viem';
4
- import { a as SpendingPolicy, S as SpendState } from '../spending-policy-DKZN3Sg8.js';
1
+ import { a as PolicyGatedSigner, N as NonBypassableEnforcement, P as PaymentIntent } from '../types-BLJU67HZ.js';
2
+ export { E as EnforcementLevel, b as PolicyRejection, S as SignResult, c as SignerDescription } from '../types-BLJU67HZ.js';
3
+ import { Account, Hex, Address } from 'viem';
4
+ import { a as SpendingPolicy, S as SpendState } from '../spending-policy-BD2Mpm-L.js';
5
5
  import { X as X402AssetParam } from '../asset-domain-4Ioxqn28.js';
6
6
 
7
7
  /**
@@ -39,6 +39,36 @@ declare class PolicyGatedSignerConfigError extends Error {
39
39
  cause?: unknown;
40
40
  });
41
41
  }
42
+ /**
43
+ * Thrown by the `mpc-2p` cryptographic adapter when the co-signer is
44
+ * **unreachable or the ceremony could not complete** — endpoint down, TLS
45
+ * failure, connection dropped mid-ceremony, timeout, a malformed/missing
46
+ * terminal frame, or an internal protocol anomaly. It is a transient / internal
47
+ * error on the throws channel (M6-0: throws are reserved for internal/config
48
+ * errors), **distinct from a policy denial**.
49
+ *
50
+ * This is the **no-silent-fallback** guarantee (RFC m6-3a constraint 3 / W8):
51
+ * the adapter has no local-signing path, so an unavailable wire NEVER yields an
52
+ * `{ ok: true }` signature and NEVER a {@link PolicyRejection}. A `rejection`
53
+ * means "the owner decided no" (audit-meaningful); a `CoSignUnavailableError`
54
+ * means "the owner did not decide" — the caller may retry the *same* intent
55
+ * (the backend's idempotency keeps a retry safe).
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * try {
60
+ * const result = await mpc2pSigner.sign(intent);
61
+ * if (!result.ok) handleDenial(result.rejection); // owner said no
62
+ * } catch (error) {
63
+ * if (error instanceof CoSignUnavailableError) retryLater(); // wire was down
64
+ * }
65
+ * ```
66
+ */
67
+ declare class CoSignUnavailableError extends Error {
68
+ constructor(message: string, options?: {
69
+ cause?: unknown;
70
+ });
71
+ }
42
72
 
43
73
  /**
44
74
  * The enforcement-level type-gate — the compile-time (and runtime) mechanism
@@ -128,4 +158,189 @@ interface CreateLocalPolicyGatedSignerParams {
128
158
  */
129
159
  declare function createLocalPolicyGatedSigner(params: CreateLocalPolicyGatedSignerParams): PolicyGatedSigner<"advisory">;
130
160
 
131
- export { type CreateLocalPolicyGatedSignerParams, NonBypassableEnforcement, PolicyGatedSigner, PolicyGatedSignerConfigError, assertNonBypassable, createLocalPolicyGatedSigner, requireNonBypassable };
161
+ /**
162
+ * The `mpc-2p` cross-process **wire** — the versioned `CoSignFrame` control
163
+ * envelope + the A3 canonical-request encoding, as TypeScript source-of-truth.
164
+ *
165
+ * This is the public, TS-interpreted half of the two-layer wire (RFC m6-3a §4.2):
166
+ * a small, versioned envelope carries the decoded {@link PaymentIntent} (never a
167
+ * digest — A4) plus the opaque DKLs round payloads (hex, produced/consumed only
168
+ * by the WASM crypto agent). The shapes here mirror the deployed
169
+ * `kawasekit-mpc-2p` Rust serde **byte-for-byte** (snake_case `wire_version`,
170
+ * `session_id`, `auth_tag`; the string-encoded {@link WireIntent}), so a frame the
171
+ * SDK builds round-trips through the backend's `serde_json`. The richer envelope
172
+ * (ceremonyId / ssid / A3 freshness) is a later slice.
173
+ *
174
+ * `canonicalIntentBytes` is the A3 analog of the EIP-712 digest corpus: it
175
+ * reproduces the backend's `auth::canonical_intent_bytes` exactly, so the
176
+ * injected authenticator's HMAC equals what the co-signer verifies.
177
+ *
178
+ * @packageDocumentation
179
+ */
180
+
181
+ /** The wire protocol version. A frame whose `wire_version` differs is rejected. */
182
+ declare const WIRE_VERSION: 1;
183
+ /**
184
+ * The string-encoded EIP-3009 intent as it crosses the wire — lowercase `0x`
185
+ * addresses, **decimal** integer strings, `0x` hex nonce. Decoupled from any
186
+ * library's native serde so a stdlib client reproduces it trivially; matches the
187
+ * Rust `WireIntent` field names + encoding exactly.
188
+ */
189
+ interface WireIntent {
190
+ readonly token: string;
191
+ readonly chain_id: number;
192
+ readonly from: string;
193
+ readonly to: string;
194
+ readonly value: string;
195
+ readonly valid_after: string;
196
+ readonly valid_before: string;
197
+ readonly nonce: string;
198
+ }
199
+ /** Encode a decoded {@link PaymentIntent} for the wire. */
200
+ declare function toWireIntent(intent: PaymentIntent): WireIntent;
201
+ /**
202
+ * A versioned control frame: the only cross-language content of the wire. The
203
+ * DKLs round bytes ride opaque inside `payload`; everything else is the small,
204
+ * pinned envelope. Internally tagged by `kind` (matches the Rust serde).
205
+ */
206
+ type CoSignFrame = {
207
+ readonly wire_version: typeof WIRE_VERSION;
208
+ } & ({
209
+ readonly kind: "request";
210
+ readonly session_id: string;
211
+ readonly intent: WireIntent;
212
+ /** A3 authenticator over {@link canonicalIntentBytes}, `0x`-hex. */
213
+ readonly auth_tag: Hex;
214
+ } | {
215
+ readonly kind: "round";
216
+ readonly payload: Hex;
217
+ } | {
218
+ readonly kind: "result";
219
+ readonly r: Hex;
220
+ readonly s: Hex;
221
+ readonly v: number;
222
+ } | {
223
+ readonly kind: "rejection";
224
+ readonly reason: string;
225
+ readonly detail: string;
226
+ } | {
227
+ readonly kind: "error";
228
+ readonly message: string;
229
+ });
230
+ /**
231
+ * The A3 canonical encoding of an intent — a byte-exact mirror of the backend's
232
+ * `auth::canonical_intent_bytes` (domain-tag `kawasekit-mpc-2p/cosign-request/v2`,
233
+ * one `key=value\n` line per field, lowercase `0x` addresses, decimal integers,
234
+ * `0x` hex nonce, trailing newline). The injected authenticator HMACs these bytes;
235
+ * because the encoding is shared, the tag equals the co-signer's.
236
+ */
237
+ declare function canonicalIntentBytes(intent: PaymentIntent): Uint8Array;
238
+
239
+ /**
240
+ * The `mpc-2p` PolicyGatedSigner adapter — `enforcement: "cryptographic"`.
241
+ *
242
+ * A 2-of-2 MPC co-signer: the agent holds ONE DKLs share, the owner backend holds
243
+ * the other + the authoritative policy gate. No valid signature exists without a
244
+ * **policy-passing co-sign**, so — unlike `local` — a single key-holder cannot
245
+ * bypass the policy. That is what earns the non-bypassable `"cryptographic"` label
246
+ * and lets the M6-0 type-gate (`requireNonBypassable`) reject an advisory signer at
247
+ * compile time in bounded flows.
248
+ *
249
+ * **Open-core / thin adapter.** This module is pure orchestration over injected
250
+ * interfaces — it ships in the public SDK with **no crypto, no socket, no key**:
251
+ *
252
+ * - {@link Mpc2pCoSignAgent} — the WASM DKLs share (the private package's compiled
253
+ * `crypto-core`); drives the agent's half of the ceremony round-by-round.
254
+ * - {@link CoSignTransport} — the authenticated, encrypted (wss/mTLS) frame channel
255
+ * to the owner backend (the private package's transport).
256
+ * - {@link CoSignRequestAuthenticator} — the A3 HMAC (the pre-shared key never
257
+ * enters this module).
258
+ *
259
+ * The adapter owns the protocol: it pins the EIP-712 domain, **re-derives the
260
+ * digest from the intent (A4)** via the shared `transferWithAuthorizationTypes`
261
+ * source-of-truth, computes the A3 canonical bytes, frames the versioned
262
+ * {@link CoSignFrame} envelope, pumps the ceremony, and maps the terminal frame to
263
+ * a {@link SignResult}. Crucially it has **no local-signing path**: any
264
+ * transport/availability failure throws {@link CoSignUnavailableError}, never an
265
+ * `{ ok: true }` and never a {@link PolicyRejection} (the no-silent-fallback
266
+ * guarantee, RFC m6-3a constraint 3 / W8).
267
+ *
268
+ * @packageDocumentation
269
+ */
270
+
271
+ /** The agent's half of the 2-of-2 ceremony (the injected WASM DKLs share). */
272
+ interface Mpc2pCoSignAgent {
273
+ /** The group 2-of-2 EOA this share controls — must equal the signer's `from`. */
274
+ groupEoa(): Address;
275
+ /** Begin signing the 32-byte EIP-712 `digest`; returns the first outbound round (hex). */
276
+ start(digest: Hex): Hex;
277
+ /** Feed one inbound round (hex); returns the next outbound round, or the final signature. */
278
+ step(incoming: Hex): Mpc2pStepOutcome;
279
+ }
280
+ /** The result of one {@link Mpc2pCoSignAgent.step}. */
281
+ type Mpc2pStepOutcome = {
282
+ readonly outbound: Hex;
283
+ } | {
284
+ readonly signature: {
285
+ readonly r: Hex;
286
+ readonly s: Hex;
287
+ readonly v: number;
288
+ };
289
+ };
290
+ /** One authenticated, encrypted ceremony connection to the owner backend. */
291
+ interface CoSignConnection {
292
+ /** Send one control frame. */
293
+ send(frame: CoSignFrame): Promise<void>;
294
+ /** Receive the next control frame (resolves per round). */
295
+ recv(): Promise<CoSignFrame>;
296
+ /** Release the connection (best-effort; errors here are ignored). */
297
+ close(): void | Promise<void>;
298
+ }
299
+ /** Opens a wss/mTLS {@link CoSignConnection} for a single co-sign ceremony. */
300
+ interface CoSignTransport {
301
+ connect(): Promise<CoSignConnection>;
302
+ }
303
+ /** The A3 request authenticator — HMAC (or signature) over the canonical request bytes. */
304
+ interface CoSignRequestAuthenticator {
305
+ /** Authenticator tag over {@link canonicalIntentBytes}; the key stays inside. */
306
+ tag(canonicalRequest: Uint8Array): Hex | Promise<Hex>;
307
+ }
308
+ /** Parameters for {@link createMpc2pPolicyGatedSigner}. */
309
+ interface Mpc2pSignerParams {
310
+ /** The group 2-of-2 EOA; every `intent.from` must equal this (asserted vs the agent). */
311
+ readonly from: Address;
312
+ /** Asset binding — pins the EIP-712 domain `name`/`version`/`verifyingContract` (A4). */
313
+ readonly asset: X402AssetParam;
314
+ /** The bound policy session, for `describe()` (the backend holds the authoritative policy). */
315
+ readonly session: {
316
+ readonly id: string;
317
+ readonly notAfter: bigint;
318
+ };
319
+ /** The injected WASM DKLs share (private package). */
320
+ readonly agent: Mpc2pCoSignAgent;
321
+ /** The injected wss/mTLS frame channel (private package). */
322
+ readonly transport: CoSignTransport;
323
+ /** The injected A3 authenticator (the pre-shared key never enters the SDK). */
324
+ readonly authenticator: CoSignRequestAuthenticator;
325
+ }
326
+ /**
327
+ * Construct an `mpc-2p` (cryptographic) PolicyGatedSigner over injected agent +
328
+ * transport + authenticator.
329
+ *
330
+ * @example
331
+ * ```ts
332
+ * // The agent, transport and authenticator come from the private `kawasekit-mpc-2p`
333
+ * // package (the WASM share, the wss/mTLS client, the HMAC key) — never bundled here.
334
+ * const signer = createMpc2pPolicyGatedSigner({
335
+ * from: groupEoa,
336
+ * asset: { kind: "known", id: "jpyc-v2" },
337
+ * session: { id: "sess-1", notAfter: 2_000_000_000n },
338
+ * agent, transport, authenticator,
339
+ * });
340
+ * requireNonBypassable(signer); // ✓ "cryptographic" — passes the type-gate
341
+ * const result = await signer.sign(intent);
342
+ * ```
343
+ */
344
+ declare function createMpc2pPolicyGatedSigner(params: Mpc2pSignerParams): PolicyGatedSigner<"cryptographic">;
345
+
346
+ export { type CoSignConnection, type CoSignFrame, type CoSignRequestAuthenticator, type CoSignTransport, CoSignUnavailableError, type CreateLocalPolicyGatedSignerParams, type Mpc2pCoSignAgent, type Mpc2pSignerParams, type Mpc2pStepOutcome, NonBypassableEnforcement, PaymentIntent, PolicyGatedSigner, PolicyGatedSignerConfigError, WIRE_VERSION, type WireIntent, assertNonBypassable, canonicalIntentBytes, createLocalPolicyGatedSigner, createMpc2pPolicyGatedSigner, requireNonBypassable, toWireIntent };
@@ -1,5 +1,5 @@
1
- export { createLocalPolicyGatedSigner } from '../chunk-THTVJZ2Q.js';
2
- export { PolicyGatedSignerConfigError, assertNonBypassable, requireNonBypassable } from '../chunk-VXZHS74W.js';
1
+ export { WIRE_VERSION, canonicalIntentBytes, createLocalPolicyGatedSigner, createMpc2pPolicyGatedSigner, toWireIntent } from '../chunk-EUW7AZ4P.js';
2
+ export { CoSignUnavailableError, PolicyGatedSignerConfigError, assertNonBypassable, requireNonBypassable } from '../chunk-5TTOAVHE.js';
3
3
  import '../chunk-WMVJNPX2.js';
4
4
  import '../chunk-6CNAYQOL.js';
5
5
  import '../chunk-KT7XDT2T.js';
@@ -1,5 +1,5 @@
1
1
  import { Address } from 'viem';
2
- import { b as PolicyRejection, P as PaymentIntent } from './types-IEl-iOIx.js';
2
+ import { b as PolicyRejection, P as PaymentIntent } from './types-BLJU67HZ.js';
3
3
 
4
4
  /**
5
5
  * Spending policy — policy-as-data for the x402 / EIP-3009 PolicyGatedSigner
@@ -1,5 +1,5 @@
1
1
  import { Address } from 'viem';
2
- import { b as PolicyRejection, P as PaymentIntent } from './types-IEl-iOIx.cjs';
2
+ import { b as PolicyRejection, P as PaymentIntent } from './types-BLJU67HZ.cjs';
3
3
 
4
4
  /**
5
5
  * Spending policy — policy-as-data for the x402 / EIP-3009 PolicyGatedSigner
@@ -77,11 +77,19 @@ interface PaymentIntent {
77
77
  * The evaluator (`evaluateSpendingPolicy`) emits the `revoked` / `expired` /
78
78
  * `token_not_allowed` / `recipient_not_allowed` / `amount_exceeds_*` reasons;
79
79
  * the adapter additionally emits `from_mismatch` and (for `mpc-2p`)
80
- * `intent_digest_mismatch` / `unauthenticated`. The consumer handles one
81
- * `SignResult` regardless of adapter.
80
+ * `intent_digest_mismatch` / `unauthenticated` / `nonce_reuse_conflict`. The
81
+ * consumer handles one `SignResult` regardless of adapter.
82
82
  */
83
83
  interface PolicyRejection {
84
- readonly reason: "revoked" | "expired" | "token_not_allowed" | "recipient_not_allowed" | "amount_exceeds_per_sign" | "amount_exceeds_cumulative" | "intent_digest_mismatch" | "unauthenticated" | "from_mismatch";
84
+ readonly reason: "revoked" | "expired" | "token_not_allowed" | "recipient_not_allowed" | "amount_exceeds_per_sign" | "amount_exceeds_cumulative" | "intent_digest_mismatch" | "unauthenticated" | "from_mismatch"
85
+ /**
86
+ * (`mpc-2p`) The co-signer was presented a **previously-seen EIP-3009
87
+ * nonce with different intent fields** — the B7 same-nonce/different-fields
88
+ * fund-correctness anomaly. The backend denies + audits it; double-pay
89
+ * protection (same nonce, same fields → cached result) is a separate,
90
+ * non-rejection path (M5 `deriveAuthorizationNonce` + `authorizationState`).
91
+ */
92
+ | "nonce_reuse_conflict";
85
93
  /** Human-readable reason; never contains the nonce or a signature. */
86
94
  readonly detail: string;
87
95
  }
@@ -77,11 +77,19 @@ interface PaymentIntent {
77
77
  * The evaluator (`evaluateSpendingPolicy`) emits the `revoked` / `expired` /
78
78
  * `token_not_allowed` / `recipient_not_allowed` / `amount_exceeds_*` reasons;
79
79
  * the adapter additionally emits `from_mismatch` and (for `mpc-2p`)
80
- * `intent_digest_mismatch` / `unauthenticated`. The consumer handles one
81
- * `SignResult` regardless of adapter.
80
+ * `intent_digest_mismatch` / `unauthenticated` / `nonce_reuse_conflict`. The
81
+ * consumer handles one `SignResult` regardless of adapter.
82
82
  */
83
83
  interface PolicyRejection {
84
- readonly reason: "revoked" | "expired" | "token_not_allowed" | "recipient_not_allowed" | "amount_exceeds_per_sign" | "amount_exceeds_cumulative" | "intent_digest_mismatch" | "unauthenticated" | "from_mismatch";
84
+ readonly reason: "revoked" | "expired" | "token_not_allowed" | "recipient_not_allowed" | "amount_exceeds_per_sign" | "amount_exceeds_cumulative" | "intent_digest_mismatch" | "unauthenticated" | "from_mismatch"
85
+ /**
86
+ * (`mpc-2p`) The co-signer was presented a **previously-seen EIP-3009
87
+ * nonce with different intent fields** — the B7 same-nonce/different-fields
88
+ * fund-correctness anomaly. The backend denies + audits it; double-pay
89
+ * protection (same nonce, same fields → cached result) is a separate,
90
+ * non-rejection path (M5 `deriveAuthorizationNonce` + `authorizationState`).
91
+ */
92
+ | "nonce_reuse_conflict";
85
93
  /** Human-readable reason; never contains the nonce or a signature. */
86
94
  readonly detail: string;
87
95
  }