kawasekit 0.1.0-beta.6 → 0.2.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 (46) hide show
  1. package/dist/asset-domain-4Ioxqn28.d.cts +348 -0
  2. package/dist/asset-domain-4Ioxqn28.d.ts +348 -0
  3. package/dist/{chunk-YMABXRCK.js → chunk-6CNAYQOL.js} +2 -2
  4. package/dist/chunk-6CNAYQOL.js.map +1 -0
  5. package/dist/{chunk-E2EG72U2.js → chunk-SMAZUZFO.js} +4 -9
  6. package/dist/chunk-SMAZUZFO.js.map +1 -0
  7. package/dist/{chunk-RUWCCP37.js → chunk-THTVJZ2Q.js} +5 -10
  8. package/dist/chunk-THTVJZ2Q.js.map +1 -0
  9. package/dist/{chunk-VPRR3TNA.js → chunk-VXZHS74W.js} +59 -51
  10. package/dist/chunk-VXZHS74W.js.map +1 -0
  11. package/dist/{chunk-UQ7WJY6O.js → chunk-XRSZTZVZ.js} +2 -2
  12. package/dist/{chunk-UQ7WJY6O.js.map → chunk-XRSZTZVZ.js.map} +1 -1
  13. package/dist/cli/index.cjs +1 -1
  14. package/dist/cli/index.cjs.map +1 -1
  15. package/dist/cli/index.js +6 -6
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/{index-Z6AL1MR_.d.cts → index-Cn6kg7KH.d.cts} +1 -1
  18. package/dist/{index-BaAOB0xd.d.ts → index-f-Xg86P9.d.ts} +1 -1
  19. package/dist/index.cjs +14 -12
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +5 -170
  22. package/dist/index.d.ts +5 -170
  23. package/dist/index.js +5 -5
  24. package/dist/policy/index.cjs.map +1 -1
  25. package/dist/policy/index.d.cts +1 -1
  26. package/dist/policy/index.d.ts +1 -1
  27. package/dist/policy/index.js +1 -1
  28. package/dist/signer/index.cjs +9 -6
  29. package/dist/signer/index.cjs.map +1 -1
  30. package/dist/signer/index.d.cts +2 -2
  31. package/dist/signer/index.d.ts +2 -2
  32. package/dist/signer/index.js +3 -3
  33. package/dist/{spending-policy-DZSNHqnD.d.ts → spending-policy-DKZN3Sg8.d.ts} +3 -2
  34. package/dist/{spending-policy-DqBRDUxx.d.cts → spending-policy-DaajDg9B.d.cts} +3 -2
  35. package/dist/x402/index.cjs +9 -6
  36. package/dist/x402/index.cjs.map +1 -1
  37. package/dist/x402/index.d.cts +2 -2
  38. package/dist/x402/index.d.ts +2 -2
  39. package/dist/x402/index.js +2 -2
  40. package/package.json +1 -1
  41. package/dist/asset-domain-CpJuDkI2.d.cts +0 -102
  42. package/dist/asset-domain-CpJuDkI2.d.ts +0 -102
  43. package/dist/chunk-E2EG72U2.js.map +0 -1
  44. package/dist/chunk-RUWCCP37.js.map +0 -1
  45. package/dist/chunk-VPRR3TNA.js.map +0 -1
  46. package/dist/chunk-YMABXRCK.js.map +0 -1
@@ -0,0 +1,348 @@
1
+ import { Address, Hex, Account } from 'viem';
2
+
3
+ /**
4
+ * EIP-3009 typed-data builders and signing helpers.
5
+ *
6
+ * Token-agnostic: works for any EIP-3009-compliant token (JPYC, USDC, USDP,
7
+ * Centre FiatToken family). Pure off-chain construction — no chain RPC, no
8
+ * submission. Submission is the caller's job (M3 x402 flow, or arbitrary
9
+ * gas-paying relayer).
10
+ *
11
+ * @packageDocumentation
12
+ */
13
+
14
+ /**
15
+ * EIP-712 domain for an EIP-3009-compliant token.
16
+ *
17
+ * `name` and `version` MUST match the values the token used when computing
18
+ * its `DOMAIN_SEPARATOR`. For JPYC see {@link JPYC_EIP712_DOMAIN_HINT}.
19
+ */
20
+ interface Eip3009Domain {
21
+ readonly name: string;
22
+ readonly version: string;
23
+ readonly chainId: number;
24
+ readonly verifyingContract: Address;
25
+ }
26
+ /** Message body for {@link signTransferWithAuthorization}. */
27
+ interface TransferWithAuthorizationMessage {
28
+ readonly from: Address;
29
+ readonly to: Address;
30
+ readonly value: bigint;
31
+ readonly validAfter: bigint;
32
+ readonly validBefore: bigint;
33
+ /** 32-byte random nonce. Generate with {@link generateAuthorizationNonce}. */
34
+ readonly nonce: Hex;
35
+ }
36
+ /** Message body for {@link signReceiveWithAuthorization}. */
37
+ type ReceiveWithAuthorizationMessage = TransferWithAuthorizationMessage;
38
+ /** Message body for {@link signCancelAuthorization}. */
39
+ interface CancelAuthorizationMessage {
40
+ readonly authorizer: Address;
41
+ readonly nonce: Hex;
42
+ }
43
+ /**
44
+ * A signed EIP-3009 authorization, ready to be passed to the token's
45
+ * `*WithAuthorization` entrypoint as `(v, r, s)`.
46
+ */
47
+ interface SignedAuthorization<TMessage> {
48
+ readonly signature: Hex;
49
+ readonly v: number;
50
+ readonly r: Hex;
51
+ readonly s: Hex;
52
+ readonly domain: Eip3009Domain;
53
+ readonly message: TMessage;
54
+ }
55
+ /**
56
+ * Canonical EIP-712 `TransferWithAuthorization` type definition.
57
+ *
58
+ * This is the **single source of truth** for the typed-data structure (field
59
+ * names, types, and order) that EIP-3009 hashes and `ecrecover` verifies.
60
+ * Exported so out-of-process / cross-language consumers — notably the `mpc-2p`
61
+ * co-signer backend (RFC M6-1 §4.5, H1) — bind to this exact definition (or
62
+ * codegen from it) instead of re-declaring it, and so the digest the policy
63
+ * gates on is provably the digest the chain verifies (see the digest-conformance
64
+ * corpus in `__fixtures__/eip3009-digest.vectors.json`).
65
+ */
66
+ declare const transferWithAuthorizationTypes: {
67
+ readonly TransferWithAuthorization: readonly [{
68
+ readonly name: "from";
69
+ readonly type: "address";
70
+ }, {
71
+ readonly name: "to";
72
+ readonly type: "address";
73
+ }, {
74
+ readonly name: "value";
75
+ readonly type: "uint256";
76
+ }, {
77
+ readonly name: "validAfter";
78
+ readonly type: "uint256";
79
+ }, {
80
+ readonly name: "validBefore";
81
+ readonly type: "uint256";
82
+ }, {
83
+ readonly name: "nonce";
84
+ readonly type: "bytes32";
85
+ }];
86
+ };
87
+ /** Canonical EIP-712 `ReceiveWithAuthorization` types. See {@link transferWithAuthorizationTypes}. */
88
+ declare const receiveWithAuthorizationTypes: {
89
+ readonly ReceiveWithAuthorization: readonly [{
90
+ readonly name: "from";
91
+ readonly type: "address";
92
+ }, {
93
+ readonly name: "to";
94
+ readonly type: "address";
95
+ }, {
96
+ readonly name: "value";
97
+ readonly type: "uint256";
98
+ }, {
99
+ readonly name: "validAfter";
100
+ readonly type: "uint256";
101
+ }, {
102
+ readonly name: "validBefore";
103
+ readonly type: "uint256";
104
+ }, {
105
+ readonly name: "nonce";
106
+ readonly type: "bytes32";
107
+ }];
108
+ };
109
+ /** Canonical EIP-712 `CancelAuthorization` types. See {@link transferWithAuthorizationTypes}. */
110
+ declare const cancelAuthorizationTypes: {
111
+ readonly CancelAuthorization: readonly [{
112
+ readonly name: "authorizer";
113
+ readonly type: "address";
114
+ }, {
115
+ readonly name: "nonce";
116
+ readonly type: "bytes32";
117
+ }];
118
+ };
119
+ /**
120
+ * Generates a cryptographically random 32-byte EIP-3009 nonce.
121
+ *
122
+ * The nonce only needs to be unique per `(authorizer, contract)` — duplicates
123
+ * across different tokens are harmless because the contract scopes them.
124
+ *
125
+ * @example
126
+ * ```ts
127
+ * import { generateAuthorizationNonce } from "kawasekit";
128
+ *
129
+ * const nonce = generateAuthorizationNonce();
130
+ * ```
131
+ */
132
+ declare function generateAuthorizationNonce(): Hex;
133
+ /**
134
+ * Derives a **deterministic** 32-byte EIP-3009 nonce from a reasoning-step
135
+ * idempotency key, scoped to `(from, verifyingContract, chainId)` so the same
136
+ * key never collides across tokens or chains (M5-1, Half B).
137
+ *
138
+ * `nonce = keccak256(DOMAIN_TAG ‖ idempotencyKey ‖ from ‖ verifyingContract ‖
139
+ * chainId)`. **No shared secret**: determinism across replicas / sub-agents
140
+ * needs only a shared `conversationId` (the source of the key), not secret
141
+ * distribution. A replayed key ⇒ identical nonce ⇒ the token contract's
142
+ * `authorizationState` rejects the second settlement — the on-chain last line of
143
+ * defence against re-signed same-intent duplicate payments. Use in place of
144
+ * {@link generateAuthorizationNonce} only when a key is available.
145
+ *
146
+ * `chainId` is in the preimage, so the same JPYC address on Polygon / Avalanche
147
+ * / Kaia / Ethereum yields distinct nonces (cross-chain replay safety).
148
+ *
149
+ * @example
150
+ * ```ts
151
+ * import { deriveAuthorizationNonce } from "kawasekit";
152
+ *
153
+ * const nonce = deriveAuthorizationNonce(
154
+ * { idempotencyKey },
155
+ * { from: account.address, verifyingContract, chainId },
156
+ * );
157
+ * ```
158
+ */
159
+ declare function deriveAuthorizationNonce(input: {
160
+ readonly idempotencyKey: string;
161
+ }, scope: {
162
+ readonly from: Address;
163
+ readonly verifyingContract: Address;
164
+ readonly chainId: number;
165
+ }): Hex;
166
+ /**
167
+ * Returns a `validBefore` UNIX timestamp `seconds` in the future.
168
+ *
169
+ * @param seconds - Lifetime of the authorization, in seconds.
170
+ * @param nowSec - Optional override of "now" (defaults to {@link Date.now}).
171
+ *
172
+ * @example
173
+ * ```ts
174
+ * import { authorizationDeadlineFromNow } from "kawasekit";
175
+ *
176
+ * const validBefore = authorizationDeadlineFromNow(60 * 5); // 5 minutes
177
+ * ```
178
+ */
179
+ declare function authorizationDeadlineFromNow(seconds: number, nowSec?: bigint): bigint;
180
+ /**
181
+ * Signs an EIP-3009 `TransferWithAuthorization` message.
182
+ *
183
+ * The signing account MUST equal `message.from` — EIP-3009 rejects signatures
184
+ * from anyone else (the on-chain check is pure `ecrecover` against `from`).
185
+ *
186
+ * @example
187
+ * ```ts
188
+ * import { privateKeyToAccount } from "viem/accounts";
189
+ * import {
190
+ * authorizationDeadlineFromNow,
191
+ * generateAuthorizationNonce,
192
+ * JPYC_EIP712_DOMAIN_HINT,
193
+ * polygon,
194
+ * signTransferWithAuthorization,
195
+ * } from "kawasekit";
196
+ *
197
+ * const account = privateKeyToAccount("0x...");
198
+ * const signed = await signTransferWithAuthorization(account, {
199
+ * ...JPYC_EIP712_DOMAIN_HINT,
200
+ * chainId: polygon.id,
201
+ * verifyingContract: "0xE7C3D8C9a439feDe00D2600032D5dB0Be71C3c29",
202
+ * }, {
203
+ * from: account.address,
204
+ * to: "0xBeef...",
205
+ * value: 100n * 10n ** 18n,
206
+ * validAfter: 0n,
207
+ * validBefore: authorizationDeadlineFromNow(300),
208
+ * nonce: generateAuthorizationNonce(),
209
+ * });
210
+ * // → submit (v, r, s) to token.transferWithAuthorization(...)
211
+ * ```
212
+ */
213
+ declare function signTransferWithAuthorization(account: Account, domain: Eip3009Domain, message: TransferWithAuthorizationMessage): Promise<SignedAuthorization<TransferWithAuthorizationMessage>>;
214
+ /**
215
+ * Signs an EIP-3009 `ReceiveWithAuthorization` message.
216
+ *
217
+ * Differs from {@link signTransferWithAuthorization} in two ways:
218
+ * 1. Uses the `ReceiveWithAuthorization` EIP-712 type.
219
+ * 2. The contract additionally enforces `msg.sender == to` at submission
220
+ * time, so only `to` (or a relayer impersonating `to` — impossible in
221
+ * practice) can land the tx.
222
+ */
223
+ declare function signReceiveWithAuthorization(account: Account, domain: Eip3009Domain, message: ReceiveWithAuthorizationMessage): Promise<SignedAuthorization<ReceiveWithAuthorizationMessage>>;
224
+ /**
225
+ * Signs an EIP-3009 `CancelAuthorization` message.
226
+ *
227
+ * Cancelling consumes the nonce so a later `transferWithAuthorization` or
228
+ * `receiveWithAuthorization` with the same nonce will revert.
229
+ */
230
+ declare function signCancelAuthorization(account: Account, domain: Eip3009Domain, message: CancelAuthorizationMessage): Promise<SignedAuthorization<CancelAuthorizationMessage>>;
231
+
232
+ /**
233
+ * Known-asset registry for {@link createX402PaymentSigner}'s
234
+ * `asset: { kind: "known", id }` discriminated-union branch.
235
+ *
236
+ * kawasekit only ships pinned EIP-712 domain definitions for assets it has
237
+ * verified empirically against the deployed contracts. Adding a new entry
238
+ * here requires citing the source-file + line reference for the contract
239
+ * that owns the `name` / `version` (so the next reviewer can spot-check the
240
+ * claim, the same discipline `docs/THREAT_MODEL.md` §0 demands of any ✅
241
+ * verdict that delegates to an out-of-scope component).
242
+ *
243
+ * @packageDocumentation
244
+ */
245
+
246
+ /** Known asset identifiers. New entries must update this union AND the table. */
247
+ type KnownAssetId = "jpyc-v2";
248
+ /** Fully-pinned EIP-712 domain for a known asset. */
249
+ interface KnownAssetDomain {
250
+ readonly id: KnownAssetId;
251
+ readonly name: string;
252
+ readonly version: string;
253
+ readonly verifyingContract: Address;
254
+ }
255
+ /**
256
+ * Look up a known asset's pinned EIP-712 domain by id.
257
+ *
258
+ * @returns The domain, or `undefined` if the id is not in the registry.
259
+ *
260
+ * @example
261
+ * ```ts
262
+ * import { getKnownAssetDomain } from "kawasekit";
263
+ *
264
+ * const jpyc = getKnownAssetDomain("jpyc-v2");
265
+ * if (jpyc === undefined) throw new Error("unreachable");
266
+ * console.log(jpyc.verifyingContract); // 0xE7C3D8C9a439feDe00D2600032D5dB0Be71C3c29
267
+ * ```
268
+ */
269
+ declare function getKnownAssetDomain(id: KnownAssetId): KnownAssetDomain | undefined;
270
+ /** List every known asset id (for diagnostics / error messages). */
271
+ declare function listKnownAssetIds(): readonly KnownAssetId[];
272
+
273
+ /**
274
+ * EIP-712 asset-domain resolution for x402 / EIP-3009 signing.
275
+ *
276
+ * Construction-time pinning of the EIP-712 domain (`name` / `version` /
277
+ * `verifyingContract`) a signer will use. The integrator declares an
278
+ * {@link X402AssetParam} — either a kawasekit-maintained `known` asset or a
279
+ * loud `unsafeOverride` — and {@link resolveAssetParam} resolves it to a pinned
280
+ * {@link ResolvedAsset}. The signer then trusts only this pinned domain and
281
+ * refuses to sign for a mismatched advertised asset (Threat 1.4: misadvertised
282
+ * EIP-712 domain).
283
+ *
284
+ * Token-domain concern, reused by both the x402 signer (`src/x402/client.ts`)
285
+ * and the M6 PolicyGatedSigner (`src/signer/`).
286
+ *
287
+ * @packageDocumentation
288
+ */
289
+
290
+ /** EIP-712 token domain `name` / `version` pair. */
291
+ interface X402TokenDomain {
292
+ readonly name: string;
293
+ readonly version: string;
294
+ }
295
+ /**
296
+ * Asset binding for {@link createX402PaymentSigner} and the M6 PolicyGatedSigner.
297
+ * Required, discriminated.
298
+ *
299
+ * **Default-on whitelist**: integrators MUST declare which asset they intend
300
+ * to sign for. The `known` branch references a kawasekit-maintained
301
+ * whitelist (see `src/tokens/known-assets.ts`); the `unsafeOverride` branch
302
+ * is the deliberate escape hatch for any other asset and is named loudly so
303
+ * it survives a code review. Either way, the signer pins the EIP-712 domain
304
+ * at construction time and refuses to sign if `paymentRequirements.asset`
305
+ * disagrees with the pinned `verifyingContract`.
306
+ *
307
+ * Closes Threat 1.4 (misadvertised EIP-712 domain): the server's advertised
308
+ * `extra.name` / `extra.version` and `asset` are all ignored for signing
309
+ * purposes — the signer trusts only what the integrator declared here.
310
+ */
311
+ type X402AssetParam = {
312
+ /** Use a kawasekit-maintained pinned EIP-712 domain. */
313
+ readonly kind: "known";
314
+ /** The asset id to pin. See {@link KnownAssetId} for the registry. */
315
+ readonly id: KnownAssetId;
316
+ } | {
317
+ /**
318
+ * Use a caller-supplied EIP-712 domain for an asset NOT on the
319
+ * kawasekit whitelist. The name is deliberately loud — pick this
320
+ * branch only when you have separately audited the contract and its
321
+ * `eip712Domain()` output.
322
+ */
323
+ readonly kind: "unsafeOverride";
324
+ readonly domain: {
325
+ readonly name: string;
326
+ readonly version: string;
327
+ readonly verifyingContract: Address;
328
+ };
329
+ };
330
+ /** Construction-time resolution of an {@link X402AssetParam} to a pinned domain. */
331
+ interface ResolvedAsset {
332
+ readonly name: string;
333
+ readonly version: string;
334
+ readonly verifyingContract: Address;
335
+ }
336
+ /**
337
+ * Assemble the EIP-712 {@link Eip3009Domain} from a construction-time pinned
338
+ * {@link ResolvedAsset} and the runtime `chainId`.
339
+ *
340
+ * The single place that maps `(pinned asset, chainId) -> domain`, so every
341
+ * signing path (`src/x402/client.ts`, `src/signer/`) builds the domain
342
+ * identically — the domain half of the EIP-712 single-source-of-truth the
343
+ * `mpc-2p` backend relies on (RFC M6-1 §4.5, H1). `name` / `version` /
344
+ * `verifyingContract` come from the pinned asset; only `chainId` is per-request.
345
+ */
346
+ declare function resolvedAssetToEip3009Domain(asset: ResolvedAsset, chainId: number): Eip3009Domain;
347
+
348
+ export { type CancelAuthorizationMessage as C, type Eip3009Domain as E, type KnownAssetDomain as K, type ReceiveWithAuthorizationMessage as R, type SignedAuthorization as S, type TransferWithAuthorizationMessage as T, type X402AssetParam as X, type KnownAssetId as a, type ResolvedAsset as b, type X402TokenDomain as c, authorizationDeadlineFromNow as d, cancelAuthorizationTypes as e, deriveAuthorizationNonce as f, generateAuthorizationNonce as g, getKnownAssetDomain as h, resolvedAssetToEip3009Domain as i, signReceiveWithAuthorization as j, signTransferWithAuthorization as k, listKnownAssetIds as l, receiveWithAuthorizationTypes as r, signCancelAuthorization as s, transferWithAuthorizationTypes as t };
@@ -0,0 +1,348 @@
1
+ import { Address, Hex, Account } from 'viem';
2
+
3
+ /**
4
+ * EIP-3009 typed-data builders and signing helpers.
5
+ *
6
+ * Token-agnostic: works for any EIP-3009-compliant token (JPYC, USDC, USDP,
7
+ * Centre FiatToken family). Pure off-chain construction — no chain RPC, no
8
+ * submission. Submission is the caller's job (M3 x402 flow, or arbitrary
9
+ * gas-paying relayer).
10
+ *
11
+ * @packageDocumentation
12
+ */
13
+
14
+ /**
15
+ * EIP-712 domain for an EIP-3009-compliant token.
16
+ *
17
+ * `name` and `version` MUST match the values the token used when computing
18
+ * its `DOMAIN_SEPARATOR`. For JPYC see {@link JPYC_EIP712_DOMAIN_HINT}.
19
+ */
20
+ interface Eip3009Domain {
21
+ readonly name: string;
22
+ readonly version: string;
23
+ readonly chainId: number;
24
+ readonly verifyingContract: Address;
25
+ }
26
+ /** Message body for {@link signTransferWithAuthorization}. */
27
+ interface TransferWithAuthorizationMessage {
28
+ readonly from: Address;
29
+ readonly to: Address;
30
+ readonly value: bigint;
31
+ readonly validAfter: bigint;
32
+ readonly validBefore: bigint;
33
+ /** 32-byte random nonce. Generate with {@link generateAuthorizationNonce}. */
34
+ readonly nonce: Hex;
35
+ }
36
+ /** Message body for {@link signReceiveWithAuthorization}. */
37
+ type ReceiveWithAuthorizationMessage = TransferWithAuthorizationMessage;
38
+ /** Message body for {@link signCancelAuthorization}. */
39
+ interface CancelAuthorizationMessage {
40
+ readonly authorizer: Address;
41
+ readonly nonce: Hex;
42
+ }
43
+ /**
44
+ * A signed EIP-3009 authorization, ready to be passed to the token's
45
+ * `*WithAuthorization` entrypoint as `(v, r, s)`.
46
+ */
47
+ interface SignedAuthorization<TMessage> {
48
+ readonly signature: Hex;
49
+ readonly v: number;
50
+ readonly r: Hex;
51
+ readonly s: Hex;
52
+ readonly domain: Eip3009Domain;
53
+ readonly message: TMessage;
54
+ }
55
+ /**
56
+ * Canonical EIP-712 `TransferWithAuthorization` type definition.
57
+ *
58
+ * This is the **single source of truth** for the typed-data structure (field
59
+ * names, types, and order) that EIP-3009 hashes and `ecrecover` verifies.
60
+ * Exported so out-of-process / cross-language consumers — notably the `mpc-2p`
61
+ * co-signer backend (RFC M6-1 §4.5, H1) — bind to this exact definition (or
62
+ * codegen from it) instead of re-declaring it, and so the digest the policy
63
+ * gates on is provably the digest the chain verifies (see the digest-conformance
64
+ * corpus in `__fixtures__/eip3009-digest.vectors.json`).
65
+ */
66
+ declare const transferWithAuthorizationTypes: {
67
+ readonly TransferWithAuthorization: readonly [{
68
+ readonly name: "from";
69
+ readonly type: "address";
70
+ }, {
71
+ readonly name: "to";
72
+ readonly type: "address";
73
+ }, {
74
+ readonly name: "value";
75
+ readonly type: "uint256";
76
+ }, {
77
+ readonly name: "validAfter";
78
+ readonly type: "uint256";
79
+ }, {
80
+ readonly name: "validBefore";
81
+ readonly type: "uint256";
82
+ }, {
83
+ readonly name: "nonce";
84
+ readonly type: "bytes32";
85
+ }];
86
+ };
87
+ /** Canonical EIP-712 `ReceiveWithAuthorization` types. See {@link transferWithAuthorizationTypes}. */
88
+ declare const receiveWithAuthorizationTypes: {
89
+ readonly ReceiveWithAuthorization: readonly [{
90
+ readonly name: "from";
91
+ readonly type: "address";
92
+ }, {
93
+ readonly name: "to";
94
+ readonly type: "address";
95
+ }, {
96
+ readonly name: "value";
97
+ readonly type: "uint256";
98
+ }, {
99
+ readonly name: "validAfter";
100
+ readonly type: "uint256";
101
+ }, {
102
+ readonly name: "validBefore";
103
+ readonly type: "uint256";
104
+ }, {
105
+ readonly name: "nonce";
106
+ readonly type: "bytes32";
107
+ }];
108
+ };
109
+ /** Canonical EIP-712 `CancelAuthorization` types. See {@link transferWithAuthorizationTypes}. */
110
+ declare const cancelAuthorizationTypes: {
111
+ readonly CancelAuthorization: readonly [{
112
+ readonly name: "authorizer";
113
+ readonly type: "address";
114
+ }, {
115
+ readonly name: "nonce";
116
+ readonly type: "bytes32";
117
+ }];
118
+ };
119
+ /**
120
+ * Generates a cryptographically random 32-byte EIP-3009 nonce.
121
+ *
122
+ * The nonce only needs to be unique per `(authorizer, contract)` — duplicates
123
+ * across different tokens are harmless because the contract scopes them.
124
+ *
125
+ * @example
126
+ * ```ts
127
+ * import { generateAuthorizationNonce } from "kawasekit";
128
+ *
129
+ * const nonce = generateAuthorizationNonce();
130
+ * ```
131
+ */
132
+ declare function generateAuthorizationNonce(): Hex;
133
+ /**
134
+ * Derives a **deterministic** 32-byte EIP-3009 nonce from a reasoning-step
135
+ * idempotency key, scoped to `(from, verifyingContract, chainId)` so the same
136
+ * key never collides across tokens or chains (M5-1, Half B).
137
+ *
138
+ * `nonce = keccak256(DOMAIN_TAG ‖ idempotencyKey ‖ from ‖ verifyingContract ‖
139
+ * chainId)`. **No shared secret**: determinism across replicas / sub-agents
140
+ * needs only a shared `conversationId` (the source of the key), not secret
141
+ * distribution. A replayed key ⇒ identical nonce ⇒ the token contract's
142
+ * `authorizationState` rejects the second settlement — the on-chain last line of
143
+ * defence against re-signed same-intent duplicate payments. Use in place of
144
+ * {@link generateAuthorizationNonce} only when a key is available.
145
+ *
146
+ * `chainId` is in the preimage, so the same JPYC address on Polygon / Avalanche
147
+ * / Kaia / Ethereum yields distinct nonces (cross-chain replay safety).
148
+ *
149
+ * @example
150
+ * ```ts
151
+ * import { deriveAuthorizationNonce } from "kawasekit";
152
+ *
153
+ * const nonce = deriveAuthorizationNonce(
154
+ * { idempotencyKey },
155
+ * { from: account.address, verifyingContract, chainId },
156
+ * );
157
+ * ```
158
+ */
159
+ declare function deriveAuthorizationNonce(input: {
160
+ readonly idempotencyKey: string;
161
+ }, scope: {
162
+ readonly from: Address;
163
+ readonly verifyingContract: Address;
164
+ readonly chainId: number;
165
+ }): Hex;
166
+ /**
167
+ * Returns a `validBefore` UNIX timestamp `seconds` in the future.
168
+ *
169
+ * @param seconds - Lifetime of the authorization, in seconds.
170
+ * @param nowSec - Optional override of "now" (defaults to {@link Date.now}).
171
+ *
172
+ * @example
173
+ * ```ts
174
+ * import { authorizationDeadlineFromNow } from "kawasekit";
175
+ *
176
+ * const validBefore = authorizationDeadlineFromNow(60 * 5); // 5 minutes
177
+ * ```
178
+ */
179
+ declare function authorizationDeadlineFromNow(seconds: number, nowSec?: bigint): bigint;
180
+ /**
181
+ * Signs an EIP-3009 `TransferWithAuthorization` message.
182
+ *
183
+ * The signing account MUST equal `message.from` — EIP-3009 rejects signatures
184
+ * from anyone else (the on-chain check is pure `ecrecover` against `from`).
185
+ *
186
+ * @example
187
+ * ```ts
188
+ * import { privateKeyToAccount } from "viem/accounts";
189
+ * import {
190
+ * authorizationDeadlineFromNow,
191
+ * generateAuthorizationNonce,
192
+ * JPYC_EIP712_DOMAIN_HINT,
193
+ * polygon,
194
+ * signTransferWithAuthorization,
195
+ * } from "kawasekit";
196
+ *
197
+ * const account = privateKeyToAccount("0x...");
198
+ * const signed = await signTransferWithAuthorization(account, {
199
+ * ...JPYC_EIP712_DOMAIN_HINT,
200
+ * chainId: polygon.id,
201
+ * verifyingContract: "0xE7C3D8C9a439feDe00D2600032D5dB0Be71C3c29",
202
+ * }, {
203
+ * from: account.address,
204
+ * to: "0xBeef...",
205
+ * value: 100n * 10n ** 18n,
206
+ * validAfter: 0n,
207
+ * validBefore: authorizationDeadlineFromNow(300),
208
+ * nonce: generateAuthorizationNonce(),
209
+ * });
210
+ * // → submit (v, r, s) to token.transferWithAuthorization(...)
211
+ * ```
212
+ */
213
+ declare function signTransferWithAuthorization(account: Account, domain: Eip3009Domain, message: TransferWithAuthorizationMessage): Promise<SignedAuthorization<TransferWithAuthorizationMessage>>;
214
+ /**
215
+ * Signs an EIP-3009 `ReceiveWithAuthorization` message.
216
+ *
217
+ * Differs from {@link signTransferWithAuthorization} in two ways:
218
+ * 1. Uses the `ReceiveWithAuthorization` EIP-712 type.
219
+ * 2. The contract additionally enforces `msg.sender == to` at submission
220
+ * time, so only `to` (or a relayer impersonating `to` — impossible in
221
+ * practice) can land the tx.
222
+ */
223
+ declare function signReceiveWithAuthorization(account: Account, domain: Eip3009Domain, message: ReceiveWithAuthorizationMessage): Promise<SignedAuthorization<ReceiveWithAuthorizationMessage>>;
224
+ /**
225
+ * Signs an EIP-3009 `CancelAuthorization` message.
226
+ *
227
+ * Cancelling consumes the nonce so a later `transferWithAuthorization` or
228
+ * `receiveWithAuthorization` with the same nonce will revert.
229
+ */
230
+ declare function signCancelAuthorization(account: Account, domain: Eip3009Domain, message: CancelAuthorizationMessage): Promise<SignedAuthorization<CancelAuthorizationMessage>>;
231
+
232
+ /**
233
+ * Known-asset registry for {@link createX402PaymentSigner}'s
234
+ * `asset: { kind: "known", id }` discriminated-union branch.
235
+ *
236
+ * kawasekit only ships pinned EIP-712 domain definitions for assets it has
237
+ * verified empirically against the deployed contracts. Adding a new entry
238
+ * here requires citing the source-file + line reference for the contract
239
+ * that owns the `name` / `version` (so the next reviewer can spot-check the
240
+ * claim, the same discipline `docs/THREAT_MODEL.md` §0 demands of any ✅
241
+ * verdict that delegates to an out-of-scope component).
242
+ *
243
+ * @packageDocumentation
244
+ */
245
+
246
+ /** Known asset identifiers. New entries must update this union AND the table. */
247
+ type KnownAssetId = "jpyc-v2";
248
+ /** Fully-pinned EIP-712 domain for a known asset. */
249
+ interface KnownAssetDomain {
250
+ readonly id: KnownAssetId;
251
+ readonly name: string;
252
+ readonly version: string;
253
+ readonly verifyingContract: Address;
254
+ }
255
+ /**
256
+ * Look up a known asset's pinned EIP-712 domain by id.
257
+ *
258
+ * @returns The domain, or `undefined` if the id is not in the registry.
259
+ *
260
+ * @example
261
+ * ```ts
262
+ * import { getKnownAssetDomain } from "kawasekit";
263
+ *
264
+ * const jpyc = getKnownAssetDomain("jpyc-v2");
265
+ * if (jpyc === undefined) throw new Error("unreachable");
266
+ * console.log(jpyc.verifyingContract); // 0xE7C3D8C9a439feDe00D2600032D5dB0Be71C3c29
267
+ * ```
268
+ */
269
+ declare function getKnownAssetDomain(id: KnownAssetId): KnownAssetDomain | undefined;
270
+ /** List every known asset id (for diagnostics / error messages). */
271
+ declare function listKnownAssetIds(): readonly KnownAssetId[];
272
+
273
+ /**
274
+ * EIP-712 asset-domain resolution for x402 / EIP-3009 signing.
275
+ *
276
+ * Construction-time pinning of the EIP-712 domain (`name` / `version` /
277
+ * `verifyingContract`) a signer will use. The integrator declares an
278
+ * {@link X402AssetParam} — either a kawasekit-maintained `known` asset or a
279
+ * loud `unsafeOverride` — and {@link resolveAssetParam} resolves it to a pinned
280
+ * {@link ResolvedAsset}. The signer then trusts only this pinned domain and
281
+ * refuses to sign for a mismatched advertised asset (Threat 1.4: misadvertised
282
+ * EIP-712 domain).
283
+ *
284
+ * Token-domain concern, reused by both the x402 signer (`src/x402/client.ts`)
285
+ * and the M6 PolicyGatedSigner (`src/signer/`).
286
+ *
287
+ * @packageDocumentation
288
+ */
289
+
290
+ /** EIP-712 token domain `name` / `version` pair. */
291
+ interface X402TokenDomain {
292
+ readonly name: string;
293
+ readonly version: string;
294
+ }
295
+ /**
296
+ * Asset binding for {@link createX402PaymentSigner} and the M6 PolicyGatedSigner.
297
+ * Required, discriminated.
298
+ *
299
+ * **Default-on whitelist**: integrators MUST declare which asset they intend
300
+ * to sign for. The `known` branch references a kawasekit-maintained
301
+ * whitelist (see `src/tokens/known-assets.ts`); the `unsafeOverride` branch
302
+ * is the deliberate escape hatch for any other asset and is named loudly so
303
+ * it survives a code review. Either way, the signer pins the EIP-712 domain
304
+ * at construction time and refuses to sign if `paymentRequirements.asset`
305
+ * disagrees with the pinned `verifyingContract`.
306
+ *
307
+ * Closes Threat 1.4 (misadvertised EIP-712 domain): the server's advertised
308
+ * `extra.name` / `extra.version` and `asset` are all ignored for signing
309
+ * purposes — the signer trusts only what the integrator declared here.
310
+ */
311
+ type X402AssetParam = {
312
+ /** Use a kawasekit-maintained pinned EIP-712 domain. */
313
+ readonly kind: "known";
314
+ /** The asset id to pin. See {@link KnownAssetId} for the registry. */
315
+ readonly id: KnownAssetId;
316
+ } | {
317
+ /**
318
+ * Use a caller-supplied EIP-712 domain for an asset NOT on the
319
+ * kawasekit whitelist. The name is deliberately loud — pick this
320
+ * branch only when you have separately audited the contract and its
321
+ * `eip712Domain()` output.
322
+ */
323
+ readonly kind: "unsafeOverride";
324
+ readonly domain: {
325
+ readonly name: string;
326
+ readonly version: string;
327
+ readonly verifyingContract: Address;
328
+ };
329
+ };
330
+ /** Construction-time resolution of an {@link X402AssetParam} to a pinned domain. */
331
+ interface ResolvedAsset {
332
+ readonly name: string;
333
+ readonly version: string;
334
+ readonly verifyingContract: Address;
335
+ }
336
+ /**
337
+ * Assemble the EIP-712 {@link Eip3009Domain} from a construction-time pinned
338
+ * {@link ResolvedAsset} and the runtime `chainId`.
339
+ *
340
+ * The single place that maps `(pinned asset, chainId) -> domain`, so every
341
+ * signing path (`src/x402/client.ts`, `src/signer/`) builds the domain
342
+ * identically — the domain half of the EIP-712 single-source-of-truth the
343
+ * `mpc-2p` backend relies on (RFC M6-1 §4.5, H1). `name` / `version` /
344
+ * `verifyingContract` come from the pinned asset; only `chainId` is per-request.
345
+ */
346
+ declare function resolvedAssetToEip3009Domain(asset: ResolvedAsset, chainId: number): Eip3009Domain;
347
+
348
+ export { type CancelAuthorizationMessage as C, type Eip3009Domain as E, type KnownAssetDomain as K, type ReceiveWithAuthorizationMessage as R, type SignedAuthorization as S, type TransferWithAuthorizationMessage as T, type X402AssetParam as X, type KnownAssetId as a, type ResolvedAsset as b, type X402TokenDomain as c, authorizationDeadlineFromNow as d, cancelAuthorizationTypes as e, deriveAuthorizationNonce as f, generateAuthorizationNonce as g, getKnownAssetDomain as h, resolvedAssetToEip3009Domain as i, signReceiveWithAuthorization as j, signTransferWithAuthorization as k, listKnownAssetIds as l, receiveWithAuthorizationTypes as r, signCancelAuthorization as s, transferWithAuthorizationTypes as t };