kawasekit 0.1.0-beta.3 → 0.1.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -26
- package/dist/{chunk-6G345P2I.js → chunk-DGWKPDDQ.js} +4 -4
- package/dist/{chunk-6G345P2I.js.map → chunk-DGWKPDDQ.js.map} +1 -1
- package/dist/{chunk-KWCPYGFE.js → chunk-N3CVLISJ.js} +3 -3
- package/dist/{chunk-KWCPYGFE.js.map → chunk-N3CVLISJ.js.map} +1 -1
- package/dist/{chunk-CD6SQBZN.js → chunk-NRGSI52C.js} +12 -5
- package/dist/{chunk-CD6SQBZN.js.map → chunk-NRGSI52C.js.map} +1 -1
- package/dist/chunk-QHUCU5YX.js +179 -0
- package/dist/chunk-QHUCU5YX.js.map +1 -0
- package/dist/chunk-SOTYGX67.js +95 -0
- package/dist/chunk-SOTYGX67.js.map +1 -0
- package/dist/chunk-TTX3RBIZ.js +159 -0
- package/dist/chunk-TTX3RBIZ.js.map +1 -0
- package/dist/{chunk-2V3W4B64.js → chunk-Y6AJKMAL.js} +15 -9
- package/dist/chunk-Y6AJKMAL.js.map +1 -0
- package/dist/cli/index.cjs +66 -9
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +8 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/idempotency/index.cjs +52 -3
- package/dist/idempotency/index.cjs.map +1 -1
- package/dist/idempotency/index.d.cts +3 -3
- package/dist/idempotency/index.d.ts +3 -3
- package/dist/idempotency/index.js +3 -2
- package/dist/{chunk-WMFCI6KC.js → idempotency/redis/index.cjs} +136 -130
- package/dist/idempotency/redis/index.cjs.map +1 -0
- package/dist/idempotency/redis/index.d.cts +83 -0
- package/dist/idempotency/redis/index.d.ts +83 -0
- package/dist/idempotency/redis/index.js +105 -0
- package/dist/idempotency/redis/index.js.map +1 -0
- package/dist/index-2fEOL83n.d.cts +472 -0
- package/dist/index-2fEOL83n.d.ts +472 -0
- package/dist/{index-NdNKNnZP.d.cts → index-CGO7bOx5.d.cts} +88 -5
- package/dist/{index-kqH78Yms.d.ts → index-CJfDUtpx.d.ts} +88 -5
- package/dist/{index-CykLOgYD.d.ts → index-CSpNGigO.d.ts} +1 -1
- package/dist/{index-DzveM0RN.d.cts → index-DFChv_fT.d.cts} +1 -1
- package/dist/index.cjs +81 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +360 -41
- package/dist/index.d.ts +360 -41
- package/dist/index.js +7 -6
- package/dist/observability/index.d.cts +2 -2
- package/dist/observability/index.d.ts +2 -2
- package/dist/observability/otlp/index.d.cts +2 -2
- package/dist/observability/otlp/index.d.ts +2 -2
- package/dist/observability/prometheus/index.d.cts +2 -2
- package/dist/observability/prometheus/index.d.ts +2 -2
- package/dist/{server-CSpATNiH.d.ts → server-D_rZc-cW.d.ts} +2 -2
- package/dist/{server-BMeg_hNB.d.cts → server-ov8YstNS.d.cts} +2 -2
- package/dist/session/index.cjs +52 -3
- package/dist/session/index.cjs.map +1 -1
- package/dist/session/index.d.cts +2 -2
- package/dist/session/index.d.ts +2 -2
- package/dist/session/index.js +2 -2
- package/dist/{store-BY16tCbe.d.cts → store-DPOLS6yp.d.cts} +1 -1
- package/dist/{store-Bd-91QL0.d.ts → store-DmdoV3Ii.d.ts} +1 -1
- package/dist/{types-DwFfT4E7.d.ts → types-BR9UcvJO.d.ts} +1 -1
- package/dist/{types-A_WwFpcv.d.cts → types-TpS_8ztt.d.cts} +1 -1
- package/dist/x402/hono/index.d.cts +4 -4
- package/dist/x402/hono/index.d.ts +4 -4
- package/dist/x402/hono/index.js +4 -3
- package/dist/x402/hono/index.js.map +1 -1
- package/dist/x402/index.cjs +69 -7
- package/dist/x402/index.cjs.map +1 -1
- package/dist/x402/index.d.cts +5 -5
- package/dist/x402/index.d.ts +5 -5
- package/dist/x402/index.js +5 -4
- package/package.json +12 -1
- package/dist/chunk-2V3W4B64.js.map +0 -1
- package/dist/chunk-SA7LMQFG.js +0 -44
- package/dist/chunk-SA7LMQFG.js.map +0 -1
- package/dist/chunk-WMFCI6KC.js.map +0 -1
- package/dist/index-jF4BGOIb.d.cts +0 -173
- package/dist/index-jF4BGOIb.d.ts +0 -173
package/README.md
CHANGED
|
@@ -5,10 +5,15 @@
|
|
|
5
5
|
[](https://www.npmjs.com/package/kawasekit)
|
|
6
6
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
7
7
|
|
|
8
|
-
🚧 **Status**:
|
|
8
|
+
🚧 **Status**: M5 backbone complete — `kawasekit@0.1.0-beta.3` is published on npm (SLSA provenance, `beta` dist-tag) and mainnet-capable, with payment flows verified on Polygon mainnet. **Not yet GA**, but **both `0.1.0` fund-correctness gates are now closed**:
|
|
9
|
+
|
|
10
|
+
- **Reasoning-step idempotency** ([`docs/THREAT_MODEL.md` §6.1](./docs/THREAT_MODEL.md), now closed) — a default-on server dedup layer prevents duplicate payments for identical re-sends, and an opt-in client-derived EIP-3009 nonce makes the token contract reject re-signed same-intent duplicates on-chain. See the [idempotency note](#x402-paywall-m3-1).
|
|
11
|
+
- **`maxAmountPerSign`** (threat 1.14) — the signer can now pin a per-signature value ceiling, the way it already pins the asset.
|
|
12
|
+
|
|
13
|
+
This removes the earlier blanket "small per-call values only" caveat: preventing duplicate payment is now a matter of correct integration (wiring a reasoning-step key for the regenerate / fan-out case), not a missing SDK capability. GA (`0.1.0` on the `latest` tag) now waits on a **clean one-week beta soak**. Review happens **continuously in the open**: issues and counter-examples are welcome on GitHub and via [SECURITY.md](./SECURITY.md) (the §6.1 gap itself came from public feedback). A formal third-party audit is a goal on the road to `1.0`, not a `0.1.0` GA blocker. Built in public.
|
|
9
14
|
|
|
10
15
|
```bash
|
|
11
|
-
pnpm add kawasekit@beta # 0.1.0-beta.
|
|
16
|
+
pnpm add kawasekit@beta # 0.1.0-beta.3 — pre-GA, mainnet-capable
|
|
12
17
|
```
|
|
13
18
|
|
|
14
19
|
## Vision
|
|
@@ -25,7 +30,7 @@ Built around modern account abstraction (ERC-4337 / Kernel v3.1) and Japan's fir
|
|
|
25
30
|
- [x] **M2**: JPYC transfer via UserOp + EIP-3009 signing helpers + Daily Limit spending policy
|
|
26
31
|
- [x] **M3**: x402 v2 server/client/facilitator + session-key lifecycle + Mastra/Hono integration example
|
|
27
32
|
- [x] **M4**: Polygon mainnet support + observability (Prometheus / OTLP) + CLI + docs site + npm `0.1.0-alpha`/`0.1.0-beta` release
|
|
28
|
-
- [ ] **M5
|
|
33
|
+
- [ ] **M5** *(backbone done)*: reasoning-step idempotency layer (§6.1 ✅) + `maxAmountPerSign` ceiling (✅) → **both `0.1.0` fund-correctness gates closed**. Remaining: `0.1.0` GA promote (after a clean beta soak) and Kaia support (fast-follow). The README roadmap's framing — "Community building + first real integrations" — is the *outcome*; closing these gaps is the technical *prerequisite* for it.
|
|
29
34
|
- [ ] **M6**: Managed service alpha + Rust policy engine
|
|
30
35
|
|
|
31
36
|
## Quick Start
|
|
@@ -173,8 +178,10 @@ const app = new Hono();
|
|
|
173
178
|
app.use(
|
|
174
179
|
"/weather/*",
|
|
175
180
|
x402Middleware({
|
|
176
|
-
// `network` is required (M4-1):
|
|
177
|
-
// walletClient.
|
|
181
|
+
// `network` is required (M4-1): cross-checked against walletClient.chain.isTestnet,
|
|
182
|
+
// throws on mismatch. walletClient.account MUST be built with viem's `nonceManager`
|
|
183
|
+
// — createSelfFacilitator throws at construction otherwise (threat 2.2). On mainnet
|
|
184
|
+
// it waits for 4 confirmations by default (1 on testnet); override with `confirmations`.
|
|
178
185
|
facilitator: createSelfFacilitator({ network: "testnet", walletClient, publicClient }),
|
|
179
186
|
requirementsFor: () => [
|
|
180
187
|
buildPaymentRequirements({
|
|
@@ -189,10 +196,17 @@ app.use(
|
|
|
189
196
|
app.get("/weather/:city", (c) => c.json({ city: c.req.param("city"), weather: "sunny" }));
|
|
190
197
|
```
|
|
191
198
|
|
|
199
|
+
The server **deduplicates identical re-sent paid requests by default** (M5-1): an
|
|
200
|
+
in-memory store replays the cached response instead of settling twice, and closes
|
|
201
|
+
the verify→settle race. It is single-process — for multi-replica deployments pass a
|
|
202
|
+
shared store (or rely on the client-derived nonce below); disable with
|
|
203
|
+
`idempotency: { store: "none" }`. See the [idempotency note](#x402-paywall-m3-1) below.
|
|
204
|
+
|
|
192
205
|
Client (any `fetch` becomes x402-aware):
|
|
193
206
|
|
|
194
207
|
```typescript
|
|
195
208
|
import { createX402PaymentSigner, JPYC_DECIMALS, wrapFetch } from "kawasekit";
|
|
209
|
+
import { createIdempotencyKeyBuilder } from "kawasekit/idempotency";
|
|
196
210
|
import { parseUnits } from "viem";
|
|
197
211
|
import { privateKeyToAccount } from "viem/accounts";
|
|
198
212
|
|
|
@@ -202,8 +216,16 @@ const signer = createX402PaymentSigner({
|
|
|
202
216
|
// Pin to the JPYC v2 EIP-712 domain at construction. The wire-format
|
|
203
217
|
// extra.name / extra.version are ignored — Threat 1.4 mitigation.
|
|
204
218
|
asset: { kind: "known", id: "jpyc-v2" },
|
|
219
|
+
// Per-signature value ceiling (M5-2, threat 1.14): refuse to sign any
|
|
220
|
+
// requirement above this. Pins the *amount* the way `asset` pins the token.
|
|
221
|
+
maxAmountPerSign: parseUnits("1", JPYC_DECIMALS), // ≤ 1 JPYC per call
|
|
205
222
|
});
|
|
206
223
|
|
|
224
|
+
// One key builder per agent run; call .next(intent) at each tool-execution
|
|
225
|
+
// boundary and reuse the returned key for retries of that step.
|
|
226
|
+
const keys = createIdempotencyKeyBuilder({ conversationId: "conv-42" });
|
|
227
|
+
let stepKey = keys.next("fetch_weather:Tokyo");
|
|
228
|
+
|
|
207
229
|
// onPayment is *required* at the type level — kawasekit refuses to default
|
|
208
230
|
// to "always pay" silently. The callback is your budget guard.
|
|
209
231
|
let spent = 0n;
|
|
@@ -216,20 +238,36 @@ const fetch402 = wrapFetch({
|
|
|
216
238
|
spent = next;
|
|
217
239
|
return true;
|
|
218
240
|
},
|
|
241
|
+
// Reasoning-step idempotency (M5-1): the key is sent as an `Idempotency-Key`
|
|
242
|
+
// header AND derives a deterministic EIP-3009 nonce, so a regenerate /
|
|
243
|
+
// multi-agent re-sign of the SAME intent reuses the nonce and the token
|
|
244
|
+
// contract rejects the duplicate on-chain. Omit for today's random-nonce path.
|
|
245
|
+
idempotencyKeyFor: () => stepKey,
|
|
219
246
|
});
|
|
220
247
|
|
|
221
248
|
const res = await fetch402("https://api.example.com/weather/Tokyo");
|
|
222
249
|
// → 402 → onPayment guard → signed retry → 200 with JPYC settled on-chain
|
|
223
250
|
```
|
|
224
251
|
|
|
225
|
-
>
|
|
226
|
-
>
|
|
227
|
-
>
|
|
228
|
-
>
|
|
229
|
-
>
|
|
230
|
-
>
|
|
231
|
-
>
|
|
232
|
-
>
|
|
252
|
+
> **Reasoning-step idempotency (M5-1).** kawasekit now prevents one agent
|
|
253
|
+
> reasoning step from paying twice, across two layers:
|
|
254
|
+
>
|
|
255
|
+
> - **Identical re-send — handled by default.** The server dedup layer (shown in
|
|
256
|
+
> the server example above) replays the cached response for a re-sent /
|
|
257
|
+
> network-duplicate request and closes the verify→settle race — no
|
|
258
|
+
> configuration needed (threat 1.8c, ✅). It is single-process; use a shared
|
|
259
|
+
> store for multiple replicas, or rely on the derived nonce below.
|
|
260
|
+
> - **Re-signed same intent — wire the key.** A "Regenerate" click or multi-agent
|
|
261
|
+
> fan-out signs a *fresh* authorization for the same intent. Pass a
|
|
262
|
+
> reasoning-step key (`idempotencyKeyFor` + `createIdempotencyKeyBuilder`, shown
|
|
263
|
+
> in the client example) so the EIP-3009 nonce is derived deterministically and
|
|
264
|
+
> the JPYC contract rejects the duplicate **on-chain**, across uncoordinated
|
|
265
|
+
> replicas. The SDK can't do this for you — it never sees the LLM intent, only
|
|
266
|
+
> your harness does — so this half is **operator responsibility** (threat 1.8b,
|
|
267
|
+
> parallel to the asset pin). Omit the key to fall back to random-nonce behaviour.
|
|
268
|
+
>
|
|
269
|
+
> See [`docs/THREAT_MODEL.md` §6.1](./docs/THREAT_MODEL.md) (now closed) and the
|
|
270
|
+
> [design RFC](./docs/rfc/m5-1-reasoning-step-idempotency.md) for the full model.
|
|
233
271
|
|
|
234
272
|
### Session-key lifecycle (M3-2)
|
|
235
273
|
|
|
@@ -263,22 +301,36 @@ const restored = await restoreSessionAccount({
|
|
|
263
301
|
|
|
264
302
|
## Supported Chains
|
|
265
303
|
|
|
266
|
-
JPYC availability and kawasekit support are **two separate axes
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
(`
|
|
270
|
-
|
|
271
|
-
|
|
304
|
+
JPYC availability and kawasekit support are **two separate axes**. As of M5-3,
|
|
305
|
+
kawasekit ships chain configs for **Polygon, Kaia, Avalanche, and Ethereum**
|
|
306
|
+
(+ their testnets) in `src/chains/`, each carrying a per-chain finality default
|
|
307
|
+
(`defaultConfirmations`). JPYC is live at the same address on **all eight
|
|
308
|
+
chains** (Kaia / Kairos / Avalanche / Fuji / Sepolia confirmed by a read-only
|
|
309
|
+
on-chain `name()`/`symbol()` check; Polygon / Amoy / Ethereum established). Two
|
|
310
|
+
honest caveats: the **x402 EOA-payer path** works on every chain, but the
|
|
311
|
+
**smart-account path** (session keys, sponsored UserOps) is verified only on
|
|
312
|
+
Polygon — Kaia's runs via Pimlico in a later phase. Real x402 settlement is
|
|
313
|
+
**verified on Kaia Kairos** — a JPYC `transferWithAuthorization` settled through
|
|
314
|
+
the self-facilitator ([tx `0xe0a0…79c0`](https://kairos.kaiascan.io/tx/0xe0a0bfc75a447ff86c3502d49ff4e45cdf0396a1edd7eb5ed132dcb0130379c0),
|
|
315
|
+
`pnpm m5:kairos-x402-self-settle`); the other new chains are liveness-verified
|
|
316
|
+
but settlement is not yet exercised there.
|
|
317
|
+
|
|
318
|
+
| Chain (id) | JPYC (`0xE7C3…c29`) | kawasekit support |
|
|
272
319
|
|---|---|---|
|
|
273
|
-
| Polygon (
|
|
274
|
-
| Polygon Amoy (
|
|
275
|
-
| Kaia | ✅ Live
|
|
276
|
-
|
|
|
277
|
-
|
|
|
320
|
+
| Polygon (137) | ✅ Live | ✅ config + x402 + smart-account; verified with live mainnet txs |
|
|
321
|
+
| Polygon Amoy (80002) | ✅ Live | ✅ primary testnet target |
|
|
322
|
+
| Kaia (8217) | ✅ Live, same address¹ | ✅ M5-3 config — x402 EOA path; smart-account via Pimlico (later) |
|
|
323
|
+
| Kaia Kairos (1001) | ✅ Live (on-chain verified) | ✅ M5-3 — x402 EOA path, **settlement verified on-chain** (tx `0xe0a0…79c0`) |
|
|
324
|
+
| Avalanche (43114) | ✅ Live | ✅ M5-3 config — x402 EOA path; smart-account untested |
|
|
325
|
+
| Avalanche Fuji (43113) | ✅ Live (on-chain verified) | ✅ M5-3 config — x402 EOA path |
|
|
326
|
+
| Ethereum (1) | ✅ Live | ✅ M5-3 config — x402 EOA path; smart-account untested; deep confirmations (32) |
|
|
327
|
+
| Sepolia (11155111) | ✅ Live (on-chain verified) | ✅ M5-3 config — x402 EOA path |
|
|
278
328
|
|
|
279
329
|
¹ JPYC officially launched on Kaia in 2026-05 (Kaia DLT Foundation; Unifi began
|
|
280
|
-
JPYC support 2026-05-22), same contract address as the other chains.
|
|
281
|
-
|
|
330
|
+
JPYC support 2026-05-22), at the same contract address as the other chains. Kaia
|
|
331
|
+
runs IBFT consensus with immediate finality, so its `defaultConfirmations` is `1`
|
|
332
|
+
(not Polygon's `4`). See the
|
|
333
|
+
[finality-tuning recipe](./docs/recipes/facilitator-finality-tuning.md).
|
|
282
334
|
|
|
283
335
|
## Why Japan-first
|
|
284
336
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getJpycAddress, jpycAbi } from './chunk-
|
|
2
|
-
import { isSupportedChainId } from './chunk-
|
|
1
|
+
import { getJpycAddress, jpycAbi } from './chunk-NRGSI52C.js';
|
|
2
|
+
import { isSupportedChainId } from './chunk-SOTYGX67.js';
|
|
3
3
|
import { isAddress, encodeFunctionData } from 'viem';
|
|
4
4
|
import { toCallPolicy, ParamCondition, CallPolicyVersion, toRateLimitPolicy } from '@zerodev/permissions/policies';
|
|
5
5
|
|
|
@@ -77,5 +77,5 @@ function createJpycDailyLimitPolicies(params) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
export { ONE_DAY_SECONDS, TransferJpycInputError, createJpycDailyLimitPolicies, transferJpyc };
|
|
80
|
-
//# sourceMappingURL=chunk-
|
|
81
|
-
//# sourceMappingURL=chunk-
|
|
80
|
+
//# sourceMappingURL=chunk-DGWKPDDQ.js.map
|
|
81
|
+
//# sourceMappingURL=chunk-DGWKPDDQ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/transfer-jpyc.ts","../src/policy/daily-limit.ts"],"names":[],"mappings":";;;;;AA6DO,IAAM,sBAAA,GAAN,cAAqC,KAAA,CAAM;AAAA,EACjD,YAAY,OAAA,EAAiB;AAC5B,IAAA,KAAA,CAAM,CAAA,cAAA,EAAiB,OAAO,CAAA,CAAE,CAAA;AAChC,IAAA,IAAA,CAAK,IAAA,GAAO,wBAAA;AAAA,EACb;AACD;AAgBA,eAAsB,YAAA,CACrB,cACA,MAAA,EAC8B;AAC9B,EAAA,IAAI,CAAC,UAAU,MAAA,CAAO,EAAA,EAAI,EAAE,MAAA,EAAQ,KAAA,EAAO,CAAA,EAAG;AAC7C,IAAA,MAAM,IAAI,sBAAA,CAAuB,CAAA,+BAAA,EAAkC,MAAA,CAAO,EAAE,CAAA,CAAE,CAAA;AAAA,EAC/E;AACA,EAAA,IAAI,MAAA,CAAO,UAAU,EAAA,EAAI;AACxB,IAAA,MAAM,IAAI,sBAAA,CAAuB,CAAA,iCAAA,EAAoC,MAAA,CAAO,MAAM,CAAA,CAAA,CAAG,CAAA;AAAA,EACtF;AAEA,EAAA,MAAM,OAAA,GAAU,aAAa,KAAA,CAAM,EAAA;AACnC,EAAA,IAAI,CAAC,kBAAA,CAAmB,OAAO,CAAA,EAAG;AACjC,IAAA,MAAM,IAAI,sBAAA,CAAuB,CAAA,SAAA,EAAY,OAAO,CAAA,oCAAA,CAAsC,CAAA;AAAA,EAC3F;AACA,EAAA,MAAM,WAAA,GAAc,eAAe,OAAkC,CAAA;AAErE,EAAA,MAAM,OAAO,kBAAA,CAAmB;AAAA,IAC/B,GAAA,EAAK,OAAA;AAAA,IACL,YAAA,EAAc,UAAA;AAAA,IACd,IAAA,EAAM,CAAC,MAAA,CAAO,EAAA,EAAI,OAAO,MAAM;AAAA,GAC/B,CAAA;AAED,EAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,OAAA,CAAQ,WAAA,CAAY,CAAC,EAAE,EAAA,EAAI,WAAA,EAAa,KAAA,EAAO,EAAA,EAAI,IAAA,EAAM,CAAC,CAAA;AAE9F,EAAA,MAAM,aAAa,MAAM,YAAA,CAAa,iBAAA,CAAkB,EAAE,UAAU,CAAA;AAEpE,EAAA,IAAI,MAAA,CAAO,mBAAmB,KAAA,EAAO;AACpC,IAAA,OAAO,EAAE,UAAA,EAAY,eAAA,EAAiB,IAAA,EAAM,SAAS,IAAA,EAAK;AAAA,EAC3D;AAEA,EAAA,MAAM,UAAU,MAAM,YAAA,CAAa,4BAA4B,EAAE,IAAA,EAAM,YAAY,CAAA;AACnF,EAAA,OAAO;AAAA,IACN,UAAA;AAAA,IACA,eAAA,EAAiB,QAAQ,OAAA,CAAQ,eAAA;AAAA,IACjC,SAAS,OAAA,CAAQ;AAAA,GAClB;AACD;AC3FO,IAAM,eAAA,GAAkB;AAyCxB,SAAS,6BACf,MAAA,EAC4B;AAC5B,EAAA,IAAI,MAAA,CAAO,kBAAkB,EAAA,EAAI;AAChC,IAAA,MAAM,IAAI,KAAA;AAAA,MACT,CAAA,mEAAA,EAAsE,OAAO,cAAc,CAAA,CAAA;AAAA,KAC5F;AAAA,EACD;AACA,EAAA,IAAI,CAAC,OAAO,SAAA,CAAU,MAAA,CAAO,kBAAkB,CAAA,IAAK,MAAA,CAAO,qBAAqB,CAAA,EAAG;AAClF,IAAA,MAAM,IAAI,KAAA;AAAA,MACT,CAAA,iFAAA,EAAoF,OAAO,kBAAkB,CAAA,CAAA;AAAA,KAC9G;AAAA,EACD;AAEA,EAAA,MAAM,aAAa,YAAA,CAAa;AAAA,IAC/B,aAAA,EAAe,MAAA,CAAO,iBAAA,IAAqB,iBAAA,CAAkB,MAAA;AAAA,IAC7D,WAAA,EAAa;AAAA,MACZ;AAAA,QACC,QAAQ,MAAA,CAAO,WAAA;AAAA,QACf,GAAA,EAAK,OAAA;AAAA,QACL,YAAA,EAAc,UAAA;AAAA,QACd,IAAA,EAAM;AAAA;AAAA,UAEL,IAAA;AAAA;AAAA,UAEA;AAAA,YACC,WAAW,cAAA,CAAe,kBAAA;AAAA,YAC1B,OAAO,MAAA,CAAO;AAAA;AACf;AACD;AACD;AACD,GACA,CAAA;AAED,EAAA,MAAM,kBAAkB,iBAAA,CAAkB;AAAA,IACzC,QAAA,EAAU,eAAA;AAAA,IACV,OAAO,MAAA,CAAO;AAAA,GACd,CAAA;AAED,EAAA,OAAO,CAAC,YAAY,eAAe,CAAA;AACpC","file":"chunk-6G345P2I.js","sourcesContent":["/**\n * High-level helper: transfer JPYC from a Kernel smart account via a sponsored\n * UserOp.\n *\n * This is the canonical \"agent payment\" path for M2. The flow:\n * 1. Resolve the JPYC contract address for `kernelClient.chain`.\n * 2. Encode `JPYC.transfer(to, amount)` calldata.\n * 3. Wrap it as a Kernel call and submit via `sendUserOperation`.\n * 4. Wait for the bundler receipt and return both hashes.\n *\n * EIP-3009 `transferWithAuthorization` cannot be used here: JPYC's signature\n * verification is pure `ecrecover`, so a smart account cannot be `from`. See\n * `src/tokens/eip3009.ts` for the EOA-payer path.\n *\n * @packageDocumentation\n */\n\nimport type { KernelAccountClient } from \"@zerodev/sdk\";\nimport type { Address, Chain, Hex, Transport } from \"viem\";\nimport { encodeFunctionData, isAddress } from \"viem\";\nimport type { SmartAccount } from \"viem/account-abstraction\";\nimport { isSupportedChainId, type SupportedChainId } from \"../chains\";\nimport { getJpycAddress, jpycAbi } from \"../tokens/jpyc\";\n\n/** A {@link KernelAccountClient} that is fully configured (chain + account). */\nexport type ConfiguredKernelClient = KernelAccountClient<Transport, Chain, SmartAccount>;\n\n/** Parameters for {@link transferJpyc}. */\nexport interface TransferJpycParams {\n\t/** Recipient address. */\n\treadonly to: Address;\n\t/**\n\t * Raw token amount in the token's smallest unit (JPYC has 18 decimals).\n\t *\n\t * @example\n\t * ```ts\n\t * import { parseUnits } from \"viem\";\n\t * import { JPYC_DECIMALS } from \"kawasekit\";\n\t *\n\t * parseUnits(\"100\", JPYC_DECIMALS); // 100 JPYC\n\t * ```\n\t */\n\treadonly amount: bigint;\n\t/**\n\t * Optional. Defaults to waiting for the bundler receipt before returning.\n\t * Set to `false` to return after the UserOp is submitted but before it\n\t * lands on chain — useful when the caller wants to do its own polling.\n\t */\n\treadonly waitForReceipt?: boolean;\n}\n\n/** Result of a {@link transferJpyc} call. */\nexport interface TransferJpycResult {\n\treadonly userOpHash: Hex;\n\t/** `null` when `waitForReceipt: false` was requested. */\n\treadonly transactionHash: Hex | null;\n\t/** `true` if the bundler receipt reported success; `null` if not awaited. */\n\treadonly success: boolean | null;\n}\n\n/** Thrown when {@link transferJpyc} is called with invalid arguments. */\nexport class TransferJpycInputError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(`transferJpyc: ${message}`);\n\t\tthis.name = \"TransferJpycInputError\";\n\t}\n}\n\n/**\n * Transfer JPYC from the Kernel smart account to `to` via a sponsored UserOp.\n *\n * @example\n * ```ts\n * import { parseUnits } from \"viem\";\n * import { JPYC_DECIMALS, transferJpyc } from \"kawasekit\";\n *\n * const { userOpHash, transactionHash } = await transferJpyc(kernelClient, {\n * to: \"0xBeef0000000000000000000000000000DEADBEEF\",\n * amount: parseUnits(\"100\", JPYC_DECIMALS),\n * });\n * ```\n */\nexport async function transferJpyc(\n\tkernelClient: ConfiguredKernelClient,\n\tparams: TransferJpycParams,\n): Promise<TransferJpycResult> {\n\tif (!isAddress(params.to, { strict: false })) {\n\t\tthrow new TransferJpycInputError(`\\`to\\` is not a valid address: ${params.to}`);\n\t}\n\tif (params.amount <= 0n) {\n\t\tthrow new TransferJpycInputError(`\\`amount\\` must be positive, got ${params.amount}.`);\n\t}\n\n\tconst chainId = kernelClient.chain.id;\n\tif (!isSupportedChainId(chainId)) {\n\t\tthrow new TransferJpycInputError(`Chain ID ${chainId} is not a kawasekit-supported chain.`);\n\t}\n\tconst jpycAddress = getJpycAddress(chainId satisfies SupportedChainId);\n\n\tconst data = encodeFunctionData({\n\t\tabi: jpycAbi,\n\t\tfunctionName: \"transfer\",\n\t\targs: [params.to, params.amount],\n\t});\n\n\tconst callData = await kernelClient.account.encodeCalls([{ to: jpycAddress, value: 0n, data }]);\n\n\tconst userOpHash = await kernelClient.sendUserOperation({ callData });\n\n\tif (params.waitForReceipt === false) {\n\t\treturn { userOpHash, transactionHash: null, success: null };\n\t}\n\n\tconst receipt = await kernelClient.waitForUserOperationReceipt({ hash: userOpHash });\n\treturn {\n\t\tuserOpHash,\n\t\ttransactionHash: receipt.receipt.transactionHash,\n\t\tsuccess: receipt.success,\n\t};\n}\n","/**\n * Daily-limit spending policy for JPYC, built on ZeroDev's Permission System.\n *\n * Composes two ZeroDev policies:\n * 1. **callPolicy** — locks the session key to `JPYC.transfer(to, value)`\n * with `value ≤ maxPerTransfer`. Recipient is unrestricted in M2;\n * add allowlisting in M3 when use cases firm up.\n * 2. **rateLimitPolicy** — caps userOp count to `maxTransfersPerDay` in any\n * 24-hour rolling window.\n *\n * Effective daily cap = `maxPerTransfer × maxTransfersPerDay`. This is not a\n * cumulative-amount tracker (ZeroDev doesn't ship one), but the agent cannot\n * exceed either dimension, so the spirit of \"daily limit\" holds.\n *\n * @packageDocumentation\n */\n\nimport type { Policy } from \"@zerodev/permissions\";\nimport {\n\tCallPolicyVersion,\n\tParamCondition,\n\ttoCallPolicy,\n\ttoRateLimitPolicy,\n} from \"@zerodev/permissions/policies\";\nimport type { Address } from \"viem\";\nimport { jpycAbi } from \"../tokens/jpyc\";\n\n/** One day in seconds — the period for {@link createJpycDailyLimitPolicies}. */\nexport const ONE_DAY_SECONDS = 86_400;\n\n/** Parameters for {@link createJpycDailyLimitPolicies}. */\nexport interface CreateJpycDailyLimitPoliciesParams {\n\t/** JPYC contract address on the target chain. */\n\treadonly jpycAddress: Address;\n\t/** Maximum JPYC (in raw units) the session key may move in one transfer. */\n\treadonly maxPerTransfer: bigint;\n\t/** Maximum number of transfer userOps the session key may submit per day. */\n\treadonly maxTransfersPerDay: number;\n\t/**\n\t * ZeroDev callPolicy on-chain version. Defaults to V0_0_4 (latest at the\n\t * time of writing). Bump only after auditing the new version's semantics.\n\t */\n\treadonly callPolicyVersion?: CallPolicyVersion;\n}\n\n/**\n * Builds the ZeroDev policy bundle that enforces a JPYC daily spend limit.\n *\n * Plug the returned policies into `toPermissionValidator({ policies, … })`\n * — see {@link createAgentSmartAccount} for the common wiring.\n *\n * @example\n * ```ts\n * import { parseUnits } from \"viem\";\n * import {\n * createJpycDailyLimitPolicies,\n * getJpycAddress,\n * JPYC_DECIMALS,\n * polygonAmoy,\n * } from \"kawasekit\";\n *\n * const policies = createJpycDailyLimitPolicies({\n * jpycAddress: getJpycAddress(polygonAmoy.id),\n * maxPerTransfer: parseUnits(\"100\", JPYC_DECIMALS), // 100 JPYC / tx\n * maxTransfersPerDay: 10, // 10 tx / day\n * // effective daily cap = 1000 JPYC\n * });\n * ```\n */\nexport function createJpycDailyLimitPolicies(\n\tparams: CreateJpycDailyLimitPoliciesParams,\n): readonly [Policy, Policy] {\n\tif (params.maxPerTransfer <= 0n) {\n\t\tthrow new Error(\n\t\t\t`createJpycDailyLimitPolicies: maxPerTransfer must be positive, got ${params.maxPerTransfer}.`,\n\t\t);\n\t}\n\tif (!Number.isInteger(params.maxTransfersPerDay) || params.maxTransfersPerDay < 1) {\n\t\tthrow new Error(\n\t\t\t`createJpycDailyLimitPolicies: maxTransfersPerDay must be a positive integer, got ${params.maxTransfersPerDay}.`,\n\t\t);\n\t}\n\n\tconst callPolicy = toCallPolicy({\n\t\tpolicyVersion: params.callPolicyVersion ?? CallPolicyVersion.V0_0_4,\n\t\tpermissions: [\n\t\t\t{\n\t\t\t\ttarget: params.jpycAddress,\n\t\t\t\tabi: jpycAbi,\n\t\t\t\tfunctionName: \"transfer\",\n\t\t\t\targs: [\n\t\t\t\t\t// Recipient: any address allowed (no allowlist in M2).\n\t\t\t\t\tnull,\n\t\t\t\t\t// value: must be ≤ maxPerTransfer.\n\t\t\t\t\t{\n\t\t\t\t\t\tcondition: ParamCondition.LESS_THAN_OR_EQUAL,\n\t\t\t\t\t\tvalue: params.maxPerTransfer,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\tconst rateLimitPolicy = toRateLimitPolicy({\n\t\tinterval: ONE_DAY_SECONDS,\n\t\tcount: params.maxTransfersPerDay,\n\t});\n\n\treturn [callPolicy, rateLimitPolicy] as const;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/client/transfer-jpyc.ts","../src/policy/daily-limit.ts"],"names":[],"mappings":"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","file":"chunk-DGWKPDDQ.js","sourcesContent":["/**\n * High-level helper: transfer JPYC from a Kernel smart account via a sponsored\n * UserOp.\n *\n * This is the canonical \"agent payment\" path for M2. The flow:\n * 1. Resolve the JPYC contract address for `kernelClient.chain`.\n * 2. Encode `JPYC.transfer(to, amount)` calldata.\n * 3. Wrap it as a Kernel call and submit via `sendUserOperation`.\n * 4. Wait for the bundler receipt and return both hashes.\n *\n * EIP-3009 `transferWithAuthorization` cannot be used here: JPYC's signature\n * verification is pure `ecrecover`, so a smart account cannot be `from`. See\n * `src/tokens/eip3009.ts` for the EOA-payer path.\n *\n * @packageDocumentation\n */\n\nimport type { KernelAccountClient } from \"@zerodev/sdk\";\nimport type { Address, Chain, Hex, Transport } from \"viem\";\nimport { encodeFunctionData, isAddress } from \"viem\";\nimport type { SmartAccount } from \"viem/account-abstraction\";\nimport { isSupportedChainId, type SupportedChainId } from \"../chains\";\nimport { getJpycAddress, jpycAbi } from \"../tokens/jpyc\";\n\n/** A {@link KernelAccountClient} that is fully configured (chain + account). */\nexport type ConfiguredKernelClient = KernelAccountClient<Transport, Chain, SmartAccount>;\n\n/** Parameters for {@link transferJpyc}. */\nexport interface TransferJpycParams {\n\t/** Recipient address. */\n\treadonly to: Address;\n\t/**\n\t * Raw token amount in the token's smallest unit (JPYC has 18 decimals).\n\t *\n\t * @example\n\t * ```ts\n\t * import { parseUnits } from \"viem\";\n\t * import { JPYC_DECIMALS } from \"kawasekit\";\n\t *\n\t * parseUnits(\"100\", JPYC_DECIMALS); // 100 JPYC\n\t * ```\n\t */\n\treadonly amount: bigint;\n\t/**\n\t * Optional. Defaults to waiting for the bundler receipt before returning.\n\t * Set to `false` to return after the UserOp is submitted but before it\n\t * lands on chain — useful when the caller wants to do its own polling.\n\t */\n\treadonly waitForReceipt?: boolean;\n}\n\n/** Result of a {@link transferJpyc} call. */\nexport interface TransferJpycResult {\n\treadonly userOpHash: Hex;\n\t/** `null` when `waitForReceipt: false` was requested. */\n\treadonly transactionHash: Hex | null;\n\t/** `true` if the bundler receipt reported success; `null` if not awaited. */\n\treadonly success: boolean | null;\n}\n\n/** Thrown when {@link transferJpyc} is called with invalid arguments. */\nexport class TransferJpycInputError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(`transferJpyc: ${message}`);\n\t\tthis.name = \"TransferJpycInputError\";\n\t}\n}\n\n/**\n * Transfer JPYC from the Kernel smart account to `to` via a sponsored UserOp.\n *\n * @example\n * ```ts\n * import { parseUnits } from \"viem\";\n * import { JPYC_DECIMALS, transferJpyc } from \"kawasekit\";\n *\n * const { userOpHash, transactionHash } = await transferJpyc(kernelClient, {\n * to: \"0xBeef0000000000000000000000000000DEADBEEF\",\n * amount: parseUnits(\"100\", JPYC_DECIMALS),\n * });\n * ```\n */\nexport async function transferJpyc(\n\tkernelClient: ConfiguredKernelClient,\n\tparams: TransferJpycParams,\n): Promise<TransferJpycResult> {\n\tif (!isAddress(params.to, { strict: false })) {\n\t\tthrow new TransferJpycInputError(`\\`to\\` is not a valid address: ${params.to}`);\n\t}\n\tif (params.amount <= 0n) {\n\t\tthrow new TransferJpycInputError(`\\`amount\\` must be positive, got ${params.amount}.`);\n\t}\n\n\tconst chainId = kernelClient.chain.id;\n\tif (!isSupportedChainId(chainId)) {\n\t\tthrow new TransferJpycInputError(`Chain ID ${chainId} is not a kawasekit-supported chain.`);\n\t}\n\tconst jpycAddress = getJpycAddress(chainId satisfies SupportedChainId);\n\n\tconst data = encodeFunctionData({\n\t\tabi: jpycAbi,\n\t\tfunctionName: \"transfer\",\n\t\targs: [params.to, params.amount],\n\t});\n\n\tconst callData = await kernelClient.account.encodeCalls([{ to: jpycAddress, value: 0n, data }]);\n\n\tconst userOpHash = await kernelClient.sendUserOperation({ callData });\n\n\tif (params.waitForReceipt === false) {\n\t\treturn { userOpHash, transactionHash: null, success: null };\n\t}\n\n\tconst receipt = await kernelClient.waitForUserOperationReceipt({ hash: userOpHash });\n\treturn {\n\t\tuserOpHash,\n\t\ttransactionHash: receipt.receipt.transactionHash,\n\t\tsuccess: receipt.success,\n\t};\n}\n","/**\n * Daily-limit spending policy for JPYC, built on ZeroDev's Permission System.\n *\n * Composes two ZeroDev policies:\n * 1. **callPolicy** — locks the session key to `JPYC.transfer(to, value)`\n * with `value ≤ maxPerTransfer`. Recipient is unrestricted in M2;\n * add allowlisting in M3 when use cases firm up.\n * 2. **rateLimitPolicy** — caps userOp count to `maxTransfersPerDay` in any\n * 24-hour rolling window.\n *\n * Effective daily cap = `maxPerTransfer × maxTransfersPerDay`. This is not a\n * cumulative-amount tracker (ZeroDev doesn't ship one), but the agent cannot\n * exceed either dimension, so the spirit of \"daily limit\" holds.\n *\n * @packageDocumentation\n */\n\nimport type { Policy } from \"@zerodev/permissions\";\nimport {\n\tCallPolicyVersion,\n\tParamCondition,\n\ttoCallPolicy,\n\ttoRateLimitPolicy,\n} from \"@zerodev/permissions/policies\";\nimport type { Address } from \"viem\";\nimport { jpycAbi } from \"../tokens/jpyc\";\n\n/** One day in seconds — the period for {@link createJpycDailyLimitPolicies}. */\nexport const ONE_DAY_SECONDS = 86_400;\n\n/** Parameters for {@link createJpycDailyLimitPolicies}. */\nexport interface CreateJpycDailyLimitPoliciesParams {\n\t/** JPYC contract address on the target chain. */\n\treadonly jpycAddress: Address;\n\t/** Maximum JPYC (in raw units) the session key may move in one transfer. */\n\treadonly maxPerTransfer: bigint;\n\t/** Maximum number of transfer userOps the session key may submit per day. */\n\treadonly maxTransfersPerDay: number;\n\t/**\n\t * ZeroDev callPolicy on-chain version. Defaults to V0_0_4 (latest at the\n\t * time of writing). Bump only after auditing the new version's semantics.\n\t */\n\treadonly callPolicyVersion?: CallPolicyVersion;\n}\n\n/**\n * Builds the ZeroDev policy bundle that enforces a JPYC daily spend limit.\n *\n * Plug the returned policies into `toPermissionValidator({ policies, … })`\n * — see {@link createAgentSmartAccount} for the common wiring.\n *\n * @example\n * ```ts\n * import { parseUnits } from \"viem\";\n * import {\n * createJpycDailyLimitPolicies,\n * getJpycAddress,\n * JPYC_DECIMALS,\n * polygonAmoy,\n * } from \"kawasekit\";\n *\n * const policies = createJpycDailyLimitPolicies({\n * jpycAddress: getJpycAddress(polygonAmoy.id),\n * maxPerTransfer: parseUnits(\"100\", JPYC_DECIMALS), // 100 JPYC / tx\n * maxTransfersPerDay: 10, // 10 tx / day\n * // effective daily cap = 1000 JPYC\n * });\n * ```\n */\nexport function createJpycDailyLimitPolicies(\n\tparams: CreateJpycDailyLimitPoliciesParams,\n): readonly [Policy, Policy] {\n\tif (params.maxPerTransfer <= 0n) {\n\t\tthrow new Error(\n\t\t\t`createJpycDailyLimitPolicies: maxPerTransfer must be positive, got ${params.maxPerTransfer}.`,\n\t\t);\n\t}\n\tif (!Number.isInteger(params.maxTransfersPerDay) || params.maxTransfersPerDay < 1) {\n\t\tthrow new Error(\n\t\t\t`createJpycDailyLimitPolicies: maxTransfersPerDay must be a positive integer, got ${params.maxTransfersPerDay}.`,\n\t\t);\n\t}\n\n\tconst callPolicy = toCallPolicy({\n\t\tpolicyVersion: params.callPolicyVersion ?? CallPolicyVersion.V0_0_4,\n\t\tpermissions: [\n\t\t\t{\n\t\t\t\ttarget: params.jpycAddress,\n\t\t\t\tabi: jpycAbi,\n\t\t\t\tfunctionName: \"transfer\",\n\t\t\t\targs: [\n\t\t\t\t\t// Recipient: any address allowed (no allowlist in M2).\n\t\t\t\t\tnull,\n\t\t\t\t\t// value: must be ≤ maxPerTransfer.\n\t\t\t\t\t{\n\t\t\t\t\t\tcondition: ParamCondition.LESS_THAN_OR_EQUAL,\n\t\t\t\t\t\tvalue: params.maxPerTransfer,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\tconst rateLimitPolicy = toRateLimitPolicy({\n\t\tinterval: ONE_DAY_SECONDS,\n\t\tcount: params.maxTransfersPerDay,\n\t});\n\n\treturn [callPolicy, rateLimitPolicy] as const;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isSupportedChainId } from './chunk-
|
|
1
|
+
import { isSupportedChainId } from './chunk-SOTYGX67.js';
|
|
2
2
|
import { signerToEcdsaValidator } from '@zerodev/ecdsa-validator';
|
|
3
3
|
import { toPermissionValidator, serializePermissionAccount, deserializePermissionAccount } from '@zerodev/permissions';
|
|
4
4
|
import { toECDSASigner } from '@zerodev/permissions/signers';
|
|
@@ -300,5 +300,5 @@ async function rotateSessionKey(params) {
|
|
|
300
300
|
}
|
|
301
301
|
|
|
302
302
|
export { KAWASEKIT_SESSION_ENVELOPE_VERSION, SessionEnvelopeChainMismatchError, SessionEnvelopeParseError, SessionEnvelopeSignerMismatchError, SessionEnvelopeVersionError, createAgentSmartAccount, issueSessionKey, parseSessionEnvelope, restoreSessionAccount, revokeSessionKey, rotateSessionKey, serializeSessionEnvelope };
|
|
303
|
-
//# sourceMappingURL=chunk-
|
|
304
|
-
//# sourceMappingURL=chunk-
|
|
303
|
+
//# sourceMappingURL=chunk-N3CVLISJ.js.map
|
|
304
|
+
//# sourceMappingURL=chunk-N3CVLISJ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/account/session-key.ts","../src/session/errors.ts","../src/session/envelope.ts","../src/session/issue.ts","../src/session/restore.ts","../src/session/revoke.ts","../src/session/rotate.ts"],"names":["getEntryPoint","KERNEL_V3_1","toECDSASigner","getAddress","toPermissionValidator"],"mappings":"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","file":"chunk-KWCPYGFE.js","sourcesContent":["/**\n * Agent smart account = Kernel v3.1 + ECDSA sudo validator + session-key\n * permission validator.\n *\n * The owner EOA keeps full control (sudo) and can revoke / rotate the session\n * key at any time. The session key is the day-to-day signer the AI agent\n * holds; whatever policies you attach (see {@link createJpycDailyLimitPolicies})\n * are enforced at the ERC-4337 validation phase by ZeroDev's\n * `PermissionValidator`. Violating userOps revert before execution — they\n * never spend any of the smart account's funds, and a sponsored bundler\n * cannot be tricked into paying for them either.\n *\n * @packageDocumentation\n */\n\nimport { signerToEcdsaValidator } from \"@zerodev/ecdsa-validator\";\nimport type { Policy } from \"@zerodev/permissions\";\nimport { toPermissionValidator } from \"@zerodev/permissions\";\nimport { toECDSASigner } from \"@zerodev/permissions/signers\";\nimport type { CreateKernelAccountReturnType } from \"@zerodev/sdk\";\nimport { createKernelAccount } from \"@zerodev/sdk\";\nimport { getEntryPoint, KERNEL_V3_1 } from \"@zerodev/sdk/constants\";\nimport type { EntryPointType, GetKernelVersion } from \"@zerodev/sdk/types\";\nimport type { Chain, LocalAccount, PublicClient, Transport } from \"viem\";\n\n/** Parameters for {@link createAgentSmartAccount}. */\nexport interface CreateAgentSmartAccountParams {\n\t/**\n\t * viem `PublicClient` used to read on-chain state during account derivation.\n\t */\n\treadonly publicClient: PublicClient<Transport, Chain | undefined>;\n\t/**\n\t * The owner EOA. Retains sudo authority — can install new plugins,\n\t * revoke / rotate the session key, and bypass any policy.\n\t */\n\treadonly ownerSigner: LocalAccount;\n\t/**\n\t * The day-to-day signer the agent holds. Authority is limited to whatever\n\t * `policies` allow — by default it can do nothing.\n\t */\n\treadonly sessionKeySigner: LocalAccount;\n\t/**\n\t * ZeroDev policies (e.g. {@link createJpycDailyLimitPolicies}) the session\n\t * key must satisfy at userOp validation time.\n\t */\n\treadonly policies: readonly Policy[];\n\t/**\n\t * EntryPoint version + address. Defaults to v0.7 at the canonical\n\t * ERC-4337 entry-point address.\n\t */\n\treadonly entryPoint?: EntryPointType<\"0.7\">;\n\t/** Kernel version. Defaults to {@link KERNEL_V3_1}. */\n\treadonly kernelVersion?: GetKernelVersion<\"0.7\">;\n}\n\n/**\n * Builds a Kernel v3.1 smart account with sudo (owner) + regular (session key)\n * validators wired up.\n *\n * @example\n * ```ts\n * import { parseUnits } from \"viem\";\n * import { privateKeyToAccount } from \"viem/accounts\";\n * import {\n * createAgentSmartAccount,\n * createJpycDailyLimitPolicies,\n * getJpycAddress,\n * JPYC_DECIMALS,\n * polygonAmoy,\n * } from \"kawasekit\";\n *\n * const owner = privateKeyToAccount(process.env.OWNER_PRIVATE_KEY as `0x${string}`);\n * const sessionKey = privateKeyToAccount(process.env.SESSION_KEY_PRIVATE_KEY as `0x${string}`);\n *\n * const account = await createAgentSmartAccount({\n * publicClient,\n * ownerSigner: owner,\n * sessionKeySigner: sessionKey,\n * policies: createJpycDailyLimitPolicies({\n * jpycAddress: getJpycAddress(polygonAmoy.id),\n * maxPerTransfer: parseUnits(\"100\", JPYC_DECIMALS),\n * maxTransfersPerDay: 10,\n * }),\n * });\n * ```\n */\nexport async function createAgentSmartAccount(\n\tparams: CreateAgentSmartAccountParams,\n): Promise<CreateKernelAccountReturnType<\"0.7\">> {\n\tconst entryPoint = params.entryPoint ?? getEntryPoint(\"0.7\");\n\tconst kernelVersion = params.kernelVersion ?? KERNEL_V3_1;\n\n\tconst sudoValidator = await signerToEcdsaValidator(params.publicClient, {\n\t\tsigner: params.ownerSigner,\n\t\tentryPoint,\n\t\tkernelVersion,\n\t});\n\n\tconst modularSessionSigner = await toECDSASigner({ signer: params.sessionKeySigner });\n\n\tconst permissionValidator = await toPermissionValidator(params.publicClient, {\n\t\tsigner: modularSessionSigner,\n\t\tpolicies: [...params.policies],\n\t\tentryPoint,\n\t\tkernelVersion,\n\t});\n\n\treturn createKernelAccount(params.publicClient, {\n\t\tplugins: {\n\t\t\tsudo: sudoValidator,\n\t\t\tregular: permissionValidator,\n\t\t},\n\t\tentryPoint,\n\t\tkernelVersion,\n\t});\n}\n","/**\n * Typed errors thrown by the `kawasekit/session` modules.\n *\n * Centralised so consumers can `instanceof`-discriminate without importing\n * deep paths.\n *\n * @packageDocumentation\n */\n\nimport type { Address } from \"viem\";\n\n/**\n * Thrown when {@link parseSessionEnvelope} encounters an envelope whose\n * `kawasekitVersion` does not match the current\n * {@link KAWASEKIT_SESSION_ENVELOPE_VERSION}.\n *\n * The version field is intentionally a string (\"1\") so that future migrations\n * can introduce non-numeric variants (e.g. \"1-jwe\") without breaking the\n * parser ordering.\n */\nexport class SessionEnvelopeVersionError extends Error {\n\treadonly expected: string;\n\treadonly received: unknown;\n\n\tconstructor(expected: string, received: unknown) {\n\t\tsuper(\n\t\t\t`Session envelope version mismatch: expected ${JSON.stringify(expected)}, got ${JSON.stringify(received)}.`,\n\t\t);\n\t\tthis.name = \"SessionEnvelopeVersionError\";\n\t\tthis.expected = expected;\n\t\tthis.received = received;\n\t}\n}\n\n/**\n * Thrown by `restoreSessionAccount()` when an envelope's `chainId` differs\n * from the chain the consumer is restoring on. Catches the common mistake of\n * issuing on Polygon Amoy and trying to restore on Polygon mainnet.\n */\nexport class SessionEnvelopeChainMismatchError extends Error {\n\treadonly envelopeChainId: number;\n\treadonly clientChainId: number;\n\n\tconstructor(envelopeChainId: number, clientChainId: number) {\n\t\tsuper(\n\t\t\t`Session envelope is for chain ${envelopeChainId} but the restore client is on chain ${clientChainId}.`,\n\t\t);\n\t\tthis.name = \"SessionEnvelopeChainMismatchError\";\n\t\tthis.envelopeChainId = envelopeChainId;\n\t\tthis.clientChainId = clientChainId;\n\t}\n}\n\n/**\n * Thrown by `restoreSessionAccount()` when the session-key signer the consumer\n * passes does not match the `sessionKeyAddress` recorded in the envelope.\n *\n * Defence against accidentally restoring with the wrong private key — which\n * would otherwise succeed locally and only fail at UserOp validation time.\n */\nexport class SessionEnvelopeSignerMismatchError extends Error {\n\treadonly envelopeSignerAddress: Address;\n\treadonly providedSignerAddress: Address;\n\n\tconstructor(envelopeSignerAddress: Address, providedSignerAddress: Address) {\n\t\tsuper(\n\t\t\t`Session envelope was issued for signer ${envelopeSignerAddress}, but the provided session-key signer is ${providedSignerAddress}.`,\n\t\t);\n\t\tthis.name = \"SessionEnvelopeSignerMismatchError\";\n\t\tthis.envelopeSignerAddress = envelopeSignerAddress;\n\t\tthis.providedSignerAddress = providedSignerAddress;\n\t}\n}\n\n/**\n * Thrown when {@link parseSessionEnvelope} cannot decode the input as a\n * structurally valid envelope (malformed JSON, missing fields, bad types).\n */\nexport class SessionEnvelopeParseError extends Error {\n\treadonly reason: string;\n\n\tconstructor(reason: string, options?: { cause?: unknown }) {\n\t\tsuper(`Failed to parse session envelope: ${reason}`, options);\n\t\tthis.name = \"SessionEnvelopeParseError\";\n\t\tthis.reason = reason;\n\t}\n}\n","/**\n * `KawasekitSessionEnvelope` — kawasekit's typed wrapper around ZeroDev's\n * opaque `serializePermissionAccount` blob.\n *\n * Why wrap ZeroDev's blob rather than use it directly?\n *\n * - **Fail-fast on restore**: chainId / version / signer mismatches surface as\n * typed errors instead of confusing UserOp-time reverts.\n * - **Host-UI affordances**: `expiresAt` and `policySummary` are advisory\n * fields a wallet can render (\"this session expires in 2 hours, max 100\n * JPYC/day\") before handing the blob to {@link restoreSessionAccount}.\n * - **Version pin**: when ZeroDev changes their serialization format we bump\n * {@link KAWASEKIT_SESSION_ENVELOPE_VERSION} and provide a migration; the\n * inner `serialized` field stays opaque.\n *\n * Wire format: a single JSON string. Bigint fields (`expiresAt`,\n * `policySummary.maxPerTransfer`) round-trip via decimal-string encoding so\n * the JSON itself is portable through any transport (env var, HTTP header,\n * file).\n *\n * @packageDocumentation\n */\n\nimport { type Address, isAddress } from \"viem\";\nimport { isSupportedChainId, type SupportedChainId } from \"../chains\";\nimport { SessionEnvelopeParseError, SessionEnvelopeVersionError } from \"./errors\";\n\n/**\n * Current envelope format version. Bumped when the envelope schema changes\n * in a way that breaks backward compatibility.\n */\nexport const KAWASEKIT_SESSION_ENVELOPE_VERSION = \"1\" as const;\n\n/** Type of {@link KAWASEKIT_SESSION_ENVELOPE_VERSION}. */\nexport type KawasekitSessionEnvelopeVersion = typeof KAWASEKIT_SESSION_ENVELOPE_VERSION;\n\n/**\n * Advisory summary of the spending policy attached to a session key. Useful\n * for host UI; **not** consulted at validation time (the on-chain validator\n * is the source of truth).\n */\nexport interface KawasekitSessionPolicySummary {\n\treadonly jpycAddress: Address;\n\treadonly maxPerTransfer: bigint;\n\treadonly maxTransfersPerDay: number;\n}\n\n/** kawasekit's typed envelope around a ZeroDev session-key serialization. */\nexport interface KawasekitSessionEnvelope {\n\treadonly kawasekitVersion: KawasekitSessionEnvelopeVersion;\n\treadonly chainId: SupportedChainId;\n\treadonly smartAccountAddress: Address;\n\treadonly sessionKeyAddress: Address;\n\t/** Optional unix-seconds expiry. Advisory + ideally enforced by a `TimestampPolicy`. */\n\treadonly expiresAt?: bigint;\n\treadonly policySummary?: KawasekitSessionPolicySummary;\n\t/** Opaque ZeroDev `serializePermissionAccount` output. */\n\treadonly serialized: string;\n}\n\n// ---------------------------------------------------------------------------\n// Wire (JSON) shape\n// ---------------------------------------------------------------------------\n\n/**\n * Internal: the JSON shape we (de)serialize to/from. Bigint fields are stored\n * as decimal strings. Kept separate from {@link KawasekitSessionEnvelope} so\n * the public type stays bigint-friendly while the wire stays string-only.\n */\ninterface SessionEnvelopeJson {\n\treadonly kawasekitVersion: string;\n\treadonly chainId: number;\n\treadonly smartAccountAddress: string;\n\treadonly sessionKeyAddress: string;\n\treadonly expiresAt?: string;\n\treadonly policySummary?: {\n\t\treadonly jpycAddress: string;\n\t\treadonly maxPerTransfer: string;\n\t\treadonly maxTransfersPerDay: number;\n\t};\n\treadonly serialized: string;\n}\n\n// ---------------------------------------------------------------------------\n// Validation helpers\n// ---------------------------------------------------------------------------\n\nconst UINT_DECIMAL = /^(0|[1-9][0-9]*)$/;\n\nfunction assertAddress(value: unknown, field: string): Address {\n\tif (typeof value !== \"string\" || !isAddress(value, { strict: false })) {\n\t\tthrow new SessionEnvelopeParseError(`\\`${field}\\` is not a valid address: ${String(value)}`);\n\t}\n\treturn value as Address;\n}\n\nfunction assertString(value: unknown, field: string): string {\n\tif (typeof value !== \"string\" || value === \"\") {\n\t\tthrow new SessionEnvelopeParseError(`\\`${field}\\` must be a non-empty string`);\n\t}\n\treturn value;\n}\n\nfunction assertNumber(value: unknown, field: string): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) {\n\t\tthrow new SessionEnvelopeParseError(`\\`${field}\\` must be a finite number`);\n\t}\n\treturn value;\n}\n\nfunction parseBigIntString(value: unknown, field: string): bigint {\n\tif (typeof value !== \"string\" || !UINT_DECIMAL.test(value)) {\n\t\tthrow new SessionEnvelopeParseError(\n\t\t\t`\\`${field}\\` must be a non-negative decimal string: ${String(value)}`,\n\t\t);\n\t}\n\treturn BigInt(value);\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Serialises a {@link KawasekitSessionEnvelope} to a transportable JSON string.\n *\n * The output is plain UTF-8 JSON (no base64). Callers who need\n * URL-/header-safe transport can base64-encode the result themselves.\n *\n * @example\n * ```ts\n * import { serializeSessionEnvelope } from \"kawasekit\";\n *\n * const blob = serializeSessionEnvelope(envelope);\n * fs.writeFileSync(\"agent.session\", blob);\n * ```\n */\nexport function serializeSessionEnvelope(envelope: KawasekitSessionEnvelope): string {\n\tconst json: SessionEnvelopeJson = {\n\t\tkawasekitVersion: envelope.kawasekitVersion,\n\t\tchainId: envelope.chainId,\n\t\tsmartAccountAddress: envelope.smartAccountAddress,\n\t\tsessionKeyAddress: envelope.sessionKeyAddress,\n\t\tserialized: envelope.serialized,\n\t\t...(envelope.expiresAt !== undefined ? { expiresAt: envelope.expiresAt.toString() } : {}),\n\t\t...(envelope.policySummary !== undefined\n\t\t\t? {\n\t\t\t\t\tpolicySummary: {\n\t\t\t\t\t\tjpycAddress: envelope.policySummary.jpycAddress,\n\t\t\t\t\t\tmaxPerTransfer: envelope.policySummary.maxPerTransfer.toString(),\n\t\t\t\t\t\tmaxTransfersPerDay: envelope.policySummary.maxTransfersPerDay,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: {}),\n\t};\n\treturn JSON.stringify(json);\n}\n\n/**\n * Parses a JSON string back into a {@link KawasekitSessionEnvelope}, asserting\n * shape and version invariants.\n *\n * @throws {SessionEnvelopeParseError} On malformed JSON or structural errors.\n * @throws {SessionEnvelopeVersionError} On `kawasekitVersion` mismatch.\n *\n * @example\n * ```ts\n * import { parseSessionEnvelope } from \"kawasekit\";\n *\n * const envelope = parseSessionEnvelope(fs.readFileSync(\"agent.session\", \"utf8\"));\n * ```\n */\nexport function parseSessionEnvelope(input: string): KawasekitSessionEnvelope {\n\tlet raw: unknown;\n\ttry {\n\t\traw = JSON.parse(input);\n\t} catch (cause) {\n\t\tthrow new SessionEnvelopeParseError(\"input is not valid JSON\", { cause });\n\t}\n\tif (raw === null || typeof raw !== \"object\" || Array.isArray(raw)) {\n\t\tthrow new SessionEnvelopeParseError(\"input is not a JSON object\");\n\t}\n\tconst obj = raw as {\n\t\tkawasekitVersion?: unknown;\n\t\tchainId?: unknown;\n\t\tsmartAccountAddress?: unknown;\n\t\tsessionKeyAddress?: unknown;\n\t\tserialized?: unknown;\n\t\texpiresAt?: unknown;\n\t\tpolicySummary?: unknown;\n\t};\n\n\tif (obj.kawasekitVersion !== KAWASEKIT_SESSION_ENVELOPE_VERSION) {\n\t\tthrow new SessionEnvelopeVersionError(KAWASEKIT_SESSION_ENVELOPE_VERSION, obj.kawasekitVersion);\n\t}\n\tconst chainIdNum = assertNumber(obj.chainId, \"chainId\");\n\tif (!isSupportedChainId(chainIdNum)) {\n\t\tthrow new SessionEnvelopeParseError(`chainId ${chainIdNum} is not a kawasekit-supported chain`);\n\t}\n\tconst chainId: SupportedChainId = chainIdNum;\n\tconst smartAccountAddress = assertAddress(obj.smartAccountAddress, \"smartAccountAddress\");\n\tconst sessionKeyAddress = assertAddress(obj.sessionKeyAddress, \"sessionKeyAddress\");\n\tconst serialized = assertString(obj.serialized, \"serialized\");\n\n\tconst expiresAt =\n\t\tobj.expiresAt !== undefined ? parseBigIntString(obj.expiresAt, \"expiresAt\") : undefined;\n\n\tlet policySummary: KawasekitSessionPolicySummary | undefined;\n\tif (obj.policySummary !== undefined) {\n\t\tif (\n\t\t\tobj.policySummary === null ||\n\t\t\ttypeof obj.policySummary !== \"object\" ||\n\t\t\tArray.isArray(obj.policySummary)\n\t\t) {\n\t\t\tthrow new SessionEnvelopeParseError(\"`policySummary` must be a JSON object\");\n\t\t}\n\t\tconst ps = obj.policySummary as {\n\t\t\tjpycAddress?: unknown;\n\t\t\tmaxPerTransfer?: unknown;\n\t\t\tmaxTransfersPerDay?: unknown;\n\t\t};\n\t\tpolicySummary = {\n\t\t\tjpycAddress: assertAddress(ps.jpycAddress, \"policySummary.jpycAddress\"),\n\t\t\tmaxPerTransfer: parseBigIntString(ps.maxPerTransfer, \"policySummary.maxPerTransfer\"),\n\t\t\tmaxTransfersPerDay: assertNumber(ps.maxTransfersPerDay, \"policySummary.maxTransfersPerDay\"),\n\t\t};\n\t}\n\n\tconst base = {\n\t\tkawasekitVersion: KAWASEKIT_SESSION_ENVELOPE_VERSION,\n\t\tchainId,\n\t\tsmartAccountAddress,\n\t\tsessionKeyAddress,\n\t\tserialized,\n\t} as const;\n\tif (expiresAt !== undefined && policySummary !== undefined) {\n\t\treturn { ...base, expiresAt, policySummary };\n\t}\n\tif (expiresAt !== undefined) {\n\t\treturn { ...base, expiresAt };\n\t}\n\tif (policySummary !== undefined) {\n\t\treturn { ...base, policySummary };\n\t}\n\treturn base;\n}\n","/**\n * `issueSessionKey()` — owner-side primitive that builds a Kernel agent\n * account and wraps ZeroDev's `serializePermissionAccount` output in a\n * {@link KawasekitSessionEnvelope}.\n *\n * The envelope is portable: callers can hand it to an agent on a different\n * machine, the agent passes it to {@link restoreSessionAccount} along with the\n * session-key private key, and it ends up holding a `KernelAccountClient`\n * scoped to the policies installed at issue time.\n *\n * The owner retains sudo authority on-chain and can revoke at any time via\n * `revokeSessionKey()` (task 2.5).\n *\n * @packageDocumentation\n */\n\nimport type { Policy } from \"@zerodev/permissions\";\nimport { serializePermissionAccount } from \"@zerodev/permissions\";\nimport { getEntryPoint, KERNEL_V3_1 } from \"@zerodev/sdk/constants\";\nimport type { EntryPointType, GetKernelVersion } from \"@zerodev/sdk/types\";\nimport type { Chain, LocalAccount, PublicClient, Transport } from \"viem\";\nimport { createAgentSmartAccount } from \"../account/session-key\";\nimport { isSupportedChainId, type SupportedChainId } from \"../chains\";\nimport {\n\tKAWASEKIT_SESSION_ENVELOPE_VERSION,\n\ttype KawasekitSessionEnvelope,\n\ttype KawasekitSessionPolicySummary,\n} from \"./envelope\";\n\n/** Parameters for {@link issueSessionKey}. */\nexport interface IssueSessionKeyParams {\n\t/**\n\t * viem `PublicClient` on the chain the smart account will live on. Its\n\t * `chain.id` MUST be a {@link SupportedChainId} and is recorded in the\n\t * envelope so restore-time mismatches fail fast.\n\t */\n\treadonly publicClient: PublicClient<Transport, Chain>;\n\t/** Owner EOA — retains sudo authority. */\n\treadonly ownerSigner: LocalAccount;\n\t/** Session-key EOA — the day-to-day signer the agent will hold. */\n\treadonly sessionKeySigner: LocalAccount;\n\t/**\n\t * Policies the session key must satisfy at userOp validation time\n\t * (e.g. {@link createJpycDailyLimitPolicies}).\n\t */\n\treadonly policies: readonly Policy[];\n\t/** Optional advisory expiry (unix seconds). Recorded in the envelope. */\n\treadonly expiresAt?: bigint;\n\t/** Optional advisory policy summary for host UI. */\n\treadonly policySummary?: KawasekitSessionPolicySummary;\n\t/** EntryPoint override. Defaults to v0.7. */\n\treadonly entryPoint?: EntryPointType<\"0.7\">;\n\t/** Kernel version override. Defaults to {@link KERNEL_V3_1}. */\n\treadonly kernelVersion?: GetKernelVersion<\"0.7\">;\n}\n\n/**\n * Issues a fresh session key for an agent smart account.\n *\n * Notes:\n * - The session-key **private key is not embedded** in the returned envelope.\n * The agent must receive the private key out-of-band; the envelope alone is\n * not enough to spend.\n * - The smart account is **not deployed** by this call. It will be deployed\n * on first userOp from `restoreSessionAccount`.\n *\n * @example\n * ```ts\n * import { parseUnits } from \"viem\";\n * import { privateKeyToAccount } from \"viem/accounts\";\n * import {\n * createJpycDailyLimitPolicies,\n * getJpycAddress,\n * issueSessionKey,\n * JPYC_DECIMALS,\n * polygonAmoy,\n * serializeSessionEnvelope,\n * } from \"kawasekit\";\n *\n * const owner = privateKeyToAccount(process.env.OWNER_PRIVATE_KEY as `0x${string}`);\n * const sessionKey = privateKeyToAccount(process.env.SESSION_KEY_PRIVATE_KEY as `0x${string}`);\n *\n * const envelope = await issueSessionKey({\n * publicClient,\n * ownerSigner: owner,\n * sessionKeySigner: sessionKey,\n * policies: createJpycDailyLimitPolicies({\n * jpycAddress: getJpycAddress(polygonAmoy.id),\n * maxPerTransfer: parseUnits(\"100\", JPYC_DECIMALS),\n * maxTransfersPerDay: 10,\n * }),\n * policySummary: {\n * jpycAddress: getJpycAddress(polygonAmoy.id),\n * maxPerTransfer: parseUnits(\"100\", JPYC_DECIMALS),\n * maxTransfersPerDay: 10,\n * },\n * });\n *\n * fs.writeFileSync(\"agent.session\", serializeSessionEnvelope(envelope));\n * ```\n */\nexport async function issueSessionKey(\n\tparams: IssueSessionKeyParams,\n): Promise<KawasekitSessionEnvelope> {\n\tconst chainId = params.publicClient.chain.id;\n\tif (!isSupportedChainId(chainId)) {\n\t\tthrow new Error(\n\t\t\t`issueSessionKey: publicClient.chain.id ${chainId} is not a kawasekit-supported chain`,\n\t\t);\n\t}\n\tconst supportedChainId: SupportedChainId = chainId;\n\tconst entryPoint = params.entryPoint ?? getEntryPoint(\"0.7\");\n\tconst kernelVersion = params.kernelVersion ?? KERNEL_V3_1;\n\n\tconst account = await createAgentSmartAccount({\n\t\tpublicClient: params.publicClient,\n\t\townerSigner: params.ownerSigner,\n\t\tsessionKeySigner: params.sessionKeySigner,\n\t\tpolicies: params.policies,\n\t\tentryPoint,\n\t\tkernelVersion,\n\t});\n\n\tconst serialized = await serializePermissionAccount(account);\n\n\tconst base = {\n\t\tkawasekitVersion: KAWASEKIT_SESSION_ENVELOPE_VERSION,\n\t\tchainId: supportedChainId,\n\t\tsmartAccountAddress: account.address,\n\t\tsessionKeyAddress: params.sessionKeySigner.address,\n\t\tserialized,\n\t} as const;\n\tif (params.expiresAt !== undefined && params.policySummary !== undefined) {\n\t\treturn {\n\t\t\t...base,\n\t\t\texpiresAt: params.expiresAt,\n\t\t\tpolicySummary: params.policySummary,\n\t\t};\n\t}\n\tif (params.expiresAt !== undefined) {\n\t\treturn { ...base, expiresAt: params.expiresAt };\n\t}\n\tif (params.policySummary !== undefined) {\n\t\treturn { ...base, policySummary: params.policySummary };\n\t}\n\treturn base;\n}\n","/**\n * `restoreSessionAccount()` — agent-side primitive that unwraps a\n * {@link KawasekitSessionEnvelope} back into a usable Kernel account scoped\n * to the policies installed at issue time.\n *\n * Three invariants are checked **before** touching ZeroDev's deserialization\n * so that misconfiguration manifests as a typed error here, not a confusing\n * UserOp-time revert:\n *\n * 1. `envelope.kawasekitVersion` matches the current envelope version\n * (already enforced by {@link parseSessionEnvelope}; re-checked here for\n * callers who construct the envelope object directly).\n * 2. `envelope.chainId === publicClient.chain.id`.\n * 3. `envelope.sessionKeyAddress` matches the provided `sessionKeySigner`.\n *\n * @packageDocumentation\n */\n\nimport { deserializePermissionAccount } from \"@zerodev/permissions\";\nimport { toECDSASigner } from \"@zerodev/permissions/signers\";\nimport type { CreateKernelAccountReturnType } from \"@zerodev/sdk\";\nimport { getEntryPoint, KERNEL_V3_1 } from \"@zerodev/sdk/constants\";\nimport type { EntryPointType, GetKernelVersion } from \"@zerodev/sdk/types\";\nimport { type Chain, getAddress, type LocalAccount, type PublicClient, type Transport } from \"viem\";\nimport { KAWASEKIT_SESSION_ENVELOPE_VERSION, type KawasekitSessionEnvelope } from \"./envelope\";\nimport {\n\tSessionEnvelopeChainMismatchError,\n\tSessionEnvelopeSignerMismatchError,\n\tSessionEnvelopeVersionError,\n} from \"./errors\";\n\n/** Parameters for {@link restoreSessionAccount}. */\nexport interface RestoreSessionAccountParams {\n\t/** Must be on the same chain the envelope was issued for. */\n\treadonly publicClient: PublicClient<Transport, Chain>;\n\t/** Envelope produced by {@link issueSessionKey} (or parsed via {@link parseSessionEnvelope}). */\n\treadonly envelope: KawasekitSessionEnvelope;\n\t/**\n\t * The session-key signer the agent holds. Its address MUST equal\n\t * `envelope.sessionKeyAddress` — otherwise the restored account would\n\t * sign userOps that the on-chain permission validator rejects.\n\t */\n\treadonly sessionKeySigner: LocalAccount;\n\t/** EntryPoint override. Defaults to v0.7. */\n\treadonly entryPoint?: EntryPointType<\"0.7\">;\n\t/** Kernel version override. Defaults to {@link KERNEL_V3_1}. */\n\treadonly kernelVersion?: GetKernelVersion<\"0.7\">;\n}\n\n/**\n * Rebuilds the Kernel account from an envelope + the session-key signer.\n *\n * @throws {SessionEnvelopeVersionError} If `envelope.kawasekitVersion` does\n * not match the current envelope version.\n * @throws {SessionEnvelopeChainMismatchError} If `envelope.chainId !==\n * publicClient.chain.id`.\n * @throws {SessionEnvelopeSignerMismatchError} If `sessionKeySigner.address !==\n * envelope.sessionKeyAddress`.\n *\n * @example\n * ```ts\n * import { createPublicClient, http } from \"viem\";\n * import { privateKeyToAccount } from \"viem/accounts\";\n * import {\n * parseSessionEnvelope,\n * polygonAmoy,\n * restoreSessionAccount,\n * } from \"kawasekit\";\n *\n * const publicClient = createPublicClient({\n * chain: polygonAmoy,\n * transport: http(),\n * });\n * const envelope = parseSessionEnvelope(fs.readFileSync(\"agent.session\", \"utf8\"));\n * const sessionKey = privateKeyToAccount(process.env.SESSION_KEY_PRIVATE_KEY as `0x${string}`);\n *\n * const account = await restoreSessionAccount({\n * publicClient,\n * envelope,\n * sessionKeySigner: sessionKey,\n * });\n * ```\n */\nexport async function restoreSessionAccount(\n\tparams: RestoreSessionAccountParams,\n): Promise<CreateKernelAccountReturnType<\"0.7\">> {\n\tconst { publicClient, envelope, sessionKeySigner } = params;\n\n\tif (envelope.kawasekitVersion !== KAWASEKIT_SESSION_ENVELOPE_VERSION) {\n\t\tthrow new SessionEnvelopeVersionError(\n\t\t\tKAWASEKIT_SESSION_ENVELOPE_VERSION,\n\t\t\tenvelope.kawasekitVersion,\n\t\t);\n\t}\n\tif (publicClient.chain.id !== envelope.chainId) {\n\t\tthrow new SessionEnvelopeChainMismatchError(envelope.chainId, publicClient.chain.id);\n\t}\n\tif (getAddress(sessionKeySigner.address) !== getAddress(envelope.sessionKeyAddress)) {\n\t\tthrow new SessionEnvelopeSignerMismatchError(\n\t\t\tenvelope.sessionKeyAddress,\n\t\t\tsessionKeySigner.address,\n\t\t);\n\t}\n\n\tconst entryPoint = params.entryPoint ?? getEntryPoint(\"0.7\");\n\tconst kernelVersion = params.kernelVersion ?? KERNEL_V3_1;\n\tconst modularSigner = await toECDSASigner({ signer: sessionKeySigner });\n\n\treturn deserializePermissionAccount(\n\t\tpublicClient,\n\t\tentryPoint,\n\t\tkernelVersion,\n\t\tenvelope.serialized,\n\t\tmodularSigner,\n\t);\n}\n","/**\n * `revokeSessionKey()` — owner-side primitive that uninstalls a session-key\n * permission validator from the agent's smart account.\n *\n * Implementation strategy (per plan §risk #3): ZeroDev does not expose a\n * dedicated revoke helper, so we re-derive the `PermissionPlugin` from the\n * envelope's `sessionKeyAddress` + the same policies that were installed at\n * issue time, then submit a sudo UserOp via `@zerodev/sdk`'s\n * {@link uninstallPlugin} action. After the receipt, the session key can no\n * longer sign UserOps the validator would accept.\n *\n * In-flight UserOps already submitted to the bundler but not yet mined can\n * still settle before the uninstall transaction lands. A future \"soft revoke\"\n * via `invalidateNonce` on the session-key validator's nonce key will close\n * that race; tracked for M5 (the helper signature accepts an\n * `invalidateInFlightNonces` option today and throws `\"not implemented\"` to\n * lock in the API shape). Until M5 lands, see\n * `docs/recipes/revoke-race-mitigation.md` for the four-layer operator\n * playbook (SDK call → merchant kill-switch → paymaster sponsorship\n * freeze → bundler mempool monitoring).\n *\n * @packageDocumentation\n */\n\nimport type { Policy } from \"@zerodev/permissions\";\nimport { toPermissionValidator } from \"@zerodev/permissions\";\nimport { toECDSASigner } from \"@zerodev/permissions/signers\";\nimport { uninstallPlugin } from \"@zerodev/sdk\";\nimport { getEntryPoint, KERNEL_V3_1 } from \"@zerodev/sdk/constants\";\nimport type { EntryPointType, GetKernelVersion } from \"@zerodev/sdk/types\";\nimport { getAddress, type Hash, type LocalAccount } from \"viem\";\nimport type { ConfiguredKernelClient } from \"../client/transfer-jpyc\";\nimport type { KawasekitSessionEnvelope } from \"./envelope\";\nimport { SessionEnvelopeSignerMismatchError } from \"./errors\";\n\n/** Parameters for {@link revokeSessionKey}. */\nexport interface RevokeSessionKeyParams {\n\t/**\n\t * The owner's sudo Kernel client — the only entity that can call\n\t * `uninstallValidation` on the agent account.\n\t *\n\t * **CRITICAL: must be a SUDO-ONLY kernel account** (i.e.\n\t * `createKernelAccount(publicClient, { plugins: { sudo: ecdsaValidator } })`\n\t * — no `regular` plugin). If you pass a client whose account also has the\n\t * session-key permission validator wired as `regular`, ZeroDev signs\n\t * userOps with that validator by default and the spending policy will\n\t * reject `uninstallValidation` at the validation phase (`AA23 reverted`).\n\t *\n\t * The counterfactual smart-account address only depends on the sudo\n\t * validator in Kernel v3.1, so a sudo-only client points at the SAME\n\t * account as one built with both sudo + regular.\n\t *\n\t * Its `account.address` MUST equal `envelope.smartAccountAddress`.\n\t */\n\treadonly ownerKernelClient: ConfiguredKernelClient;\n\t/** The envelope of the session being revoked. */\n\treadonly envelope: KawasekitSessionEnvelope;\n\t/**\n\t * A LocalAccount whose address equals `envelope.sessionKeyAddress`. Used\n\t * to reconstruct the validator's on-chain identifier; no signing is\n\t * actually performed with this account during revoke.\n\t */\n\treadonly sessionKeySigner: LocalAccount;\n\t/**\n\t * The policies that were installed at issue time. ZeroDev does not store\n\t * these on-chain in a retrievable form, so the caller MUST re-supply\n\t * them. Mismatches surface as an `uninstallValidation` revert at userOp\n\t * validation time.\n\t */\n\treadonly policies: readonly Policy[];\n\t/**\n\t * Future option: also invalidate the session-key validator's nonce key\n\t * to kill in-flight UserOps. Not implemented today — passing `true`\n\t * throws. Tracked for M5; see `docs/THREAT_MODEL.md` §6.3 and\n\t * `docs/recipes/revoke-race-mitigation.md` for the operator playbook to\n\t * use until then.\n\t */\n\treadonly invalidateInFlightNonces?: boolean;\n\t/** EntryPoint override. Defaults to v0.7. */\n\treadonly entryPoint?: EntryPointType<\"0.7\">;\n\t/** Kernel version override. Defaults to {@link KERNEL_V3_1}. */\n\treadonly kernelVersion?: GetKernelVersion<\"0.7\">;\n\t/**\n\t * If `false`, return after submitting the UserOp without waiting for the\n\t * bundler receipt. Default `true` (wait).\n\t */\n\treadonly waitForReceipt?: boolean;\n}\n\n/** Result of {@link revokeSessionKey}. */\nexport interface RevokeSessionKeyResult {\n\t/** Hash of the uninstall UserOp. */\n\treadonly userOpHash: Hash;\n\t/** Bundler transaction hash, present when `waitForReceipt` (default true). */\n\treadonly transactionHash: Hash | null;\n\t/** `true` if the bundler reported success, `null` if not awaited. */\n\treadonly success: boolean | null;\n}\n\n/**\n * Uninstalls a session-key permission validator from the agent's smart\n * account. After the returned UserOp lands, the session key can no longer\n * authorise actions.\n *\n * @throws {SessionEnvelopeSignerMismatchError} If `sessionKeySigner.address`\n * does not match `envelope.sessionKeyAddress`.\n * @throws {Error} If `invalidateInFlightNonces` is `true` (planned for M5;\n * see `docs/THREAT_MODEL.md` §6.3 and\n * `docs/recipes/revoke-race-mitigation.md` for the four-layer\n * operator playbook to use until then).\n *\n * @example\n * ```ts\n * import { signerToEcdsaValidator } from \"@zerodev/ecdsa-validator\";\n * import { createKernelAccount, createKernelAccountClient } from \"@zerodev/sdk\";\n * import { getEntryPoint, KERNEL_V3_1 } from \"@zerodev/sdk/constants\";\n * import { revokeSessionKey } from \"kawasekit\";\n *\n * // Build a SUDO-ONLY kernel account for the owner — see param JSDoc.\n * const sudoValidator = await signerToEcdsaValidator(publicClient, {\n * signer: owner,\n * entryPoint: getEntryPoint(\"0.7\"),\n * kernelVersion: KERNEL_V3_1,\n * });\n * const ownerSudoAccount = await createKernelAccount(publicClient, {\n * plugins: { sudo: sudoValidator },\n * entryPoint: getEntryPoint(\"0.7\"),\n * kernelVersion: KERNEL_V3_1,\n * });\n * const ownerKernelClient = createKernelAccountClient({\n * account: ownerSudoAccount,\n * chain,\n * client: publicClient,\n * bundlerTransport,\n * paymaster,\n * });\n *\n * await revokeSessionKey({\n * ownerKernelClient,\n * envelope,\n * sessionKeySigner,\n * policies: createJpycDailyLimitPolicies({ ... }),\n * });\n * ```\n */\nexport async function revokeSessionKey(\n\tparams: RevokeSessionKeyParams,\n): Promise<RevokeSessionKeyResult> {\n\tconst { ownerKernelClient, envelope, sessionKeySigner, policies } = params;\n\n\tif (params.invalidateInFlightNonces === true) {\n\t\tthrow new Error(\n\t\t\t\"revokeSessionKey: `invalidateInFlightNonces` is not implemented yet — the helper signature accepts the option to lock in the API shape, but in-flight nonce invalidation lands in M5. Hard revoke via uninstallPlugin is what runs today; see docs/recipes/revoke-race-mitigation.md for the four-layer operator playbook to use until then.\",\n\t\t);\n\t}\n\n\tif (getAddress(sessionKeySigner.address) !== getAddress(envelope.sessionKeyAddress)) {\n\t\tthrow new SessionEnvelopeSignerMismatchError(\n\t\t\tenvelope.sessionKeyAddress,\n\t\t\tsessionKeySigner.address,\n\t\t);\n\t}\n\n\tif (getAddress(ownerKernelClient.account.address) !== getAddress(envelope.smartAccountAddress)) {\n\t\tthrow new Error(\n\t\t\t`revokeSessionKey: ownerKernelClient is bound to ${ownerKernelClient.account.address}, but envelope is for ${envelope.smartAccountAddress}.`,\n\t\t);\n\t}\n\n\tconst entryPoint = params.entryPoint ?? getEntryPoint(\"0.7\");\n\tconst kernelVersion = params.kernelVersion ?? KERNEL_V3_1;\n\n\tif (ownerKernelClient.client === undefined) {\n\t\tthrow new Error(\n\t\t\t\"revokeSessionKey: ownerKernelClient.client is undefined — pass `client: publicClient` when constructing the Kernel client so the validator can be reconstructed.\",\n\t\t);\n\t}\n\n\tconst modularSigner = await toECDSASigner({ signer: sessionKeySigner });\n\tconst permissionPlugin = await toPermissionValidator(ownerKernelClient.client, {\n\t\tsigner: modularSigner,\n\t\tpolicies: [...policies],\n\t\tentryPoint,\n\t\tkernelVersion,\n\t});\n\n\tconst userOpHash = await uninstallPlugin(ownerKernelClient, {\n\t\tplugin: permissionPlugin,\n\t});\n\n\tif (params.waitForReceipt === false) {\n\t\treturn { userOpHash, transactionHash: null, success: null };\n\t}\n\n\tconst receipt = await ownerKernelClient.waitForUserOperationReceipt({\n\t\thash: userOpHash,\n\t});\n\treturn {\n\t\tuserOpHash,\n\t\ttransactionHash: receipt.receipt.transactionHash,\n\t\tsuccess: receipt.success,\n\t};\n}\n","/**\n * `rotateSessionKey()` — a thin compositional helper that revokes the\n * current session key and issues a new one in sequence.\n *\n * Compose-don't-conflate: rotate is just `revoke` followed by `issue`. Both\n * primitives are exposed individually so callers who need finer control\n * (e.g. revoke now, issue tomorrow with different policies) can chain them\n * themselves.\n *\n * @packageDocumentation\n */\n\nimport type { KawasekitSessionEnvelope } from \"./envelope\";\nimport { type IssueSessionKeyParams, issueSessionKey } from \"./issue\";\nimport {\n\ttype RevokeSessionKeyParams,\n\ttype RevokeSessionKeyResult,\n\trevokeSessionKey,\n} from \"./revoke\";\n\n/** Parameters for {@link rotateSessionKey}. */\nexport interface RotateSessionKeyParams {\n\t/** Inputs for revoking the current session. `waitForReceipt` is forced `true`. */\n\treadonly revoke: Omit<RevokeSessionKeyParams, \"waitForReceipt\">;\n\t/** Inputs for issuing the replacement session. */\n\treadonly issue: IssueSessionKeyParams;\n}\n\n/** Result of {@link rotateSessionKey}. */\nexport interface RotateSessionKeyResult {\n\t/** Outcome of the revoke step. */\n\treadonly revoke: RevokeSessionKeyResult;\n\t/** The freshly issued replacement envelope. */\n\treadonly envelope: KawasekitSessionEnvelope;\n}\n\n/**\n * Atomically rotate the agent's session key: revoke the old, issue the new.\n *\n * The revoke is always awaited to the bundler receipt — issuing a replacement\n * before the old key is actually disarmed would leave two valid signers at\n * once, defeating the point.\n *\n * @example\n * ```ts\n * import { rotateSessionKey } from \"kawasekit\";\n *\n * const { revoke, envelope } = await rotateSessionKey({\n * revoke: {\n * ownerKernelClient,\n * envelope: oldEnvelope,\n * sessionKeySigner: oldSessionKeySigner,\n * policies: oldPolicies,\n * },\n * issue: {\n * publicClient,\n * ownerSigner,\n * sessionKeySigner: newSessionKeySigner,\n * policies: newPolicies,\n * },\n * });\n * ```\n */\nexport async function rotateSessionKey(\n\tparams: RotateSessionKeyParams,\n): Promise<RotateSessionKeyResult> {\n\tconst revoke = await revokeSessionKey({ ...params.revoke, waitForReceipt: true });\n\tconst envelope = await issueSessionKey(params.issue);\n\treturn { revoke, envelope };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/account/session-key.ts","../src/session/errors.ts","../src/session/envelope.ts","../src/session/issue.ts","../src/session/restore.ts","../src/session/revoke.ts","../src/session/rotate.ts"],"names":["getEntryPoint","KERNEL_V3_1","toECDSASigner","getAddress","toPermissionValidator"],"mappings":"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","file":"chunk-N3CVLISJ.js","sourcesContent":["/**\n * Agent smart account = Kernel v3.1 + ECDSA sudo validator + session-key\n * permission validator.\n *\n * The owner EOA keeps full control (sudo) and can revoke / rotate the session\n * key at any time. The session key is the day-to-day signer the AI agent\n * holds; whatever policies you attach (see {@link createJpycDailyLimitPolicies})\n * are enforced at the ERC-4337 validation phase by ZeroDev's\n * `PermissionValidator`. Violating userOps revert before execution — they\n * never spend any of the smart account's funds, and a sponsored bundler\n * cannot be tricked into paying for them either.\n *\n * @packageDocumentation\n */\n\nimport { signerToEcdsaValidator } from \"@zerodev/ecdsa-validator\";\nimport type { Policy } from \"@zerodev/permissions\";\nimport { toPermissionValidator } from \"@zerodev/permissions\";\nimport { toECDSASigner } from \"@zerodev/permissions/signers\";\nimport type { CreateKernelAccountReturnType } from \"@zerodev/sdk\";\nimport { createKernelAccount } from \"@zerodev/sdk\";\nimport { getEntryPoint, KERNEL_V3_1 } from \"@zerodev/sdk/constants\";\nimport type { EntryPointType, GetKernelVersion } from \"@zerodev/sdk/types\";\nimport type { Chain, LocalAccount, PublicClient, Transport } from \"viem\";\n\n/** Parameters for {@link createAgentSmartAccount}. */\nexport interface CreateAgentSmartAccountParams {\n\t/**\n\t * viem `PublicClient` used to read on-chain state during account derivation.\n\t */\n\treadonly publicClient: PublicClient<Transport, Chain | undefined>;\n\t/**\n\t * The owner EOA. Retains sudo authority — can install new plugins,\n\t * revoke / rotate the session key, and bypass any policy.\n\t */\n\treadonly ownerSigner: LocalAccount;\n\t/**\n\t * The day-to-day signer the agent holds. Authority is limited to whatever\n\t * `policies` allow — by default it can do nothing.\n\t */\n\treadonly sessionKeySigner: LocalAccount;\n\t/**\n\t * ZeroDev policies (e.g. {@link createJpycDailyLimitPolicies}) the session\n\t * key must satisfy at userOp validation time.\n\t */\n\treadonly policies: readonly Policy[];\n\t/**\n\t * EntryPoint version + address. Defaults to v0.7 at the canonical\n\t * ERC-4337 entry-point address.\n\t */\n\treadonly entryPoint?: EntryPointType<\"0.7\">;\n\t/** Kernel version. Defaults to {@link KERNEL_V3_1}. */\n\treadonly kernelVersion?: GetKernelVersion<\"0.7\">;\n}\n\n/**\n * Builds a Kernel v3.1 smart account with sudo (owner) + regular (session key)\n * validators wired up.\n *\n * @example\n * ```ts\n * import { parseUnits } from \"viem\";\n * import { privateKeyToAccount } from \"viem/accounts\";\n * import {\n * createAgentSmartAccount,\n * createJpycDailyLimitPolicies,\n * getJpycAddress,\n * JPYC_DECIMALS,\n * polygonAmoy,\n * } from \"kawasekit\";\n *\n * const owner = privateKeyToAccount(process.env.OWNER_PRIVATE_KEY as `0x${string}`);\n * const sessionKey = privateKeyToAccount(process.env.SESSION_KEY_PRIVATE_KEY as `0x${string}`);\n *\n * const account = await createAgentSmartAccount({\n * publicClient,\n * ownerSigner: owner,\n * sessionKeySigner: sessionKey,\n * policies: createJpycDailyLimitPolicies({\n * jpycAddress: getJpycAddress(polygonAmoy.id),\n * maxPerTransfer: parseUnits(\"100\", JPYC_DECIMALS),\n * maxTransfersPerDay: 10,\n * }),\n * });\n * ```\n */\nexport async function createAgentSmartAccount(\n\tparams: CreateAgentSmartAccountParams,\n): Promise<CreateKernelAccountReturnType<\"0.7\">> {\n\tconst entryPoint = params.entryPoint ?? getEntryPoint(\"0.7\");\n\tconst kernelVersion = params.kernelVersion ?? KERNEL_V3_1;\n\n\tconst sudoValidator = await signerToEcdsaValidator(params.publicClient, {\n\t\tsigner: params.ownerSigner,\n\t\tentryPoint,\n\t\tkernelVersion,\n\t});\n\n\tconst modularSessionSigner = await toECDSASigner({ signer: params.sessionKeySigner });\n\n\tconst permissionValidator = await toPermissionValidator(params.publicClient, {\n\t\tsigner: modularSessionSigner,\n\t\tpolicies: [...params.policies],\n\t\tentryPoint,\n\t\tkernelVersion,\n\t});\n\n\treturn createKernelAccount(params.publicClient, {\n\t\tplugins: {\n\t\t\tsudo: sudoValidator,\n\t\t\tregular: permissionValidator,\n\t\t},\n\t\tentryPoint,\n\t\tkernelVersion,\n\t});\n}\n","/**\n * Typed errors thrown by the `kawasekit/session` modules.\n *\n * Centralised so consumers can `instanceof`-discriminate without importing\n * deep paths.\n *\n * @packageDocumentation\n */\n\nimport type { Address } from \"viem\";\n\n/**\n * Thrown when {@link parseSessionEnvelope} encounters an envelope whose\n * `kawasekitVersion` does not match the current\n * {@link KAWASEKIT_SESSION_ENVELOPE_VERSION}.\n *\n * The version field is intentionally a string (\"1\") so that future migrations\n * can introduce non-numeric variants (e.g. \"1-jwe\") without breaking the\n * parser ordering.\n */\nexport class SessionEnvelopeVersionError extends Error {\n\treadonly expected: string;\n\treadonly received: unknown;\n\n\tconstructor(expected: string, received: unknown) {\n\t\tsuper(\n\t\t\t`Session envelope version mismatch: expected ${JSON.stringify(expected)}, got ${JSON.stringify(received)}.`,\n\t\t);\n\t\tthis.name = \"SessionEnvelopeVersionError\";\n\t\tthis.expected = expected;\n\t\tthis.received = received;\n\t}\n}\n\n/**\n * Thrown by `restoreSessionAccount()` when an envelope's `chainId` differs\n * from the chain the consumer is restoring on. Catches the common mistake of\n * issuing on Polygon Amoy and trying to restore on Polygon mainnet.\n */\nexport class SessionEnvelopeChainMismatchError extends Error {\n\treadonly envelopeChainId: number;\n\treadonly clientChainId: number;\n\n\tconstructor(envelopeChainId: number, clientChainId: number) {\n\t\tsuper(\n\t\t\t`Session envelope is for chain ${envelopeChainId} but the restore client is on chain ${clientChainId}.`,\n\t\t);\n\t\tthis.name = \"SessionEnvelopeChainMismatchError\";\n\t\tthis.envelopeChainId = envelopeChainId;\n\t\tthis.clientChainId = clientChainId;\n\t}\n}\n\n/**\n * Thrown by `restoreSessionAccount()` when the session-key signer the consumer\n * passes does not match the `sessionKeyAddress` recorded in the envelope.\n *\n * Defence against accidentally restoring with the wrong private key — which\n * would otherwise succeed locally and only fail at UserOp validation time.\n */\nexport class SessionEnvelopeSignerMismatchError extends Error {\n\treadonly envelopeSignerAddress: Address;\n\treadonly providedSignerAddress: Address;\n\n\tconstructor(envelopeSignerAddress: Address, providedSignerAddress: Address) {\n\t\tsuper(\n\t\t\t`Session envelope was issued for signer ${envelopeSignerAddress}, but the provided session-key signer is ${providedSignerAddress}.`,\n\t\t);\n\t\tthis.name = \"SessionEnvelopeSignerMismatchError\";\n\t\tthis.envelopeSignerAddress = envelopeSignerAddress;\n\t\tthis.providedSignerAddress = providedSignerAddress;\n\t}\n}\n\n/**\n * Thrown when {@link parseSessionEnvelope} cannot decode the input as a\n * structurally valid envelope (malformed JSON, missing fields, bad types).\n */\nexport class SessionEnvelopeParseError extends Error {\n\treadonly reason: string;\n\n\tconstructor(reason: string, options?: { cause?: unknown }) {\n\t\tsuper(`Failed to parse session envelope: ${reason}`, options);\n\t\tthis.name = \"SessionEnvelopeParseError\";\n\t\tthis.reason = reason;\n\t}\n}\n","/**\n * `KawasekitSessionEnvelope` — kawasekit's typed wrapper around ZeroDev's\n * opaque `serializePermissionAccount` blob.\n *\n * Why wrap ZeroDev's blob rather than use it directly?\n *\n * - **Fail-fast on restore**: chainId / version / signer mismatches surface as\n * typed errors instead of confusing UserOp-time reverts.\n * - **Host-UI affordances**: `expiresAt` and `policySummary` are advisory\n * fields a wallet can render (\"this session expires in 2 hours, max 100\n * JPYC/day\") before handing the blob to {@link restoreSessionAccount}.\n * - **Version pin**: when ZeroDev changes their serialization format we bump\n * {@link KAWASEKIT_SESSION_ENVELOPE_VERSION} and provide a migration; the\n * inner `serialized` field stays opaque.\n *\n * Wire format: a single JSON string. Bigint fields (`expiresAt`,\n * `policySummary.maxPerTransfer`) round-trip via decimal-string encoding so\n * the JSON itself is portable through any transport (env var, HTTP header,\n * file).\n *\n * @packageDocumentation\n */\n\nimport { type Address, isAddress } from \"viem\";\nimport { isSupportedChainId, type SupportedChainId } from \"../chains\";\nimport { SessionEnvelopeParseError, SessionEnvelopeVersionError } from \"./errors\";\n\n/**\n * Current envelope format version. Bumped when the envelope schema changes\n * in a way that breaks backward compatibility.\n */\nexport const KAWASEKIT_SESSION_ENVELOPE_VERSION = \"1\" as const;\n\n/** Type of {@link KAWASEKIT_SESSION_ENVELOPE_VERSION}. */\nexport type KawasekitSessionEnvelopeVersion = typeof KAWASEKIT_SESSION_ENVELOPE_VERSION;\n\n/**\n * Advisory summary of the spending policy attached to a session key. Useful\n * for host UI; **not** consulted at validation time (the on-chain validator\n * is the source of truth).\n */\nexport interface KawasekitSessionPolicySummary {\n\treadonly jpycAddress: Address;\n\treadonly maxPerTransfer: bigint;\n\treadonly maxTransfersPerDay: number;\n}\n\n/** kawasekit's typed envelope around a ZeroDev session-key serialization. */\nexport interface KawasekitSessionEnvelope {\n\treadonly kawasekitVersion: KawasekitSessionEnvelopeVersion;\n\treadonly chainId: SupportedChainId;\n\treadonly smartAccountAddress: Address;\n\treadonly sessionKeyAddress: Address;\n\t/** Optional unix-seconds expiry. Advisory + ideally enforced by a `TimestampPolicy`. */\n\treadonly expiresAt?: bigint;\n\treadonly policySummary?: KawasekitSessionPolicySummary;\n\t/** Opaque ZeroDev `serializePermissionAccount` output. */\n\treadonly serialized: string;\n}\n\n// ---------------------------------------------------------------------------\n// Wire (JSON) shape\n// ---------------------------------------------------------------------------\n\n/**\n * Internal: the JSON shape we (de)serialize to/from. Bigint fields are stored\n * as decimal strings. Kept separate from {@link KawasekitSessionEnvelope} so\n * the public type stays bigint-friendly while the wire stays string-only.\n */\ninterface SessionEnvelopeJson {\n\treadonly kawasekitVersion: string;\n\treadonly chainId: number;\n\treadonly smartAccountAddress: string;\n\treadonly sessionKeyAddress: string;\n\treadonly expiresAt?: string;\n\treadonly policySummary?: {\n\t\treadonly jpycAddress: string;\n\t\treadonly maxPerTransfer: string;\n\t\treadonly maxTransfersPerDay: number;\n\t};\n\treadonly serialized: string;\n}\n\n// ---------------------------------------------------------------------------\n// Validation helpers\n// ---------------------------------------------------------------------------\n\nconst UINT_DECIMAL = /^(0|[1-9][0-9]*)$/;\n\nfunction assertAddress(value: unknown, field: string): Address {\n\tif (typeof value !== \"string\" || !isAddress(value, { strict: false })) {\n\t\tthrow new SessionEnvelopeParseError(`\\`${field}\\` is not a valid address: ${String(value)}`);\n\t}\n\treturn value as Address;\n}\n\nfunction assertString(value: unknown, field: string): string {\n\tif (typeof value !== \"string\" || value === \"\") {\n\t\tthrow new SessionEnvelopeParseError(`\\`${field}\\` must be a non-empty string`);\n\t}\n\treturn value;\n}\n\nfunction assertNumber(value: unknown, field: string): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) {\n\t\tthrow new SessionEnvelopeParseError(`\\`${field}\\` must be a finite number`);\n\t}\n\treturn value;\n}\n\nfunction parseBigIntString(value: unknown, field: string): bigint {\n\tif (typeof value !== \"string\" || !UINT_DECIMAL.test(value)) {\n\t\tthrow new SessionEnvelopeParseError(\n\t\t\t`\\`${field}\\` must be a non-negative decimal string: ${String(value)}`,\n\t\t);\n\t}\n\treturn BigInt(value);\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Serialises a {@link KawasekitSessionEnvelope} to a transportable JSON string.\n *\n * The output is plain UTF-8 JSON (no base64). Callers who need\n * URL-/header-safe transport can base64-encode the result themselves.\n *\n * @example\n * ```ts\n * import { serializeSessionEnvelope } from \"kawasekit\";\n *\n * const blob = serializeSessionEnvelope(envelope);\n * fs.writeFileSync(\"agent.session\", blob);\n * ```\n */\nexport function serializeSessionEnvelope(envelope: KawasekitSessionEnvelope): string {\n\tconst json: SessionEnvelopeJson = {\n\t\tkawasekitVersion: envelope.kawasekitVersion,\n\t\tchainId: envelope.chainId,\n\t\tsmartAccountAddress: envelope.smartAccountAddress,\n\t\tsessionKeyAddress: envelope.sessionKeyAddress,\n\t\tserialized: envelope.serialized,\n\t\t...(envelope.expiresAt !== undefined ? { expiresAt: envelope.expiresAt.toString() } : {}),\n\t\t...(envelope.policySummary !== undefined\n\t\t\t? {\n\t\t\t\t\tpolicySummary: {\n\t\t\t\t\t\tjpycAddress: envelope.policySummary.jpycAddress,\n\t\t\t\t\t\tmaxPerTransfer: envelope.policySummary.maxPerTransfer.toString(),\n\t\t\t\t\t\tmaxTransfersPerDay: envelope.policySummary.maxTransfersPerDay,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: {}),\n\t};\n\treturn JSON.stringify(json);\n}\n\n/**\n * Parses a JSON string back into a {@link KawasekitSessionEnvelope}, asserting\n * shape and version invariants.\n *\n * @throws {SessionEnvelopeParseError} On malformed JSON or structural errors.\n * @throws {SessionEnvelopeVersionError} On `kawasekitVersion` mismatch.\n *\n * @example\n * ```ts\n * import { parseSessionEnvelope } from \"kawasekit\";\n *\n * const envelope = parseSessionEnvelope(fs.readFileSync(\"agent.session\", \"utf8\"));\n * ```\n */\nexport function parseSessionEnvelope(input: string): KawasekitSessionEnvelope {\n\tlet raw: unknown;\n\ttry {\n\t\traw = JSON.parse(input);\n\t} catch (cause) {\n\t\tthrow new SessionEnvelopeParseError(\"input is not valid JSON\", { cause });\n\t}\n\tif (raw === null || typeof raw !== \"object\" || Array.isArray(raw)) {\n\t\tthrow new SessionEnvelopeParseError(\"input is not a JSON object\");\n\t}\n\tconst obj = raw as {\n\t\tkawasekitVersion?: unknown;\n\t\tchainId?: unknown;\n\t\tsmartAccountAddress?: unknown;\n\t\tsessionKeyAddress?: unknown;\n\t\tserialized?: unknown;\n\t\texpiresAt?: unknown;\n\t\tpolicySummary?: unknown;\n\t};\n\n\tif (obj.kawasekitVersion !== KAWASEKIT_SESSION_ENVELOPE_VERSION) {\n\t\tthrow new SessionEnvelopeVersionError(KAWASEKIT_SESSION_ENVELOPE_VERSION, obj.kawasekitVersion);\n\t}\n\tconst chainIdNum = assertNumber(obj.chainId, \"chainId\");\n\tif (!isSupportedChainId(chainIdNum)) {\n\t\tthrow new SessionEnvelopeParseError(`chainId ${chainIdNum} is not a kawasekit-supported chain`);\n\t}\n\tconst chainId: SupportedChainId = chainIdNum;\n\tconst smartAccountAddress = assertAddress(obj.smartAccountAddress, \"smartAccountAddress\");\n\tconst sessionKeyAddress = assertAddress(obj.sessionKeyAddress, \"sessionKeyAddress\");\n\tconst serialized = assertString(obj.serialized, \"serialized\");\n\n\tconst expiresAt =\n\t\tobj.expiresAt !== undefined ? parseBigIntString(obj.expiresAt, \"expiresAt\") : undefined;\n\n\tlet policySummary: KawasekitSessionPolicySummary | undefined;\n\tif (obj.policySummary !== undefined) {\n\t\tif (\n\t\t\tobj.policySummary === null ||\n\t\t\ttypeof obj.policySummary !== \"object\" ||\n\t\t\tArray.isArray(obj.policySummary)\n\t\t) {\n\t\t\tthrow new SessionEnvelopeParseError(\"`policySummary` must be a JSON object\");\n\t\t}\n\t\tconst ps = obj.policySummary as {\n\t\t\tjpycAddress?: unknown;\n\t\t\tmaxPerTransfer?: unknown;\n\t\t\tmaxTransfersPerDay?: unknown;\n\t\t};\n\t\tpolicySummary = {\n\t\t\tjpycAddress: assertAddress(ps.jpycAddress, \"policySummary.jpycAddress\"),\n\t\t\tmaxPerTransfer: parseBigIntString(ps.maxPerTransfer, \"policySummary.maxPerTransfer\"),\n\t\t\tmaxTransfersPerDay: assertNumber(ps.maxTransfersPerDay, \"policySummary.maxTransfersPerDay\"),\n\t\t};\n\t}\n\n\tconst base = {\n\t\tkawasekitVersion: KAWASEKIT_SESSION_ENVELOPE_VERSION,\n\t\tchainId,\n\t\tsmartAccountAddress,\n\t\tsessionKeyAddress,\n\t\tserialized,\n\t} as const;\n\tif (expiresAt !== undefined && policySummary !== undefined) {\n\t\treturn { ...base, expiresAt, policySummary };\n\t}\n\tif (expiresAt !== undefined) {\n\t\treturn { ...base, expiresAt };\n\t}\n\tif (policySummary !== undefined) {\n\t\treturn { ...base, policySummary };\n\t}\n\treturn base;\n}\n","/**\n * `issueSessionKey()` — owner-side primitive that builds a Kernel agent\n * account and wraps ZeroDev's `serializePermissionAccount` output in a\n * {@link KawasekitSessionEnvelope}.\n *\n * The envelope is portable: callers can hand it to an agent on a different\n * machine, the agent passes it to {@link restoreSessionAccount} along with the\n * session-key private key, and it ends up holding a `KernelAccountClient`\n * scoped to the policies installed at issue time.\n *\n * The owner retains sudo authority on-chain and can revoke at any time via\n * `revokeSessionKey()` (task 2.5).\n *\n * @packageDocumentation\n */\n\nimport type { Policy } from \"@zerodev/permissions\";\nimport { serializePermissionAccount } from \"@zerodev/permissions\";\nimport { getEntryPoint, KERNEL_V3_1 } from \"@zerodev/sdk/constants\";\nimport type { EntryPointType, GetKernelVersion } from \"@zerodev/sdk/types\";\nimport type { Chain, LocalAccount, PublicClient, Transport } from \"viem\";\nimport { createAgentSmartAccount } from \"../account/session-key\";\nimport { isSupportedChainId, type SupportedChainId } from \"../chains\";\nimport {\n\tKAWASEKIT_SESSION_ENVELOPE_VERSION,\n\ttype KawasekitSessionEnvelope,\n\ttype KawasekitSessionPolicySummary,\n} from \"./envelope\";\n\n/** Parameters for {@link issueSessionKey}. */\nexport interface IssueSessionKeyParams {\n\t/**\n\t * viem `PublicClient` on the chain the smart account will live on. Its\n\t * `chain.id` MUST be a {@link SupportedChainId} and is recorded in the\n\t * envelope so restore-time mismatches fail fast.\n\t */\n\treadonly publicClient: PublicClient<Transport, Chain>;\n\t/** Owner EOA — retains sudo authority. */\n\treadonly ownerSigner: LocalAccount;\n\t/** Session-key EOA — the day-to-day signer the agent will hold. */\n\treadonly sessionKeySigner: LocalAccount;\n\t/**\n\t * Policies the session key must satisfy at userOp validation time\n\t * (e.g. {@link createJpycDailyLimitPolicies}).\n\t */\n\treadonly policies: readonly Policy[];\n\t/** Optional advisory expiry (unix seconds). Recorded in the envelope. */\n\treadonly expiresAt?: bigint;\n\t/** Optional advisory policy summary for host UI. */\n\treadonly policySummary?: KawasekitSessionPolicySummary;\n\t/** EntryPoint override. Defaults to v0.7. */\n\treadonly entryPoint?: EntryPointType<\"0.7\">;\n\t/** Kernel version override. Defaults to {@link KERNEL_V3_1}. */\n\treadonly kernelVersion?: GetKernelVersion<\"0.7\">;\n}\n\n/**\n * Issues a fresh session key for an agent smart account.\n *\n * Notes:\n * - The session-key **private key is not embedded** in the returned envelope.\n * The agent must receive the private key out-of-band; the envelope alone is\n * not enough to spend.\n * - The smart account is **not deployed** by this call. It will be deployed\n * on first userOp from `restoreSessionAccount`.\n *\n * @example\n * ```ts\n * import { parseUnits } from \"viem\";\n * import { privateKeyToAccount } from \"viem/accounts\";\n * import {\n * createJpycDailyLimitPolicies,\n * getJpycAddress,\n * issueSessionKey,\n * JPYC_DECIMALS,\n * polygonAmoy,\n * serializeSessionEnvelope,\n * } from \"kawasekit\";\n *\n * const owner = privateKeyToAccount(process.env.OWNER_PRIVATE_KEY as `0x${string}`);\n * const sessionKey = privateKeyToAccount(process.env.SESSION_KEY_PRIVATE_KEY as `0x${string}`);\n *\n * const envelope = await issueSessionKey({\n * publicClient,\n * ownerSigner: owner,\n * sessionKeySigner: sessionKey,\n * policies: createJpycDailyLimitPolicies({\n * jpycAddress: getJpycAddress(polygonAmoy.id),\n * maxPerTransfer: parseUnits(\"100\", JPYC_DECIMALS),\n * maxTransfersPerDay: 10,\n * }),\n * policySummary: {\n * jpycAddress: getJpycAddress(polygonAmoy.id),\n * maxPerTransfer: parseUnits(\"100\", JPYC_DECIMALS),\n * maxTransfersPerDay: 10,\n * },\n * });\n *\n * fs.writeFileSync(\"agent.session\", serializeSessionEnvelope(envelope));\n * ```\n */\nexport async function issueSessionKey(\n\tparams: IssueSessionKeyParams,\n): Promise<KawasekitSessionEnvelope> {\n\tconst chainId = params.publicClient.chain.id;\n\tif (!isSupportedChainId(chainId)) {\n\t\tthrow new Error(\n\t\t\t`issueSessionKey: publicClient.chain.id ${chainId} is not a kawasekit-supported chain`,\n\t\t);\n\t}\n\tconst supportedChainId: SupportedChainId = chainId;\n\tconst entryPoint = params.entryPoint ?? getEntryPoint(\"0.7\");\n\tconst kernelVersion = params.kernelVersion ?? KERNEL_V3_1;\n\n\tconst account = await createAgentSmartAccount({\n\t\tpublicClient: params.publicClient,\n\t\townerSigner: params.ownerSigner,\n\t\tsessionKeySigner: params.sessionKeySigner,\n\t\tpolicies: params.policies,\n\t\tentryPoint,\n\t\tkernelVersion,\n\t});\n\n\tconst serialized = await serializePermissionAccount(account);\n\n\tconst base = {\n\t\tkawasekitVersion: KAWASEKIT_SESSION_ENVELOPE_VERSION,\n\t\tchainId: supportedChainId,\n\t\tsmartAccountAddress: account.address,\n\t\tsessionKeyAddress: params.sessionKeySigner.address,\n\t\tserialized,\n\t} as const;\n\tif (params.expiresAt !== undefined && params.policySummary !== undefined) {\n\t\treturn {\n\t\t\t...base,\n\t\t\texpiresAt: params.expiresAt,\n\t\t\tpolicySummary: params.policySummary,\n\t\t};\n\t}\n\tif (params.expiresAt !== undefined) {\n\t\treturn { ...base, expiresAt: params.expiresAt };\n\t}\n\tif (params.policySummary !== undefined) {\n\t\treturn { ...base, policySummary: params.policySummary };\n\t}\n\treturn base;\n}\n","/**\n * `restoreSessionAccount()` — agent-side primitive that unwraps a\n * {@link KawasekitSessionEnvelope} back into a usable Kernel account scoped\n * to the policies installed at issue time.\n *\n * Three invariants are checked **before** touching ZeroDev's deserialization\n * so that misconfiguration manifests as a typed error here, not a confusing\n * UserOp-time revert:\n *\n * 1. `envelope.kawasekitVersion` matches the current envelope version\n * (already enforced by {@link parseSessionEnvelope}; re-checked here for\n * callers who construct the envelope object directly).\n * 2. `envelope.chainId === publicClient.chain.id`.\n * 3. `envelope.sessionKeyAddress` matches the provided `sessionKeySigner`.\n *\n * @packageDocumentation\n */\n\nimport { deserializePermissionAccount } from \"@zerodev/permissions\";\nimport { toECDSASigner } from \"@zerodev/permissions/signers\";\nimport type { CreateKernelAccountReturnType } from \"@zerodev/sdk\";\nimport { getEntryPoint, KERNEL_V3_1 } from \"@zerodev/sdk/constants\";\nimport type { EntryPointType, GetKernelVersion } from \"@zerodev/sdk/types\";\nimport { type Chain, getAddress, type LocalAccount, type PublicClient, type Transport } from \"viem\";\nimport { KAWASEKIT_SESSION_ENVELOPE_VERSION, type KawasekitSessionEnvelope } from \"./envelope\";\nimport {\n\tSessionEnvelopeChainMismatchError,\n\tSessionEnvelopeSignerMismatchError,\n\tSessionEnvelopeVersionError,\n} from \"./errors\";\n\n/** Parameters for {@link restoreSessionAccount}. */\nexport interface RestoreSessionAccountParams {\n\t/** Must be on the same chain the envelope was issued for. */\n\treadonly publicClient: PublicClient<Transport, Chain>;\n\t/** Envelope produced by {@link issueSessionKey} (or parsed via {@link parseSessionEnvelope}). */\n\treadonly envelope: KawasekitSessionEnvelope;\n\t/**\n\t * The session-key signer the agent holds. Its address MUST equal\n\t * `envelope.sessionKeyAddress` — otherwise the restored account would\n\t * sign userOps that the on-chain permission validator rejects.\n\t */\n\treadonly sessionKeySigner: LocalAccount;\n\t/** EntryPoint override. Defaults to v0.7. */\n\treadonly entryPoint?: EntryPointType<\"0.7\">;\n\t/** Kernel version override. Defaults to {@link KERNEL_V3_1}. */\n\treadonly kernelVersion?: GetKernelVersion<\"0.7\">;\n}\n\n/**\n * Rebuilds the Kernel account from an envelope + the session-key signer.\n *\n * @throws {SessionEnvelopeVersionError} If `envelope.kawasekitVersion` does\n * not match the current envelope version.\n * @throws {SessionEnvelopeChainMismatchError} If `envelope.chainId !==\n * publicClient.chain.id`.\n * @throws {SessionEnvelopeSignerMismatchError} If `sessionKeySigner.address !==\n * envelope.sessionKeyAddress`.\n *\n * @example\n * ```ts\n * import { createPublicClient, http } from \"viem\";\n * import { privateKeyToAccount } from \"viem/accounts\";\n * import {\n * parseSessionEnvelope,\n * polygonAmoy,\n * restoreSessionAccount,\n * } from \"kawasekit\";\n *\n * const publicClient = createPublicClient({\n * chain: polygonAmoy,\n * transport: http(),\n * });\n * const envelope = parseSessionEnvelope(fs.readFileSync(\"agent.session\", \"utf8\"));\n * const sessionKey = privateKeyToAccount(process.env.SESSION_KEY_PRIVATE_KEY as `0x${string}`);\n *\n * const account = await restoreSessionAccount({\n * publicClient,\n * envelope,\n * sessionKeySigner: sessionKey,\n * });\n * ```\n */\nexport async function restoreSessionAccount(\n\tparams: RestoreSessionAccountParams,\n): Promise<CreateKernelAccountReturnType<\"0.7\">> {\n\tconst { publicClient, envelope, sessionKeySigner } = params;\n\n\tif (envelope.kawasekitVersion !== KAWASEKIT_SESSION_ENVELOPE_VERSION) {\n\t\tthrow new SessionEnvelopeVersionError(\n\t\t\tKAWASEKIT_SESSION_ENVELOPE_VERSION,\n\t\t\tenvelope.kawasekitVersion,\n\t\t);\n\t}\n\tif (publicClient.chain.id !== envelope.chainId) {\n\t\tthrow new SessionEnvelopeChainMismatchError(envelope.chainId, publicClient.chain.id);\n\t}\n\tif (getAddress(sessionKeySigner.address) !== getAddress(envelope.sessionKeyAddress)) {\n\t\tthrow new SessionEnvelopeSignerMismatchError(\n\t\t\tenvelope.sessionKeyAddress,\n\t\t\tsessionKeySigner.address,\n\t\t);\n\t}\n\n\tconst entryPoint = params.entryPoint ?? getEntryPoint(\"0.7\");\n\tconst kernelVersion = params.kernelVersion ?? KERNEL_V3_1;\n\tconst modularSigner = await toECDSASigner({ signer: sessionKeySigner });\n\n\treturn deserializePermissionAccount(\n\t\tpublicClient,\n\t\tentryPoint,\n\t\tkernelVersion,\n\t\tenvelope.serialized,\n\t\tmodularSigner,\n\t);\n}\n","/**\n * `revokeSessionKey()` — owner-side primitive that uninstalls a session-key\n * permission validator from the agent's smart account.\n *\n * Implementation strategy (per plan §risk #3): ZeroDev does not expose a\n * dedicated revoke helper, so we re-derive the `PermissionPlugin` from the\n * envelope's `sessionKeyAddress` + the same policies that were installed at\n * issue time, then submit a sudo UserOp via `@zerodev/sdk`'s\n * {@link uninstallPlugin} action. After the receipt, the session key can no\n * longer sign UserOps the validator would accept.\n *\n * In-flight UserOps already submitted to the bundler but not yet mined can\n * still settle before the uninstall transaction lands. A future \"soft revoke\"\n * via `invalidateNonce` on the session-key validator's nonce key will close\n * that race; tracked for M5 (the helper signature accepts an\n * `invalidateInFlightNonces` option today and throws `\"not implemented\"` to\n * lock in the API shape). Until M5 lands, see\n * `docs/recipes/revoke-race-mitigation.md` for the four-layer operator\n * playbook (SDK call → merchant kill-switch → paymaster sponsorship\n * freeze → bundler mempool monitoring).\n *\n * @packageDocumentation\n */\n\nimport type { Policy } from \"@zerodev/permissions\";\nimport { toPermissionValidator } from \"@zerodev/permissions\";\nimport { toECDSASigner } from \"@zerodev/permissions/signers\";\nimport { uninstallPlugin } from \"@zerodev/sdk\";\nimport { getEntryPoint, KERNEL_V3_1 } from \"@zerodev/sdk/constants\";\nimport type { EntryPointType, GetKernelVersion } from \"@zerodev/sdk/types\";\nimport { getAddress, type Hash, type LocalAccount } from \"viem\";\nimport type { ConfiguredKernelClient } from \"../client/transfer-jpyc\";\nimport type { KawasekitSessionEnvelope } from \"./envelope\";\nimport { SessionEnvelopeSignerMismatchError } from \"./errors\";\n\n/** Parameters for {@link revokeSessionKey}. */\nexport interface RevokeSessionKeyParams {\n\t/**\n\t * The owner's sudo Kernel client — the only entity that can call\n\t * `uninstallValidation` on the agent account.\n\t *\n\t * **CRITICAL: must be a SUDO-ONLY kernel account** (i.e.\n\t * `createKernelAccount(publicClient, { plugins: { sudo: ecdsaValidator } })`\n\t * — no `regular` plugin). If you pass a client whose account also has the\n\t * session-key permission validator wired as `regular`, ZeroDev signs\n\t * userOps with that validator by default and the spending policy will\n\t * reject `uninstallValidation` at the validation phase (`AA23 reverted`).\n\t *\n\t * The counterfactual smart-account address only depends on the sudo\n\t * validator in Kernel v3.1, so a sudo-only client points at the SAME\n\t * account as one built with both sudo + regular.\n\t *\n\t * Its `account.address` MUST equal `envelope.smartAccountAddress`.\n\t */\n\treadonly ownerKernelClient: ConfiguredKernelClient;\n\t/** The envelope of the session being revoked. */\n\treadonly envelope: KawasekitSessionEnvelope;\n\t/**\n\t * A LocalAccount whose address equals `envelope.sessionKeyAddress`. Used\n\t * to reconstruct the validator's on-chain identifier; no signing is\n\t * actually performed with this account during revoke.\n\t */\n\treadonly sessionKeySigner: LocalAccount;\n\t/**\n\t * The policies that were installed at issue time. ZeroDev does not store\n\t * these on-chain in a retrievable form, so the caller MUST re-supply\n\t * them. Mismatches surface as an `uninstallValidation` revert at userOp\n\t * validation time.\n\t */\n\treadonly policies: readonly Policy[];\n\t/**\n\t * Future option: also invalidate the session-key validator's nonce key\n\t * to kill in-flight UserOps. Not implemented today — passing `true`\n\t * throws. Tracked for M5; see `docs/THREAT_MODEL.md` §6.3 and\n\t * `docs/recipes/revoke-race-mitigation.md` for the operator playbook to\n\t * use until then.\n\t */\n\treadonly invalidateInFlightNonces?: boolean;\n\t/** EntryPoint override. Defaults to v0.7. */\n\treadonly entryPoint?: EntryPointType<\"0.7\">;\n\t/** Kernel version override. Defaults to {@link KERNEL_V3_1}. */\n\treadonly kernelVersion?: GetKernelVersion<\"0.7\">;\n\t/**\n\t * If `false`, return after submitting the UserOp without waiting for the\n\t * bundler receipt. Default `true` (wait).\n\t */\n\treadonly waitForReceipt?: boolean;\n}\n\n/** Result of {@link revokeSessionKey}. */\nexport interface RevokeSessionKeyResult {\n\t/** Hash of the uninstall UserOp. */\n\treadonly userOpHash: Hash;\n\t/** Bundler transaction hash, present when `waitForReceipt` (default true). */\n\treadonly transactionHash: Hash | null;\n\t/** `true` if the bundler reported success, `null` if not awaited. */\n\treadonly success: boolean | null;\n}\n\n/**\n * Uninstalls a session-key permission validator from the agent's smart\n * account. After the returned UserOp lands, the session key can no longer\n * authorise actions.\n *\n * @throws {SessionEnvelopeSignerMismatchError} If `sessionKeySigner.address`\n * does not match `envelope.sessionKeyAddress`.\n * @throws {Error} If `invalidateInFlightNonces` is `true` (planned for M5;\n * see `docs/THREAT_MODEL.md` §6.3 and\n * `docs/recipes/revoke-race-mitigation.md` for the four-layer\n * operator playbook to use until then).\n *\n * @example\n * ```ts\n * import { signerToEcdsaValidator } from \"@zerodev/ecdsa-validator\";\n * import { createKernelAccount, createKernelAccountClient } from \"@zerodev/sdk\";\n * import { getEntryPoint, KERNEL_V3_1 } from \"@zerodev/sdk/constants\";\n * import { revokeSessionKey } from \"kawasekit\";\n *\n * // Build a SUDO-ONLY kernel account for the owner — see param JSDoc.\n * const sudoValidator = await signerToEcdsaValidator(publicClient, {\n * signer: owner,\n * entryPoint: getEntryPoint(\"0.7\"),\n * kernelVersion: KERNEL_V3_1,\n * });\n * const ownerSudoAccount = await createKernelAccount(publicClient, {\n * plugins: { sudo: sudoValidator },\n * entryPoint: getEntryPoint(\"0.7\"),\n * kernelVersion: KERNEL_V3_1,\n * });\n * const ownerKernelClient = createKernelAccountClient({\n * account: ownerSudoAccount,\n * chain,\n * client: publicClient,\n * bundlerTransport,\n * paymaster,\n * });\n *\n * await revokeSessionKey({\n * ownerKernelClient,\n * envelope,\n * sessionKeySigner,\n * policies: createJpycDailyLimitPolicies({ ... }),\n * });\n * ```\n */\nexport async function revokeSessionKey(\n\tparams: RevokeSessionKeyParams,\n): Promise<RevokeSessionKeyResult> {\n\tconst { ownerKernelClient, envelope, sessionKeySigner, policies } = params;\n\n\tif (params.invalidateInFlightNonces === true) {\n\t\tthrow new Error(\n\t\t\t\"revokeSessionKey: `invalidateInFlightNonces` is not implemented yet — the helper signature accepts the option to lock in the API shape, but in-flight nonce invalidation lands in M5. Hard revoke via uninstallPlugin is what runs today; see docs/recipes/revoke-race-mitigation.md for the four-layer operator playbook to use until then.\",\n\t\t);\n\t}\n\n\tif (getAddress(sessionKeySigner.address) !== getAddress(envelope.sessionKeyAddress)) {\n\t\tthrow new SessionEnvelopeSignerMismatchError(\n\t\t\tenvelope.sessionKeyAddress,\n\t\t\tsessionKeySigner.address,\n\t\t);\n\t}\n\n\tif (getAddress(ownerKernelClient.account.address) !== getAddress(envelope.smartAccountAddress)) {\n\t\tthrow new Error(\n\t\t\t`revokeSessionKey: ownerKernelClient is bound to ${ownerKernelClient.account.address}, but envelope is for ${envelope.smartAccountAddress}.`,\n\t\t);\n\t}\n\n\tconst entryPoint = params.entryPoint ?? getEntryPoint(\"0.7\");\n\tconst kernelVersion = params.kernelVersion ?? KERNEL_V3_1;\n\n\tif (ownerKernelClient.client === undefined) {\n\t\tthrow new Error(\n\t\t\t\"revokeSessionKey: ownerKernelClient.client is undefined — pass `client: publicClient` when constructing the Kernel client so the validator can be reconstructed.\",\n\t\t);\n\t}\n\n\tconst modularSigner = await toECDSASigner({ signer: sessionKeySigner });\n\tconst permissionPlugin = await toPermissionValidator(ownerKernelClient.client, {\n\t\tsigner: modularSigner,\n\t\tpolicies: [...policies],\n\t\tentryPoint,\n\t\tkernelVersion,\n\t});\n\n\tconst userOpHash = await uninstallPlugin(ownerKernelClient, {\n\t\tplugin: permissionPlugin,\n\t});\n\n\tif (params.waitForReceipt === false) {\n\t\treturn { userOpHash, transactionHash: null, success: null };\n\t}\n\n\tconst receipt = await ownerKernelClient.waitForUserOperationReceipt({\n\t\thash: userOpHash,\n\t});\n\treturn {\n\t\tuserOpHash,\n\t\ttransactionHash: receipt.receipt.transactionHash,\n\t\tsuccess: receipt.success,\n\t};\n}\n","/**\n * `rotateSessionKey()` — a thin compositional helper that revokes the\n * current session key and issues a new one in sequence.\n *\n * Compose-don't-conflate: rotate is just `revoke` followed by `issue`. Both\n * primitives are exposed individually so callers who need finer control\n * (e.g. revoke now, issue tomorrow with different policies) can chain them\n * themselves.\n *\n * @packageDocumentation\n */\n\nimport type { KawasekitSessionEnvelope } from \"./envelope\";\nimport { type IssueSessionKeyParams, issueSessionKey } from \"./issue\";\nimport {\n\ttype RevokeSessionKeyParams,\n\ttype RevokeSessionKeyResult,\n\trevokeSessionKey,\n} from \"./revoke\";\n\n/** Parameters for {@link rotateSessionKey}. */\nexport interface RotateSessionKeyParams {\n\t/** Inputs for revoking the current session. `waitForReceipt` is forced `true`. */\n\treadonly revoke: Omit<RevokeSessionKeyParams, \"waitForReceipt\">;\n\t/** Inputs for issuing the replacement session. */\n\treadonly issue: IssueSessionKeyParams;\n}\n\n/** Result of {@link rotateSessionKey}. */\nexport interface RotateSessionKeyResult {\n\t/** Outcome of the revoke step. */\n\treadonly revoke: RevokeSessionKeyResult;\n\t/** The freshly issued replacement envelope. */\n\treadonly envelope: KawasekitSessionEnvelope;\n}\n\n/**\n * Atomically rotate the agent's session key: revoke the old, issue the new.\n *\n * The revoke is always awaited to the bundler receipt — issuing a replacement\n * before the old key is actually disarmed would leave two valid signers at\n * once, defeating the point.\n *\n * @example\n * ```ts\n * import { rotateSessionKey } from \"kawasekit\";\n *\n * const { revoke, envelope } = await rotateSessionKey({\n * revoke: {\n * ownerKernelClient,\n * envelope: oldEnvelope,\n * sessionKeySigner: oldSessionKeySigner,\n * policies: oldPolicies,\n * },\n * issue: {\n * publicClient,\n * ownerSigner,\n * sessionKeySigner: newSessionKeySigner,\n * policies: newPolicies,\n * },\n * });\n * ```\n */\nexport async function rotateSessionKey(\n\tparams: RotateSessionKeyParams,\n): Promise<RotateSessionKeyResult> {\n\tconst revoke = await revokeSessionKey({ ...params.revoke, waitForReceipt: true });\n\tconst envelope = await issueSessionKey(params.issue);\n\treturn { revoke, envelope };\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { createInMemoryIdempotencyStore } from './chunk-TTX3RBIZ.js';
|
|
2
|
+
import { chainIdToX402Network, X402_VERSION, KAWASEKIT_IDEMPOTENCY_RECORD_VERSION } from './chunk-QHUCU5YX.js';
|
|
3
|
+
import { sepolia, avalancheFuji, ethereum, avalanche, kairos, kaia, polygonAmoy, polygon } from './chunk-SOTYGX67.js';
|
|
3
4
|
import { invokeHookSafely, extractAcceptedNetworks } from './chunk-LEHWRDVS.js';
|
|
4
5
|
import { isAddress, getAddress } from 'viem';
|
|
5
6
|
|
|
@@ -12,7 +13,13 @@ var JPYC_EIP712_DOMAIN_HINT = {
|
|
|
12
13
|
var JPYC_V2_ADDRESS = "0xE7C3D8C9a439feDe00D2600032D5dB0Be71C3c29";
|
|
13
14
|
var jpycDeployments = {
|
|
14
15
|
[polygon.id]: { chainId: polygon.id, address: JPYC_V2_ADDRESS, isLive: true },
|
|
15
|
-
[polygonAmoy.id]: { chainId: polygonAmoy.id, address: JPYC_V2_ADDRESS, isLive: true }
|
|
16
|
+
[polygonAmoy.id]: { chainId: polygonAmoy.id, address: JPYC_V2_ADDRESS, isLive: true },
|
|
17
|
+
[kaia.id]: { chainId: kaia.id, address: JPYC_V2_ADDRESS, isLive: true },
|
|
18
|
+
[kairos.id]: { chainId: kairos.id, address: JPYC_V2_ADDRESS, isLive: true },
|
|
19
|
+
[avalanche.id]: { chainId: avalanche.id, address: JPYC_V2_ADDRESS, isLive: true },
|
|
20
|
+
[ethereum.id]: { chainId: ethereum.id, address: JPYC_V2_ADDRESS, isLive: true },
|
|
21
|
+
[avalancheFuji.id]: { chainId: avalancheFuji.id, address: JPYC_V2_ADDRESS, isLive: true },
|
|
22
|
+
[sepolia.id]: { chainId: sepolia.id, address: JPYC_V2_ADDRESS, isLive: true }
|
|
16
23
|
};
|
|
17
24
|
var JpycNotAvailableError = class extends Error {
|
|
18
25
|
constructor(chainId) {
|
|
@@ -735,5 +742,5 @@ function createX402Handler(params) {
|
|
|
735
742
|
}
|
|
736
743
|
|
|
737
744
|
export { JPYC_DECIMALS, JPYC_EIP712_DOMAIN_HINT, JPYC_V2_ADDRESS, JpycNotAvailableError, X402InvalidConfigError, X402InvalidPayloadError, X402_DEFAULT_MAX_TIMEOUT_SECONDS, X402_HEADER_IDEMPOTENCY_KEY, X402_HEADER_PAYMENT_REQUIRED, X402_HEADER_PAYMENT_RESPONSE, X402_HEADER_PAYMENT_SIGNATURE, buildPaymentRequiredResponse, buildPaymentRequirements, createX402Handler, decodePaymentRequiredHeader, decodePaymentResponseHeader, decodePaymentSignatureHeader, encodePaymentRequiredHeader, encodePaymentResponseHeader, encodePaymentSignatureHeader, getJpycAddress, jpycAbi, jpycDeployments };
|
|
738
|
-
//# sourceMappingURL=chunk-
|
|
739
|
-
//# sourceMappingURL=chunk-
|
|
745
|
+
//# sourceMappingURL=chunk-NRGSI52C.js.map
|
|
746
|
+
//# sourceMappingURL=chunk-NRGSI52C.js.map
|