@invisi-labs/sdk 1.1.2 → 1.1.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.
@@ -2,6 +2,53 @@ import {
2
2
  EthersChainReader
3
3
  } from "./chunk-4HMM7ZKY.js";
4
4
 
5
+ // src/errors.ts
6
+ import { MissingCapabilityError } from "@invisi-labs/core";
7
+ var InvisiError = class extends Error {
8
+ code;
9
+ operation;
10
+ address;
11
+ outputIndex;
12
+ field;
13
+ capability;
14
+ constructor(code, message, details = {}) {
15
+ super(message, { cause: details.cause });
16
+ this.name = "InvisiError";
17
+ this.code = code;
18
+ this.operation = details.operation;
19
+ this.address = details.address;
20
+ this.outputIndex = details.outputIndex;
21
+ this.field = details.field;
22
+ this.capability = details.capability;
23
+ }
24
+ };
25
+ async function prepareWithErrors(operation, prepare) {
26
+ try {
27
+ return await prepare();
28
+ } catch (cause) {
29
+ if (cause instanceof InvisiError) {
30
+ if (cause.operation) throw cause;
31
+ throw new InvisiError(cause.code, cause.message, {
32
+ operation,
33
+ ...cause.address === void 0 ? {} : { address: cause.address },
34
+ ...cause.outputIndex === void 0 ? {} : { outputIndex: cause.outputIndex },
35
+ ...cause.field === void 0 ? {} : { field: cause.field },
36
+ ...cause.capability === void 0 ? {} : { capability: cause.capability },
37
+ cause: cause.cause
38
+ });
39
+ }
40
+ throw new InvisiError(
41
+ cause instanceof MissingCapabilityError ? "MISSING_CAPABILITY" : "PREPARATION_FAILED",
42
+ cause instanceof Error ? cause.message : "Transaction preparation failed",
43
+ {
44
+ operation,
45
+ cause,
46
+ ...cause instanceof MissingCapabilityError ? { capability: cause.capability } : {}
47
+ }
48
+ );
49
+ }
50
+ }
51
+
5
52
  // src/session/state.ts
6
53
  function creditReservationKey(commitment) {
7
54
  return "credit:" + commitment;
@@ -57,6 +104,7 @@ function walletBalances(state) {
57
104
  }
58
105
 
59
106
  // src/session/operation-protocol.ts
107
+ import { creditPeriods } from "@invisi-labs/core";
60
108
  import {
61
109
  WitnessBuilder,
62
110
  buildCancelCreditCalldata,
@@ -77,11 +125,8 @@ import {
77
125
  transactUserPublicInputs
78
126
  } from "@invisi-labs/protocol";
79
127
  function requiresAuthorization(plan) {
80
- if (plan.kind === "sweep") {
81
- if (plan.credit || !plan.inputs.length || plan.outputs.length || !plan.params || plan.params.outputCommitments.length || (plan.funding.amount ?? 0n) !== 0n || BigInt(plan.params.withdrawalAddress) !== BigInt(plan.scope.walletIdentity) || plan.params.withdrawalAmount !== plan.inputs.reduce((sum, input) => sum + input.note.amount, 0n) || plan.inputs.some((input) => input.note.walletIdentity !== plan.scope.walletIdentity))
82
- throw new Error("invalid owner-only sweep plan");
83
- return false;
84
- }
128
+ const ownerOnlyFullWithdrawal = !plan.credit && plan.inputs.length > 0 && plan.outputs.length === 0 && plan.params !== void 0 && plan.params.outputCommitments.length === 0 && (plan.funding.amount ?? 0n) === 0n && plan.fundingMode === "none" && BigInt(plan.params.withdrawalAddress) === BigInt(plan.scope.walletIdentity) && plan.params.withdrawalAmount === plan.inputs.reduce((sum, input) => sum + input.note.amount, 0n) && plan.inputs.every((input) => input.note.walletIdentity === plan.scope.walletIdentity);
129
+ if (ownerOnlyFullWithdrawal) return false;
85
130
  return !!plan.credit || plan.inputs.length > 0;
86
131
  }
87
132
  function inputFacts(plan) {
@@ -212,6 +257,7 @@ async function witnessFor(protocol, plan, authorization) {
212
257
  }
213
258
  if (credit.draw) {
214
259
  return builder.drawCredit({
260
+ timestamp: plan.preparedAt.timestamp,
215
261
  params: credit.draw,
216
262
  deliveries: credit.deliveries,
217
263
  inputs: credit.inputs,
@@ -342,7 +388,12 @@ function operationExpired(plan, now) {
342
388
  const credit = plan.credit;
343
389
  if (credit?.topUp && now >= credit.topUp.previousExpiry) return true;
344
390
  if (credit?.creation && now >= credit.creation.expiry) return true;
345
- if (credit?.draw && credit.draw.expiries.some((expiry) => now >= expiry)) return true;
391
+ if (credit?.draw) {
392
+ if (credit.draw.expiries.some((expiry) => now >= expiry)) return true;
393
+ const prepared = creditPeriods(plan.preparedAt.timestamp), current2 = creditPeriods(now);
394
+ if (prepared.currentDay !== current2.currentDay || prepared.currentMonth !== current2.currentMonth)
395
+ return true;
396
+ }
346
397
  return false;
347
398
  }
348
399
 
@@ -350,352 +401,987 @@ function operationExpired(plan, now) {
350
401
  var gas_benchmarks_default = [
351
402
  {
352
403
  formatVersion: 1,
353
- id: "protocol-92ef274-osaka-real",
404
+ id: "protocol-42f2546-621cbef5f84a-prague-credit-real",
354
405
  deployment: {
355
406
  chainId: "31337",
356
- protocolAddress: "0x8870C63A18a9480C7de9B860b849fD293832856D",
357
- runtimeCodeHash: "0x604572c0da90ea139b774cd0d2962a2972fac46e0556c7cec6f6f9aac5deef14",
358
- tokenAddress: "0x4826533B4897376654Bb4d4AD88B7faFD0C98528"
407
+ protocolAddress: "0xEeD9be753bccbCB21463C49f0c56cC0E48bEcf3c",
408
+ runtimeCodeHash: "0x80228a2080d224b4481fc5df24fe8ce080d4536c663b13ec7829ecf0ef46abbd",
409
+ tokenAddress: "0x99bbA657f2BbC93c02D617f8bA121cB8Fc104Acf"
359
410
  },
360
411
  source: {
361
- protocolCommit: "92ef274c6b36d783507699a33ee20e52192c83c7",
362
- measuredAt: "2026-10-27T08:42:15.991Z",
412
+ protocolCommit: "42f2546b62312e4c11e21b8e6b2ff6f72187d6a6",
413
+ measuredAt: "2026-10-29T10:56:24.758Z",
363
414
  chain: "Anvil 31337",
364
- hardfork: "osaka",
415
+ hardfork: "prague",
365
416
  token: "MockERC20",
366
417
  verifier: "real",
418
+ fingerprints: {
419
+ protocolSourceSha256: "621cbef5f84a133ca96674a2dba39b21b5f9fbc022977d4d2ab296d9d6e685e0",
420
+ dirtyDiffSha256: "eb2c41cca3802a47196181648397ec6f47fb2ba0efa8aa3800508d8d255fae3f",
421
+ compiledArtifactsSha256: "c0e658d74fe49caeebf5ef9deadc1751d9e48add690f7e9ab478de7a00dab7e4",
422
+ creditManifestSha256: "da819378af60471905cc902a43e464b58159e0c75bd46fb804ea9d34d8aa7ef6",
423
+ userManifestSha256: "067b6c50e4bc4d9c19dd29f25352db88d189a5f49aed0ed603daa70760e699df",
424
+ sdkSourceSha256: "37e1f82a447db741f46e1490b866ddf85718eab42c33d369cf5f5d2ec3a25c78"
425
+ },
426
+ toolchain: {
427
+ solidity: "0.8.38",
428
+ barretenberg: "6.0.0",
429
+ noir: "1.0.0-rc.6",
430
+ evmVersion: "prague",
431
+ optimizerRuns: 200,
432
+ anvil: "anvil Version: 1.8.6"
433
+ },
434
+ blockGasLimit: "500000000",
435
+ runtimeContracts: {
436
+ transact_user_slots14_direct_Verifier: {
437
+ address: "0x5FbDB2315678afecb367f032d93F642f64180aa3",
438
+ runtimeCodeHash: "0xedab185b2b9fc7d98660db2cdc99fe30b9d1341dfe568172a1626e322d208f7e"
439
+ },
440
+ "transact_user_slots14-adapter": {
441
+ address: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
442
+ runtimeCodeHash: "0xe222cd9c142bc2b13e083e6fe66ea76c0e1e9a194715bfa57082b625c55d867f"
443
+ },
444
+ transact_user_slots56_direct_Verifier: {
445
+ address: "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0",
446
+ runtimeCodeHash: "0x8913eb7060f38234aca199c4a1007892f68e703de48b588c436b24faaeb23a53"
447
+ },
448
+ "transact_user_slots56-adapter": {
449
+ address: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
450
+ runtimeCodeHash: "0x97c416d190da0b9b8111a5ee17367e8a702ba7884019bf724155ae629a783477"
451
+ },
452
+ transact_user_slots112_direct_Verifier: {
453
+ address: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9",
454
+ runtimeCodeHash: "0x501a4791ff0c0a96465ab5e0d42d0ce763bbbb7fd8aebe21929de4d460e1b42c"
455
+ },
456
+ "transact_user_slots112-adapter": {
457
+ address: "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707",
458
+ runtimeCodeHash: "0xf22ed8ea34a4011650a41c1b9f664b5259ea5a8d66a82d706dab9611a38c109f"
459
+ },
460
+ transact_user_slots168_direct_Verifier: {
461
+ address: "0x0165878A594ca255338adfa4d48449f69242Eb8F",
462
+ runtimeCodeHash: "0xc22acdfa6f3e278ae46d194a1c50b905e4815fd7b61e39edb52334570670fdce"
463
+ },
464
+ "transact_user_slots168-adapter": {
465
+ address: "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853",
466
+ runtimeCodeHash: "0x05a318f54d93440a501b6fc6be88e4e76e89d72f1be8333553cb4a61f4f9a0d7"
467
+ },
468
+ transact_aggregate_14_4_Verifier: {
469
+ address: "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6",
470
+ runtimeCodeHash: "0x7a6f2bafe4c61a72a99a195e188f2f4a32900c0cc63cc132e33881d8199fd446"
471
+ },
472
+ "transact_aggregate_14_4-adapter": {
473
+ address: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318",
474
+ runtimeCodeHash: "0x15877da9940d5b8dd4868ffa92ded3b93d6092c3963ba9e18b50f1ea15d89898"
475
+ },
476
+ transact_aggregate_14_8_Verifier: {
477
+ address: "0x610178dA211FEF7D417bC0e6FeD39F05609AD788",
478
+ runtimeCodeHash: "0x5667d16b39973813a499375f6885a3082d7bfcd6e3c0f3548d7de3131cd285f3"
479
+ },
480
+ "transact_aggregate_14_8-adapter": {
481
+ address: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e",
482
+ runtimeCodeHash: "0x9d1a93c78edf7e81b4b6da10ab209b3fb009ed8355594f670559a67842d88cfc"
483
+ },
484
+ transact_aggregate_14_12_Verifier: {
485
+ address: "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0",
486
+ runtimeCodeHash: "0xa4e67840a47182d4011d577981c2477bb4ab2bc36845bb136375f19f12c0800b"
487
+ },
488
+ "transact_aggregate_14_12-adapter": {
489
+ address: "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82",
490
+ runtimeCodeHash: "0x96a6e170aafc0af9d46232ba00206d950bba85e65962d43501bafb6d7f9fe61d"
491
+ },
492
+ create_credit_direct_Verifier: {
493
+ address: "0x9A676e781A523b5d0C0e43731313A708CB607508",
494
+ runtimeCodeHash: "0xbdc6450bf9ba01001082f345b8bd21006a4f75274f32d026cf6e14270e6d56e6"
495
+ },
496
+ "create_credit-adapter": {
497
+ address: "0x0B306BF915C4d645ff596e518fAf3F9669b97016",
498
+ runtimeCodeHash: "0x3a95a22b32aef18ce053a7110056bbfbf13bb0b07932a49765ebb136528a4707"
499
+ },
500
+ credit_draw_slots1_direct_Verifier: {
501
+ address: "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1",
502
+ runtimeCodeHash: "0x47be80e72c3a22ea044638f6004de8c3a0264d5a0d17189c01153cdabfd7bab6"
503
+ },
504
+ "credit_draw_slots1-adapter": {
505
+ address: "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE",
506
+ runtimeCodeHash: "0x28f25aeb97659fb9253ae67f2ff284789710bc59e1ed077ffc7a07b800cbfcc1"
507
+ },
508
+ credit_draw_slots12_direct_Verifier: {
509
+ address: "0x68B1D87F95878fE05B998F19b66F4baba5De1aed",
510
+ runtimeCodeHash: "0x244d9ba22f5c736c2a5c42c466701e2a8ba7ae8108665133541026ea45d56e04"
511
+ },
512
+ "credit_draw_slots12-adapter": {
513
+ address: "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c",
514
+ runtimeCodeHash: "0x60d48a35279d318a0621e5f59b293f44074463b8002ce180b7e6a31b995ac195"
515
+ },
516
+ credit_draw_slots50_direct_Verifier: {
517
+ address: "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d",
518
+ runtimeCodeHash: "0x2ad5eb64bcfae34ef04111dd8f9c1ffc5fc8aa6c1ad3a65d8da78233f3390660"
519
+ },
520
+ "credit_draw_slots50-adapter": {
521
+ address: "0x59b670e9fA9D0A427751Af201D676719a970857b",
522
+ runtimeCodeHash: "0x468966de20e5c71cf7b6f3cda7fa7a76b5d80dc5ddf82119f441ea6a7c6c1e70"
523
+ },
524
+ credit_draw_slots120_direct_Verifier: {
525
+ address: "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1",
526
+ runtimeCodeHash: "0x523b6d211618bbd33d708f8198b9f3daafc10e2fa7a6a857db5795ed748a24e4"
527
+ },
528
+ "credit_draw_slots120-adapter": {
529
+ address: "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44",
530
+ runtimeCodeHash: "0xa91d585ce6037e703efb914205bf193881fde4f470d2fc63b615699b56175239"
531
+ },
532
+ credit_cancel_direct_Verifier: {
533
+ address: "0xa85233C63b9Ee964Add6F2cffe00Fd84eb32338f",
534
+ runtimeCodeHash: "0x182e86861a73f712071e40a6b8497b80c58c383eaa799182e7a50e39196399fd"
535
+ },
536
+ "credit_cancel-adapter": {
537
+ address: "0x4A679253410272dd5232B3Ff7cF5dbB88f295319",
538
+ runtimeCodeHash: "0xea1f0f22445eed5a92c8d6990219059b7e241ad66c55a6d9ddef22a94a0f015f"
539
+ },
540
+ credit_top_up_direct_Verifier: {
541
+ address: "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F",
542
+ runtimeCodeHash: "0xeeb42a2b6377ab305b713d1caf4ca96edb302c6d1e1007239e5c70091819c266"
543
+ },
544
+ "credit_top_up-adapter": {
545
+ address: "0x09635F643e140090A9A8Dcd712eD6285858ceBef",
546
+ runtimeCodeHash: "0xbcf35a1d0e6c16dd01b09f944889aa5917d358d986fe399a0343d06bbdedaa61"
547
+ },
548
+ PrivateTransferVerifierRegistry: {
549
+ address: "0xc5a5C42992dECbae36851359345FE25997F5C42d",
550
+ runtimeCodeHash: "0x678684af147cb42c872184b6e22c8439748139ae0c5885032941ab8832fcb142"
551
+ },
552
+ CrossTreeVerifierRegistry: {
553
+ address: "0x67d269191c92Caf3cD7723F116c85e6E9bf55933",
554
+ runtimeCodeHash: "0xa5ee16fc7ed9f982450e42a48365a93bfca784fa884adcb8695b557e921cb93b"
555
+ },
556
+ DualVerifierRouter: {
557
+ address: "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E",
558
+ runtimeCodeHash: "0xcc094ed6f1bcc9270c597f62b817e4fc0a54770f373320133c2836e5b07ef2cc"
559
+ },
560
+ AtomicBatchOutputLib: {
561
+ address: "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690",
562
+ runtimeCodeHash: "0x7c138c13e40b3ad0fee3b319d6c1580a21855cb5ecdda92571d530509d9b7316"
563
+ },
564
+ FundingLib: {
565
+ address: "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB",
566
+ runtimeCodeHash: "0x898d13d6ec4123df85f21ee0f98678dcd9f9b9a60134f88e35c1ef1aaa0a45f9"
567
+ },
568
+ PrivateTransferLib: {
569
+ address: "0x9E545E3C0baAB3E08CdfD552C960A1050f373042",
570
+ runtimeCodeHash: "0xfb18f2dd0a39af1b99ae35c25e2746cb5bc85c205e041db5f440671d84c82e5e"
571
+ },
572
+ CrossTreeTransferLib: {
573
+ address: "0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9",
574
+ runtimeCodeHash: "0x7b33a08f2feb9da462b951c95482cb2909796a85c0fde7cc9a6b65ff8b7ff253"
575
+ },
576
+ AggregateTransferLib: {
577
+ address: "0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8",
578
+ runtimeCodeHash: "0xb3b4bd3a428f5c35712a57180f07b2249774d399ca87d4494929148ea26c5b99"
579
+ },
580
+ CreateCreditLib: {
581
+ address: "0x851356ae760d987E095750cCeb3bC6014560891C",
582
+ runtimeCodeHash: "0xe37a4b7c129c4fba5615d25ed8b7e898e64a306c68f7e599ade911db98fe881c"
583
+ },
584
+ CreditLifecycleLib: {
585
+ address: "0xf5059a5D33d5853360D16C683c16e67980206f36",
586
+ runtimeCodeHash: "0xf87a2227680efa7070071516587793e2e847c172b83261b8983c826f8a8c79bb"
587
+ },
588
+ ShieldLib: {
589
+ address: "0x95401dc811bb5740090279Ba06cfA8fcF6113778",
590
+ runtimeCodeHash: "0x371e57d8d324e44445a4ec30303b89a8bc98bbdbd03aeaa80faf0f821a65451d"
591
+ },
592
+ InvisiFactory: {
593
+ address: "0x998abeb3E57409262aE5b751f60747921B33613E",
594
+ runtimeCodeHash: "0xc56e5a0b71f4a1f63576a6663efb62b17c0d7520b6885a8d3483a356e12edf9b"
595
+ },
596
+ InvisiAddressRegistry: {
597
+ address: "0x70e0bA845a1A0F2DA3359C97E0285013525FFC49",
598
+ runtimeCodeHash: "0x007da3f4e888366ba0eed52cd511c4a369359291387ad19ca37e89eb395fce30"
599
+ },
600
+ InvisiProtocol: {
601
+ address: "0xEeD9be753bccbCB21463C49f0c56cC0E48bEcf3c",
602
+ runtimeCodeHash: "0x80228a2080d224b4481fc5df24fe8ce080d4536c663b13ec7829ecf0ef46abbd"
603
+ },
604
+ MockERC20: {
605
+ address: "0x99bbA657f2BbC93c02D617f8bA121cB8Fc104Acf",
606
+ runtimeCodeHash: "0xf7f676b5c54f6e94f82f0de65a0117468a0d915e8a79d150e74f76bd6d7f708b"
607
+ }
608
+ },
367
609
  assumptions: [
368
- "normal CREATE/Factory deployment; no code or storage injection",
369
- "Solidity 0.8.27 optimizer 200; real BB 5.2.1 verifiers",
370
- "one source tree; two existing leaves; no rollover or screener",
371
- "funding/approval setup excluded; complete transaction receipt gas included",
372
- "exact allowance for caller funding; configured benchmark payout balances",
373
- "observed local samples, not a confidence interval or gas limit"
610
+ "normal CREATE/Factory deployment and fresh registry; EIP170/EIP3860 unchanged; no code/storage injection",
611
+ "Solidity0.8.38 optimizer200 Prague; pinned BB6.0.0 real verifiers; every native proof independently verified",
612
+ "one physical source tree and 123 existing leaves shared by every sample; top-up has two authenticated source groups; no rollover or screener",
613
+ "funding/approvals/121 genuine Credit seeds/usage-seed draw/payout reset excluded from business gas",
614
+ "each round restores identical token balances, exact caller allowance100, note cursor, nullifiers and baseline; spender payout starts zero",
615
+ "complete receipt.gasUsed is measured, including verifier/calldata/logging/output insertion; memo0",
616
+ "Prague local block gas limit500000000; measured transactions may be unmineable under lower network transaction/block limits",
617
+ "observed three-sample ranges are neither a confidence interval nor a recommended transaction gas limit"
374
618
  ]
375
619
  },
376
620
  measurements: [
377
621
  {
378
- id: "shield-1",
622
+ id: "create-credit-caller-0x0",
379
623
  shape: {
380
- kind: "shield",
624
+ kind: "create-credit",
381
625
  target: "evm",
382
- capacity: 0,
626
+ capacity: 10,
383
627
  noteInputs: 0,
384
- noteOutputs: 1,
628
+ noteOutputs: 0,
385
629
  sourceTrees: 0,
386
630
  creditInputs: 0,
387
- creditOutputs: 0,
631
+ creditOutputs: 1,
388
632
  creditRemainders: 0,
389
633
  funding: "caller",
390
634
  permit: false,
391
- deliveryBytes: 226
635
+ deliveryBytes: 1132
636
+ },
637
+ circuit: {
638
+ circuitName: "create_credit",
639
+ target: "evm",
640
+ artifactSha256: "3ed6cfdee4f5fd840f023580f76c208768777fea79737f2511377e5c55be0230",
641
+ vkSha256: "56f663c6053be0d158a271022d200c732597efd3a2e0be48fe94549d0b1795e0"
392
642
  },
393
- circuit: null,
394
643
  samples: [
395
644
  {
396
- gasUsed: "649286",
397
- transactionHash: "0xcc299d1780ada9a69b1d9f0f3d06a165db15fccbd2b7ff407834f02f5d563a18",
398
- blockNumber: "50",
399
- blockHash: "0xbcb868e781a20588d2fa099a4d7f87c1600044a2e5ec1e369e384d7a5f22f00a",
400
- calldataBytes: 1156
645
+ gasUsed: "1574696",
646
+ transactionHash: "0x76112c532a1b5f24ad84fb83f91789ba4acd15ed9473ec9a0267cd5fe605448d",
647
+ blockNumber: "172",
648
+ blockHash: "0x0d91421e94947132a19f38ffdd76932c2d85add201de3d9189325ed3568125a7",
649
+ calldataBytes: 11780
401
650
  },
402
651
  {
403
- gasUsed: "649322",
404
- transactionHash: "0x95139dff109725989f0769e3e6fb9bd3e7e1bf581fd475f14e822875eb90fda4",
405
- blockNumber: "50",
406
- blockHash: "0x7ace353fea4fc8c856c0fd45521d200b02619921977709ff4f910e0ff41c06fe",
407
- calldataBytes: 1156
652
+ gasUsed: "1574576",
653
+ transactionHash: "0x545f72d9d207329bfc69ef0d1e96470c614924d5e463d974cc001712bf619fd8",
654
+ blockNumber: "172",
655
+ blockHash: "0x2053f97a2b2f3cf66e14da0ab9c1d7bd462d2d4f3ef2b13021aefcddedb71cf8",
656
+ calldataBytes: 11780
408
657
  },
409
658
  {
410
- gasUsed: "649322",
411
- transactionHash: "0xef578bb38dc8ff8bfd47d2e76e3ab4273019ea9a385f5d2fd99add32ceaecb58",
412
- blockNumber: "50",
413
- blockHash: "0xded817f8ef89637e2443e3b626c0837f184ca134fe753be913d5570554c649a6",
414
- calldataBytes: 1156
659
+ gasUsed: "1574612",
660
+ transactionHash: "0x880ec0c666068d0756fba39947dc5b211aeebb31f41bd1e1e54856b090f65d34",
661
+ blockNumber: "172",
662
+ blockHash: "0xbb86ed21379a917e9688a3c90364ae8fbe1ba633ac068360e0a82bf4d3113b6d",
663
+ calldataBytes: 11780
415
664
  }
416
665
  ]
417
666
  },
418
667
  {
419
- id: "shield-2",
668
+ id: "create-credit-1x1",
420
669
  shape: {
421
- kind: "shield",
670
+ kind: "create-credit",
422
671
  target: "evm",
423
- capacity: 0,
424
- noteInputs: 0,
425
- noteOutputs: 2,
426
- sourceTrees: 0,
672
+ capacity: 10,
673
+ noteInputs: 1,
674
+ noteOutputs: 1,
675
+ sourceTrees: 1,
427
676
  creditInputs: 0,
428
- creditOutputs: 0,
677
+ creditOutputs: 1,
429
678
  creditRemainders: 0,
430
- funding: "caller",
679
+ funding: "none",
431
680
  permit: false,
432
- deliveryBytes: 452
681
+ deliveryBytes: 1360
682
+ },
683
+ circuit: {
684
+ circuitName: "create_credit",
685
+ target: "evm",
686
+ artifactSha256: "3ed6cfdee4f5fd840f023580f76c208768777fea79737f2511377e5c55be0230",
687
+ vkSha256: "56f663c6053be0d158a271022d200c732597efd3a2e0be48fe94549d0b1795e0"
433
688
  },
434
- circuit: null,
435
689
  samples: [
436
690
  {
437
- gasUsed: "757063",
438
- transactionHash: "0x024e2dfbd6f50c368e2a4aa347e3029de668f4ebd36b80227aa003bb7ac21c74",
439
- blockNumber: "50",
440
- blockHash: "0x8ed63973c158d706ac54bb646626e4f0db5777b4bd56d179b94503af6c417c50",
441
- calldataBytes: 1668
691
+ gasUsed: "1671641",
692
+ transactionHash: "0x24ca3f03681aeb188b48989d5eaf7dd264a8c32e828acd34ff1b44be74f17ea6",
693
+ blockNumber: "172",
694
+ blockHash: "0xcdac07aa5d3ec187874dc1fc9be65503235289c7036ebe455feaf5161db42bb5",
695
+ calldataBytes: 12132
442
696
  },
443
697
  {
444
- gasUsed: "757063",
445
- transactionHash: "0x898d852ab28f68adac4d30b160a3dbfee33fa7ca875f70df9eb7763b6b1cd1f0",
446
- blockNumber: "50",
447
- blockHash: "0x9bb6810de38193933a9f26fa03d3d9bad1ca0151ff5e04544c56520e09da3043",
448
- calldataBytes: 1668
698
+ gasUsed: "1671509",
699
+ transactionHash: "0x31a7f69ab02effa5fdd2e02bd02fb7e715a54786813261113fd7c07a0d3ef549",
700
+ blockNumber: "172",
701
+ blockHash: "0xc78ca874aa22cc6b8ea19e12a2806ba448a0f844345450d3fedc9841ea71c3a8",
702
+ calldataBytes: 12132
449
703
  },
450
704
  {
451
- gasUsed: "757039",
452
- transactionHash: "0x8ff9720e3197aab2d741fbd8d0fa2969203ea8cd051d9649d1e5eb890bcc2be3",
453
- blockNumber: "50",
454
- blockHash: "0x8604c75eb6363aaae774276e638f5b749aae1f8f815eb99ab1183137eef5730e",
455
- calldataBytes: 1668
705
+ gasUsed: "1671485",
706
+ transactionHash: "0xc5a30116885dcac8b3631c15847544cfeb91c46bde44c3765ac0ce42e3259157",
707
+ blockNumber: "172",
708
+ blockHash: "0x4a2c90ff972da4d37408567062779762efbb5790d4784d03842ee2c926c8c894",
709
+ calldataBytes: 12132
456
710
  }
457
711
  ]
458
712
  },
459
713
  {
460
- id: "shield-10",
714
+ id: "draw-credit-1-partial",
461
715
  shape: {
462
- kind: "shield",
716
+ kind: "draw-credit",
463
717
  target: "evm",
464
- capacity: 0,
718
+ capacity: 1,
465
719
  noteInputs: 0,
466
- noteOutputs: 10,
467
- sourceTrees: 0,
468
- creditInputs: 0,
469
- creditOutputs: 0,
470
- creditRemainders: 0,
471
- funding: "caller",
720
+ noteOutputs: 0,
721
+ sourceTrees: 1,
722
+ creditInputs: 1,
723
+ creditOutputs: 1,
724
+ creditRemainders: 1,
725
+ funding: "none",
472
726
  permit: false,
473
- deliveryBytes: 2260
727
+ deliveryBytes: 1132
728
+ },
729
+ circuit: {
730
+ circuitName: "credit_draw_slots1",
731
+ target: "evm",
732
+ artifactSha256: "4542b227e0552b45c302f1dace21cadeba4962c96244e021472f1f7531cff8d1",
733
+ vkSha256: "43c051a2bedf9454c12e70b10156361e414944823ba23e80662c16c7ced0a2ce"
474
734
  },
475
- circuit: null,
476
735
  samples: [
477
736
  {
478
- gasUsed: "1692143",
479
- transactionHash: "0x6c13db8bd8a8599daf5034e56712abefbf406982fafe7647b6d22291ba4199ed",
480
- blockNumber: "50",
481
- blockHash: "0x1ab2ae514f408a79e0c40ca10cee74b2e23d7c8a5f24641b8eea3e1cf58ce700",
482
- calldataBytes: 5764
737
+ gasUsed: "1588303",
738
+ transactionHash: "0x85c5180692470aa952aa13eb29ca0404d4f5b5192cb31475f90d03d78864895e",
739
+ blockNumber: "172",
740
+ blockHash: "0xfe4876c0a2ebf05385a46562bca693b6df80da731fd9651117593916015dc38c",
741
+ calldataBytes: 11588
483
742
  },
484
743
  {
485
- gasUsed: "1692083",
486
- transactionHash: "0x5e476c9d3838b782a51332af9bf5c372d29fc411c2168a7af619c52bd5309c7b",
487
- blockNumber: "50",
488
- blockHash: "0x9c62bc72fc90f990c6711b48865ff922a1856ae05c4fef61dad5f4da7d948401",
489
- calldataBytes: 5764
744
+ gasUsed: "1588303",
745
+ transactionHash: "0x61684313840623187ca1205b4b07b43a08038448524ee1a028c7e14050032682",
746
+ blockNumber: "172",
747
+ blockHash: "0x9726d31c10e6516e38e3f63c84fc4b9a8a161486d35e0d8d07e6829261a88fe7",
748
+ calldataBytes: 11588
490
749
  },
491
750
  {
492
- gasUsed: "1692203",
493
- transactionHash: "0x0092e2d9160fad95279cde586fc6c79c713244f55db8a2060a5abab9d98c176a",
494
- blockNumber: "50",
495
- blockHash: "0xac1bf780b4cc05b4dcc7ee5d741c049ba99ab4af9bdcd25104add730c2a14152",
496
- calldataBytes: 5764
751
+ gasUsed: "1588255",
752
+ transactionHash: "0x0aa052fb8e356cc81dd73bcdae72f760937cd2e56bd4a3e8eb5878208b4f7596",
753
+ blockNumber: "172",
754
+ blockHash: "0x2c958cfba0627e18cd5cb47001b278628c305071929596e3335d770b92c1dc16",
755
+ calldataBytes: 11588
497
756
  }
498
757
  ]
499
758
  },
500
759
  {
501
- id: "transfer-1x2",
760
+ id: "draw-credit-1-full",
502
761
  shape: {
503
- kind: "transfer",
762
+ kind: "draw-credit",
504
763
  target: "evm",
505
- capacity: 14,
506
- noteInputs: 1,
507
- noteOutputs: 2,
764
+ capacity: 1,
765
+ noteInputs: 0,
766
+ noteOutputs: 0,
508
767
  sourceTrees: 1,
509
- creditInputs: 0,
768
+ creditInputs: 1,
510
769
  creditOutputs: 0,
511
770
  creditRemainders: 0,
512
771
  funding: "none",
513
772
  permit: false,
514
- deliveryBytes: 452
773
+ deliveryBytes: 0
515
774
  },
516
775
  circuit: {
517
- circuitName: "transact_user_slots14",
776
+ circuitName: "credit_draw_slots1",
518
777
  target: "evm",
519
- artifactSha256: "2a6a20839e90b88b1ecd629f59a01821bad3ee11dbe04db1fd9cdce7a3de0e84",
520
- vkSha256: "ffe0e1a4e690792ecb4eb1fc1acc9ff60f13d3b5af03cfc6ae6d6bf26e99bdea"
778
+ artifactSha256: "4542b227e0552b45c302f1dace21cadeba4962c96244e021472f1f7531cff8d1",
779
+ vkSha256: "43c051a2bedf9454c12e70b10156361e414944823ba23e80662c16c7ced0a2ce"
521
780
  },
522
781
  samples: [
523
782
  {
524
- gasUsed: "1617516",
525
- transactionHash: "0xf49ea3d31cc1346472172e2dee84f9360f60a3fe948a3ef6e87f727af6d42f0d",
526
- blockNumber: "49",
527
- blockHash: "0xf59c57e63ec2f03abc36d28f273b0af5290184dc97197df740b23d79a851a887",
528
- calldataBytes: 11012
783
+ gasUsed: "1042812",
784
+ transactionHash: "0xb5d55729d975abdc92ca44c0b72e44a0d5841da8b23dc11b5bd31f46d88a341a",
785
+ blockNumber: "172",
786
+ blockHash: "0x8a6ddbe2f1630e1956485cac7984fb9cdc4fbb26b10522e158b38e2970ee4f3b",
787
+ calldataBytes: 10372
529
788
  },
530
789
  {
531
- gasUsed: "1617516",
532
- transactionHash: "0xf8d11286f1f2a4db006ff6b06900c47d0fbf685984499e1e5d4aea49478ba8e5",
533
- blockNumber: "49",
534
- blockHash: "0xeb5a800190be3534c9e2675c97ac56d0e0be8adef55f60bd32d375776a7d150c",
535
- calldataBytes: 11012
790
+ gasUsed: "1042824",
791
+ transactionHash: "0xf64f3186fbf94fcbd9fb12426c714b4a8425599e1a7e5677866fae3d6873b7ae",
792
+ blockNumber: "172",
793
+ blockHash: "0xd630c44d8ce96234ec836dd2178caac2a6d0bc2df5cf37df1534eb8896be48d3",
794
+ calldataBytes: 10372
536
795
  },
537
796
  {
538
- gasUsed: "1617504",
539
- transactionHash: "0x8939fcea97079a3c5118b9e94325455e2ad1cdb47310ae499a277272654b3eb6",
540
- blockNumber: "49",
541
- blockHash: "0xecffefb593e2fec5d5827cfd39d0cc4d0efb67dbff6f8dbbd0d2db2439a80cf9",
542
- calldataBytes: 11012
797
+ gasUsed: "1042884",
798
+ transactionHash: "0xdf634e809b87603a62292ef046fa5e84715561fa76ef121c768303dd779568f1",
799
+ blockNumber: "172",
800
+ blockHash: "0x09cad4a799360bdf825c3ad70fe374b7fe2df802f8ee37ccb7f26ffc49aa2a3a",
801
+ calldataBytes: 10372
543
802
  }
544
803
  ]
545
804
  },
546
805
  {
547
- id: "transfer-1x14",
806
+ id: "draw-credit-12-partial",
548
807
  shape: {
549
- kind: "transfer",
808
+ kind: "draw-credit",
550
809
  target: "evm",
551
- capacity: 56,
552
- noteInputs: 1,
553
- noteOutputs: 14,
810
+ capacity: 12,
811
+ noteInputs: 0,
812
+ noteOutputs: 0,
554
813
  sourceTrees: 1,
555
- creditInputs: 0,
556
- creditOutputs: 0,
557
- creditRemainders: 0,
814
+ creditInputs: 12,
815
+ creditOutputs: 12,
816
+ creditRemainders: 12,
558
817
  funding: "none",
559
818
  permit: false,
560
- deliveryBytes: 3164
819
+ deliveryBytes: 13584
561
820
  },
562
821
  circuit: {
563
- circuitName: "transact_user_slots56",
822
+ circuitName: "credit_draw_slots12",
564
823
  target: "evm",
565
- artifactSha256: "ba83ec2f177d16fa88ea04bc54f2e99920f1ac195cdb05b88b9b3bbc245fd953",
566
- vkSha256: "6ad5d3aff0c72a632fb19895658af093a6a92478a9994985e838a71e61237720"
824
+ artifactSha256: "dd72b0867fc3be7cd90de263bd2d0892075cb18eb4f6dd671b13111710f10369",
825
+ vkSha256: "5e31d771e6294993736078596d9c69f21fe7595eda50e3cce6d7406b65cf1443"
567
826
  },
568
827
  samples: [
569
828
  {
570
- gasUsed: "2489010",
571
- transactionHash: "0x053557acea930a869d6469c91e9bc015d0893607a6ab18d2af684986f7074676",
572
- blockNumber: "49",
573
- blockHash: "0x734873097eb5e4cb66bfc2cdb61fac6753b53a4b9450fb22895281100af3aaf3",
574
- calldataBytes: 17156
829
+ gasUsed: "3102895",
830
+ transactionHash: "0x699ba81f296f4af397a8dfaf96adf14d00d0f7dd69c0b09608641fc9b99fc28f",
831
+ blockNumber: "172",
832
+ blockHash: "0x8d318f563f5563fa5c213617481089f75aab3a6e9d14818db107ac20a8c20ffb",
833
+ calldataBytes: 30276
575
834
  },
576
835
  {
577
- gasUsed: "2489106",
578
- transactionHash: "0xb3990edb994011775e275bc1eb38c527b7206a2bfadf510e8aa53e260f3594b8",
579
- blockNumber: "49",
580
- blockHash: "0xf8cb019ebb0ecd0ec5d6634198292883c63fe93a7c65c34f9f3120c6cc54f1cf",
581
- calldataBytes: 17156
836
+ gasUsed: "3102871",
837
+ transactionHash: "0xddfc1c6c505f6c54f4d9aabc96a02eb6b606182e8ad708a578eacd274d885dee",
838
+ blockNumber: "172",
839
+ blockHash: "0xcc7738fe329a608241615dc43b7d16e075eb62be202ea8aaf4ae27a5278bf438",
840
+ calldataBytes: 30276
582
841
  },
583
842
  {
584
- gasUsed: "2489094",
585
- transactionHash: "0xc97079019567ff8a79d285421351ee4bc48d14092a0e12ff634151719e991088",
586
- blockNumber: "49",
587
- blockHash: "0x5a6947839165c8961eeeb9190331415c40366a78b4a6a5771e7b8954dbb8b3c7",
588
- calldataBytes: 17156
843
+ gasUsed: "3103171",
844
+ transactionHash: "0x6efab6408d927e1877f1f6c33ecd285a128382f7d1dfe6e123927b035781c8aa",
845
+ blockNumber: "172",
846
+ blockHash: "0xcb4588df9ecdca0d353ccbd226e1d5d07f21e6dc93875e41cdd5f64568859f4d",
847
+ calldataBytes: 30276
589
848
  }
590
849
  ]
591
850
  },
592
851
  {
593
- id: "transfer-1x56",
852
+ id: "draw-credit-12-full",
594
853
  shape: {
595
- kind: "transfer",
854
+ kind: "draw-credit",
596
855
  target: "evm",
597
- capacity: 112,
598
- noteInputs: 1,
599
- noteOutputs: 56,
856
+ capacity: 12,
857
+ noteInputs: 0,
858
+ noteOutputs: 0,
600
859
  sourceTrees: 1,
601
- creditInputs: 0,
860
+ creditInputs: 12,
602
861
  creditOutputs: 0,
603
862
  creditRemainders: 0,
604
863
  funding: "none",
605
864
  permit: false,
606
- deliveryBytes: 12656
865
+ deliveryBytes: 0
607
866
  },
608
867
  circuit: {
609
- circuitName: "transact_user_slots112",
868
+ circuitName: "credit_draw_slots12",
610
869
  target: "evm",
611
- artifactSha256: "713b78469b6e97711122210f8497942120c1c9d66d3604bc184566c4eba59cc3",
612
- vkSha256: "d6a46e297949c28b9a62fd9aef1f202870fdca97b8bfb15beefd27b9e9f3d86e"
870
+ artifactSha256: "dd72b0867fc3be7cd90de263bd2d0892075cb18eb4f6dd671b13111710f10369",
871
+ vkSha256: "5e31d771e6294993736078596d9c69f21fe7595eda50e3cce6d7406b65cf1443"
872
+ },
873
+ samples: [
874
+ {
875
+ gasUsed: "1536675",
876
+ transactionHash: "0xc0d3eef8e6b0e90984d776a5e41bcdce1e0ca0bc6dc3a71616e4768e80c01546",
877
+ blockNumber: "172",
878
+ blockHash: "0x22dfac3d8e9913a6a1f2ff84faaece4ed59bfe1cb74e06a60131ff28cc6c2f9d",
879
+ calldataBytes: 15684
880
+ },
881
+ {
882
+ gasUsed: "1536675",
883
+ transactionHash: "0x9879d86a1eaa550a6a6afaeeb0f5f07745d5dcd9caa07b660d7fb512911dc67e",
884
+ blockNumber: "172",
885
+ blockHash: "0xf88ba9f1b7a0c627338a61bbabe1c650bdfcd7fa1c56433d6853f492135b753d",
886
+ calldataBytes: 15684
887
+ },
888
+ {
889
+ gasUsed: "1536711",
890
+ transactionHash: "0xbd8f75a021a8ce8dc1900bd2d84d723acc6a64018844050a5aa2f8712cf7fd6b",
891
+ blockNumber: "172",
892
+ blockHash: "0xa55b539c2ea4e10ce9a9ee8e6de9cf1daa97263b51f32cfef8342c100b663b0f",
893
+ calldataBytes: 15684
894
+ }
895
+ ]
896
+ },
897
+ {
898
+ id: "draw-credit-50-partial",
899
+ shape: {
900
+ kind: "draw-credit",
901
+ target: "evm",
902
+ capacity: 50,
903
+ noteInputs: 0,
904
+ noteOutputs: 0,
905
+ sourceTrees: 1,
906
+ creditInputs: 50,
907
+ creditOutputs: 50,
908
+ creditRemainders: 50,
909
+ funding: "none",
910
+ permit: false,
911
+ deliveryBytes: 56600
912
+ },
913
+ circuit: {
914
+ circuitName: "credit_draw_slots50",
915
+ target: "evm",
916
+ artifactSha256: "09c7469866748b4c0c4bbf2b040844771948a170999f6dc7a38fe5c0ecda4054",
917
+ vkSha256: "7b613225b6f32a077011d4196c356e836d22dcd116efe687fde53144fbd8db9f"
918
+ },
919
+ samples: [
920
+ {
921
+ gasUsed: "8015473",
922
+ transactionHash: "0x5dcc0fa08abaf5212424ac6f3e2f3bb8a0bd333f90ef6e421f8d3fe370ca1acf",
923
+ blockNumber: "172",
924
+ blockHash: "0x3197c523dece3492226c5021f974e7c02db2e686265943d03a5550c6cb96a12e",
925
+ calldataBytes: 94276
926
+ },
927
+ {
928
+ gasUsed: "8015449",
929
+ transactionHash: "0x6a55f88551a45b3e118cde0607cfff1ef0b6ab15ad9472e838412d9ce714b42a",
930
+ blockNumber: "172",
931
+ blockHash: "0xea82c8962d45db8361bd67ed326806f21c511bd51550adc453d0c3e5cab3a7ae",
932
+ calldataBytes: 94276
933
+ },
934
+ {
935
+ gasUsed: "8015149",
936
+ transactionHash: "0x2cc8d474a92abe91f8025109a70cf1f9f081dbec43aa4a475ab9f33222cfc76b",
937
+ blockNumber: "172",
938
+ blockHash: "0x4398f419da699ccca33867852d4975b5c461a40bb01cd5241a0e6dcacaeb78b3",
939
+ calldataBytes: 94276
940
+ }
941
+ ]
942
+ },
943
+ {
944
+ id: "draw-credit-50-full",
945
+ shape: {
946
+ kind: "draw-credit",
947
+ target: "evm",
948
+ capacity: 50,
949
+ noteInputs: 0,
950
+ noteOutputs: 0,
951
+ sourceTrees: 1,
952
+ creditInputs: 50,
953
+ creditOutputs: 0,
954
+ creditRemainders: 0,
955
+ funding: "none",
956
+ permit: false,
957
+ deliveryBytes: 0
958
+ },
959
+ circuit: {
960
+ circuitName: "credit_draw_slots50",
961
+ target: "evm",
962
+ artifactSha256: "09c7469866748b4c0c4bbf2b040844771948a170999f6dc7a38fe5c0ecda4054",
963
+ vkSha256: "7b613225b6f32a077011d4196c356e836d22dcd116efe687fde53144fbd8db9f"
964
+ },
965
+ samples: [
966
+ {
967
+ gasUsed: "3216708",
968
+ transactionHash: "0x16933368d26ea1d7fbe69027c700671df832ad308944eeff42e7c2da40297b06",
969
+ blockNumber: "172",
970
+ blockHash: "0x0739a6f4188b8bdeae7bd5460960086d04adfea993d07d65b2b3630ad01b8cab",
971
+ calldataBytes: 33476
972
+ },
973
+ {
974
+ gasUsed: "3216840",
975
+ transactionHash: "0x45dc15a62b1661f54e167cf13b9693770370c926a8a7af959da7354e9bb4aa6e",
976
+ blockNumber: "172",
977
+ blockHash: "0xf2e294db9af3b11814fed1dec358b8370ea28a99189211f883c9b0012349d677",
978
+ calldataBytes: 33476
979
+ },
980
+ {
981
+ gasUsed: "3216744",
982
+ transactionHash: "0x2c827753026ea421497534a01bcc2adaca866a7612f570dad3fcf18c660f8590",
983
+ blockNumber: "172",
984
+ blockHash: "0x3ccd465528ff22e6d1955670220df3565899a16dd683f71c83c9810f2df420b4",
985
+ calldataBytes: 33476
986
+ }
987
+ ]
988
+ },
989
+ {
990
+ id: "draw-credit-120-partial",
991
+ shape: {
992
+ kind: "draw-credit",
993
+ target: "evm",
994
+ capacity: 120,
995
+ noteInputs: 0,
996
+ noteOutputs: 0,
997
+ sourceTrees: 1,
998
+ creditInputs: 120,
999
+ creditOutputs: 120,
1000
+ creditRemainders: 120,
1001
+ funding: "none",
1002
+ permit: false,
1003
+ deliveryBytes: 135840
1004
+ },
1005
+ circuit: {
1006
+ circuitName: "credit_draw_slots120",
1007
+ target: "evm",
1008
+ artifactSha256: "6ccd0366a669c50fd5da875c3eae194fe8aa4c36d35a5f9ebfd64636ea599b48",
1009
+ vkSha256: "d715848afc5c1ecdfcef5ed5026865abef5040a3bc232fd65330a5ffee8475fb"
1010
+ },
1011
+ samples: [
1012
+ {
1013
+ gasUsed: "17458512",
1014
+ transactionHash: "0x84dd6bda5f3172a53e899051fd226dc5869edb796bd513a33e7f224bed13f4ae",
1015
+ blockNumber: "172",
1016
+ blockHash: "0xfca82de1e112b92319185d8c3f0115e0aa339d0247ea65970eb0d37ba958b08e",
1017
+ calldataBytes: 211140
1018
+ },
1019
+ {
1020
+ gasUsed: "17458224",
1021
+ transactionHash: "0xae26838942cf8b5499d43cb5e74681ae87aec77890a8eabddd692ff83830e013",
1022
+ blockNumber: "172",
1023
+ blockHash: "0x3e513447e0cfdbb682a95b7a719b0d300ec46b0ee22b518eaae7fb082f6436e7",
1024
+ calldataBytes: 211140
1025
+ },
1026
+ {
1027
+ gasUsed: "17458524",
1028
+ transactionHash: "0xeaa07e77fe958f4317e71b07ddb876482ae9c5172fd6d6cefaacc551dbbda7d5",
1029
+ blockNumber: "172",
1030
+ blockHash: "0x12b34c1fd2e15480276052842157c2a6355acdd43d7bd01ae7511c3f39e0ecfc",
1031
+ calldataBytes: 211140
1032
+ }
1033
+ ]
1034
+ },
1035
+ {
1036
+ id: "draw-credit-120-full",
1037
+ shape: {
1038
+ kind: "draw-credit",
1039
+ target: "evm",
1040
+ capacity: 120,
1041
+ noteInputs: 0,
1042
+ noteOutputs: 0,
1043
+ sourceTrees: 1,
1044
+ creditInputs: 120,
1045
+ creditOutputs: 0,
1046
+ creditRemainders: 0,
1047
+ funding: "none",
1048
+ permit: false,
1049
+ deliveryBytes: 0
1050
+ },
1051
+ circuit: {
1052
+ circuitName: "credit_draw_slots120",
1053
+ target: "evm",
1054
+ artifactSha256: "6ccd0366a669c50fd5da875c3eae194fe8aa4c36d35a5f9ebfd64636ea599b48",
1055
+ vkSha256: "d715848afc5c1ecdfcef5ed5026865abef5040a3bc232fd65330a5ffee8475fb"
1056
+ },
1057
+ samples: [
1058
+ {
1059
+ gasUsed: "6289576",
1060
+ transactionHash: "0xbf11743f7edc5ed5ff334efc5e35634f45e48e4940d33ddd9c87d8fe444dafc5",
1061
+ blockNumber: "172",
1062
+ blockHash: "0x774de17971107b73cab2cd20f26b60665f55a37b0cc1147166babf16743e34d5",
1063
+ calldataBytes: 65220
1064
+ },
1065
+ {
1066
+ gasUsed: "6289768",
1067
+ transactionHash: "0x651bb13e0645ee8a08657db627f1072f5e964ddaff44f70f829440ed68488dea",
1068
+ blockNumber: "172",
1069
+ blockHash: "0xa9795828565fb0ce65bda295073106b8bbdc110bb8317d269839d3db3e312d5b",
1070
+ calldataBytes: 65220
1071
+ },
1072
+ {
1073
+ gasUsed: "6289720",
1074
+ transactionHash: "0x2a859d381cb4b50830971b1ffc9789b11569fc96147e130dae6fecd141f5ceb0",
1075
+ blockNumber: "172",
1076
+ blockHash: "0x7d990830157bfeff8e5cbe580e9effe97faa7676c9957ce32891b76c83961430",
1077
+ calldataBytes: 65220
1078
+ }
1079
+ ]
1080
+ },
1081
+ {
1082
+ id: "top-up-credit-1x1-unchanged-limits",
1083
+ shape: {
1084
+ kind: "top-up-credit",
1085
+ target: "evm",
1086
+ capacity: 10,
1087
+ noteInputs: 1,
1088
+ noteOutputs: 1,
1089
+ sourceTrees: 2,
1090
+ creditInputs: 1,
1091
+ creditOutputs: 1,
1092
+ creditRemainders: 0,
1093
+ funding: "none",
1094
+ permit: false,
1095
+ deliveryBytes: 1360
1096
+ },
1097
+ circuit: {
1098
+ circuitName: "credit_top_up",
1099
+ target: "evm",
1100
+ artifactSha256: "2ffebd5753ec1b0c050204d4f97498765fe61ea01a793a9b2466c2f97536345c",
1101
+ vkSha256: "40b02a9d2e7eb7b49daaac4b7760328537b7982fd5a225cc065bb74cd5ef44b3"
1102
+ },
1103
+ samples: [
1104
+ {
1105
+ gasUsed: "1711282",
1106
+ transactionHash: "0x74d45084bb07bacabbced09ee6ef69d8632a22a4493be783c326c47e929ba0ed",
1107
+ blockNumber: "172",
1108
+ blockHash: "0x3503643f7081b52ae20d4754a0e9b11f52034ae48059f5b5298546c2570fa091",
1109
+ calldataBytes: 12292
1110
+ },
1111
+ {
1112
+ gasUsed: "1711282",
1113
+ transactionHash: "0x4b5e2432d5571f6b56507b3ab995a8120560ba608959ff100f03b87873e72be6",
1114
+ blockNumber: "172",
1115
+ blockHash: "0xca15dc309371a5aa9c7bc5bf1d65c5b325c71528ce7856ba68a118114124fccc",
1116
+ calldataBytes: 12292
1117
+ },
1118
+ {
1119
+ gasUsed: "1711390",
1120
+ transactionHash: "0x304f3740b64c80dcc5c894fb30af59080d96a11e08371096ae695cbc46ef2c8b",
1121
+ blockNumber: "172",
1122
+ blockHash: "0x9671ed76d6b8e49a36ba229d3609289fcf70756f31277ac5fc0e3f08cd52304f",
1123
+ calldataBytes: 12292
1124
+ }
1125
+ ]
1126
+ },
1127
+ {
1128
+ id: "top-up-credit-1x1-changed-limits",
1129
+ shape: {
1130
+ kind: "top-up-credit",
1131
+ target: "evm",
1132
+ capacity: 10,
1133
+ noteInputs: 1,
1134
+ noteOutputs: 1,
1135
+ sourceTrees: 2,
1136
+ creditInputs: 1,
1137
+ creditOutputs: 1,
1138
+ creditRemainders: 0,
1139
+ funding: "none",
1140
+ permit: false,
1141
+ deliveryBytes: 1360
1142
+ },
1143
+ circuit: {
1144
+ circuitName: "credit_top_up",
1145
+ target: "evm",
1146
+ artifactSha256: "2ffebd5753ec1b0c050204d4f97498765fe61ea01a793a9b2466c2f97536345c",
1147
+ vkSha256: "40b02a9d2e7eb7b49daaac4b7760328537b7982fd5a225cc065bb74cd5ef44b3"
1148
+ },
1149
+ samples: [
1150
+ {
1151
+ gasUsed: "1711318",
1152
+ transactionHash: "0x65284df534b42631f8a592fb2a6efc16361a4cc122f1a8dd41418e7b950f48f1",
1153
+ blockNumber: "172",
1154
+ blockHash: "0xf198242a1edf5b133961568c9165648c829729e7bfbbf57a1e148551c971b87c",
1155
+ calldataBytes: 12292
1156
+ },
1157
+ {
1158
+ gasUsed: "1711438",
1159
+ transactionHash: "0xcee89a81e598974798365c4ebada806fb51196ee602334b0fffdbb25da0afe25",
1160
+ blockNumber: "172",
1161
+ blockHash: "0xb506a6fb54cc2f91b803211ed955aac0203fba93e2428f8f52ec0d413c90af09",
1162
+ calldataBytes: 12292
1163
+ },
1164
+ {
1165
+ gasUsed: "1711342",
1166
+ transactionHash: "0x957de5c79f365c9b0510b9e125a662317494aad50cb446edceef6f678d561cc7",
1167
+ blockNumber: "172",
1168
+ blockHash: "0xb1d5cffd6d6db58ade9d5e16d48b060b9ab2152415966dc809e7e70785472ab8",
1169
+ calldataBytes: 12292
1170
+ }
1171
+ ]
1172
+ },
1173
+ {
1174
+ id: "cancel-credit-1",
1175
+ shape: {
1176
+ kind: "cancel-credit",
1177
+ target: "evm",
1178
+ capacity: 1,
1179
+ noteInputs: 0,
1180
+ noteOutputs: 0,
1181
+ sourceTrees: 1,
1182
+ creditInputs: 1,
1183
+ creditOutputs: 0,
1184
+ creditRemainders: 0,
1185
+ funding: "none",
1186
+ permit: false,
1187
+ deliveryBytes: 0
1188
+ },
1189
+ circuit: {
1190
+ circuitName: "credit_cancel",
1191
+ target: "evm",
1192
+ artifactSha256: "b4459c2cf756d096e37291cf4d7cd129866b6d420b6d03c928f383b057112ccb",
1193
+ vkSha256: "fc8ad196ef15f3328afcc8f01d867a3ebefd15451c2813948442fab1923b73b2"
1194
+ },
1195
+ samples: [
1196
+ {
1197
+ gasUsed: "985543",
1198
+ transactionHash: "0x29ca63fbefcc5e92dbc86f67d6280993e567a5dd02ff3defd7f3251ce711865e",
1199
+ blockNumber: "172",
1200
+ blockHash: "0xecd7808fe9f7467af917069bd7a82ab0324e3cbab8dcad622b089d6e3eee9a58",
1201
+ calldataBytes: 9540
1202
+ },
1203
+ {
1204
+ gasUsed: "985795",
1205
+ transactionHash: "0xaf8bca0769330f89b647363f99b752dbbe6fdbb8b1aae912224f6a3a59f40faa",
1206
+ blockNumber: "172",
1207
+ blockHash: "0x58e1358e02f189d57628fa7c504b87fb000fe60eb9f0a0c3c0e58dae876e64da",
1208
+ calldataBytes: 9540
1209
+ },
1210
+ {
1211
+ gasUsed: "985711",
1212
+ transactionHash: "0x2c911fd5a422f6f72f2a00b16872b7e46e182d39b8f5bfa9e3b2bf99d3155da7",
1213
+ blockNumber: "172",
1214
+ blockHash: "0x9da571cbe63f52232261ee1527d5ed97a9e90e374b4fcda97d04feb25114d18e",
1215
+ calldataBytes: 9540
1216
+ }
1217
+ ]
1218
+ }
1219
+ ]
1220
+ },
1221
+ {
1222
+ formatVersion: 1,
1223
+ id: "protocol-92ef274-osaka-real",
1224
+ deployment: {
1225
+ chainId: "31337",
1226
+ protocolAddress: "0x8870C63A18a9480C7de9B860b849fD293832856D",
1227
+ runtimeCodeHash: "0x604572c0da90ea139b774cd0d2962a2972fac46e0556c7cec6f6f9aac5deef14",
1228
+ tokenAddress: "0x4826533B4897376654Bb4d4AD88B7faFD0C98528"
1229
+ },
1230
+ source: {
1231
+ protocolCommit: "92ef274c6b36d783507699a33ee20e52192c83c7",
1232
+ measuredAt: "2026-10-27T08:42:15.991Z",
1233
+ chain: "Anvil 31337",
1234
+ hardfork: "osaka",
1235
+ token: "MockERC20",
1236
+ verifier: "real",
1237
+ assumptions: [
1238
+ "normal CREATE/Factory deployment; no code or storage injection",
1239
+ "Solidity 0.8.27 optimizer 200; real BB 5.2.1 verifiers",
1240
+ "one source tree; two existing leaves; no rollover or screener",
1241
+ "funding/approval setup excluded; complete transaction receipt gas included",
1242
+ "exact allowance for caller funding; configured benchmark payout balances",
1243
+ "observed local samples, not a confidence interval or gas limit"
1244
+ ]
1245
+ },
1246
+ measurements: [
1247
+ {
1248
+ id: "shield-1",
1249
+ shape: {
1250
+ kind: "shield",
1251
+ target: "evm",
1252
+ capacity: 0,
1253
+ noteInputs: 0,
1254
+ noteOutputs: 1,
1255
+ sourceTrees: 0,
1256
+ creditInputs: 0,
1257
+ creditOutputs: 0,
1258
+ creditRemainders: 0,
1259
+ funding: "caller",
1260
+ permit: false,
1261
+ deliveryBytes: 226
1262
+ },
1263
+ circuit: null,
1264
+ samples: [
1265
+ {
1266
+ gasUsed: "649286",
1267
+ transactionHash: "0xcc299d1780ada9a69b1d9f0f3d06a165db15fccbd2b7ff407834f02f5d563a18",
1268
+ blockNumber: "50",
1269
+ blockHash: "0xbcb868e781a20588d2fa099a4d7f87c1600044a2e5ec1e369e384d7a5f22f00a",
1270
+ calldataBytes: 1156
1271
+ },
1272
+ {
1273
+ gasUsed: "649322",
1274
+ transactionHash: "0x95139dff109725989f0769e3e6fb9bd3e7e1bf581fd475f14e822875eb90fda4",
1275
+ blockNumber: "50",
1276
+ blockHash: "0x7ace353fea4fc8c856c0fd45521d200b02619921977709ff4f910e0ff41c06fe",
1277
+ calldataBytes: 1156
1278
+ },
1279
+ {
1280
+ gasUsed: "649322",
1281
+ transactionHash: "0xef578bb38dc8ff8bfd47d2e76e3ab4273019ea9a385f5d2fd99add32ceaecb58",
1282
+ blockNumber: "50",
1283
+ blockHash: "0xded817f8ef89637e2443e3b626c0837f184ca134fe753be913d5570554c649a6",
1284
+ calldataBytes: 1156
1285
+ }
1286
+ ]
1287
+ },
1288
+ {
1289
+ id: "shield-2",
1290
+ shape: {
1291
+ kind: "shield",
1292
+ target: "evm",
1293
+ capacity: 0,
1294
+ noteInputs: 0,
1295
+ noteOutputs: 2,
1296
+ sourceTrees: 0,
1297
+ creditInputs: 0,
1298
+ creditOutputs: 0,
1299
+ creditRemainders: 0,
1300
+ funding: "caller",
1301
+ permit: false,
1302
+ deliveryBytes: 452
613
1303
  },
1304
+ circuit: null,
614
1305
  samples: [
615
1306
  {
616
- gasUsed: "5389227",
617
- transactionHash: "0xb820d3c358724c1d64422017f232d074e4ff1ffaf1b1ce5ee719409427cf2208",
618
- blockNumber: "49",
619
- blockHash: "0x474bd1e52457801d1a596a9f23aeb6d365a17be028ee0c8cf8fd4758eaa1106b",
620
- calldataBytes: 36356
1307
+ gasUsed: "757063",
1308
+ transactionHash: "0x024e2dfbd6f50c368e2a4aa347e3029de668f4ebd36b80227aa003bb7ac21c74",
1309
+ blockNumber: "50",
1310
+ blockHash: "0x8ed63973c158d706ac54bb646626e4f0db5777b4bd56d179b94503af6c417c50",
1311
+ calldataBytes: 1668
621
1312
  },
622
1313
  {
623
- gasUsed: "5389095",
624
- transactionHash: "0x16514d8cf1136d7a7f40591859e2ea2d256af66520498e1fc81eb28837db600d",
625
- blockNumber: "49",
626
- blockHash: "0x42314a0d6eb9e765869e1b66b279444c78f919d2c28aed544d9fa7ac3bd2acb4",
627
- calldataBytes: 36356
1314
+ gasUsed: "757063",
1315
+ transactionHash: "0x898d852ab28f68adac4d30b160a3dbfee33fa7ca875f70df9eb7763b6b1cd1f0",
1316
+ blockNumber: "50",
1317
+ blockHash: "0x9bb6810de38193933a9f26fa03d3d9bad1ca0151ff5e04544c56520e09da3043",
1318
+ calldataBytes: 1668
628
1319
  },
629
1320
  {
630
- gasUsed: "5389203",
631
- transactionHash: "0xee69d565a7eafb60ad7a47afe80a49d4fa40b50660669d9141e7dc6f4c3dbe0d",
632
- blockNumber: "49",
633
- blockHash: "0x0dcdada663ee04dd63e06fcdb79dacc5623201d29b687f63deede2b4762a994e",
634
- calldataBytes: 36356
1321
+ gasUsed: "757039",
1322
+ transactionHash: "0x8ff9720e3197aab2d741fbd8d0fa2969203ea8cd051d9649d1e5eb890bcc2be3",
1323
+ blockNumber: "50",
1324
+ blockHash: "0x8604c75eb6363aaae774276e638f5b749aae1f8f815eb99ab1183137eef5730e",
1325
+ calldataBytes: 1668
635
1326
  }
636
1327
  ]
637
1328
  },
638
1329
  {
639
- id: "transfer-1x112",
1330
+ id: "shield-10",
640
1331
  shape: {
641
- kind: "transfer",
1332
+ kind: "shield",
642
1333
  target: "evm",
643
- capacity: 168,
644
- noteInputs: 1,
645
- noteOutputs: 112,
646
- sourceTrees: 1,
1334
+ capacity: 0,
1335
+ noteInputs: 0,
1336
+ noteOutputs: 10,
1337
+ sourceTrees: 0,
647
1338
  creditInputs: 0,
648
1339
  creditOutputs: 0,
649
1340
  creditRemainders: 0,
650
- funding: "none",
1341
+ funding: "caller",
651
1342
  permit: false,
652
- deliveryBytes: 25312
653
- },
654
- circuit: {
655
- circuitName: "transact_user_slots168",
656
- target: "evm",
657
- artifactSha256: "f7b3b1384e961367702f544299ca3521d8205fac31b7691c45ff84325d5a31c3",
658
- vkSha256: "e00181533d7e35d2307570528f9e7f8f88e2909b6ae338d93373b608dea96881"
1343
+ deliveryBytes: 2260
659
1344
  },
1345
+ circuit: null,
660
1346
  samples: [
661
1347
  {
662
- gasUsed: "9139842",
663
- transactionHash: "0x09951c4e00b868b6660429d187a482004646e4c84ef341d3b98352c249db6a06",
664
- blockNumber: "49",
665
- blockHash: "0xba9da3c08189335acff1eb33554f5f12475e4a6510324cf6ec9eadf340ce15d2",
666
- calldataBytes: 61444
1348
+ gasUsed: "1692143",
1349
+ transactionHash: "0x6c13db8bd8a8599daf5034e56712abefbf406982fafe7647b6d22291ba4199ed",
1350
+ blockNumber: "50",
1351
+ blockHash: "0x1ab2ae514f408a79e0c40ca10cee74b2e23d7c8a5f24641b8eea3e1cf58ce700",
1352
+ calldataBytes: 5764
667
1353
  },
668
1354
  {
669
- gasUsed: "9139650",
670
- transactionHash: "0xb06f69d1c6e5406758918d5d296ab889bab4c3814f616cc581ad312cc7ebb2f3",
671
- blockNumber: "49",
672
- blockHash: "0x5516a76b4b366f2e539a67bb848b7d232c3e6f328d34ca5bd3dba43a14c316bf",
673
- calldataBytes: 61444
1355
+ gasUsed: "1692083",
1356
+ transactionHash: "0x5e476c9d3838b782a51332af9bf5c372d29fc411c2168a7af619c52bd5309c7b",
1357
+ blockNumber: "50",
1358
+ blockHash: "0x9c62bc72fc90f990c6711b48865ff922a1856ae05c4fef61dad5f4da7d948401",
1359
+ calldataBytes: 5764
674
1360
  },
675
1361
  {
676
- gasUsed: "9139530",
677
- transactionHash: "0x116c4875b7712b7cb51cdb0fcb6e66a95733dca272aa272bc0b1fd265edbe26c",
678
- blockNumber: "49",
679
- blockHash: "0xd36340fddd1eace21b73f785c6589bf73b07bef782f2e78a5e3d3d828b0b607c",
680
- calldataBytes: 61444
1362
+ gasUsed: "1692203",
1363
+ transactionHash: "0x0092e2d9160fad95279cde586fc6c79c713244f55db8a2060a5abab9d98c176a",
1364
+ blockNumber: "50",
1365
+ blockHash: "0xac1bf780b4cc05b4dcc7ee5d741c049ba99ab4af9bdcd25104add730c2a14152",
1366
+ calldataBytes: 5764
681
1367
  }
682
1368
  ]
683
1369
  },
684
1370
  {
685
- id: "withdraw-1x1",
1371
+ id: "transfer-1x2",
686
1372
  shape: {
687
- kind: "withdraw",
1373
+ kind: "transfer",
688
1374
  target: "evm",
689
1375
  capacity: 14,
690
1376
  noteInputs: 1,
691
- noteOutputs: 1,
1377
+ noteOutputs: 2,
692
1378
  sourceTrees: 1,
693
1379
  creditInputs: 0,
694
1380
  creditOutputs: 0,
695
1381
  creditRemainders: 0,
696
1382
  funding: "none",
697
1383
  permit: false,
698
- deliveryBytes: 226
1384
+ deliveryBytes: 452
699
1385
  },
700
1386
  circuit: {
701
1387
  circuitName: "transact_user_slots14",
@@ -705,222 +1391,222 @@ var gas_benchmarks_default = [
705
1391
  },
706
1392
  samples: [
707
1393
  {
708
- gasUsed: "1597571",
709
- transactionHash: "0x326892d32146e0bc36b396fd3973151a629312df68ed25a4ffbb6a3da23ba274",
1394
+ gasUsed: "1617516",
1395
+ transactionHash: "0xf49ea3d31cc1346472172e2dee84f9360f60a3fe948a3ef6e87f727af6d42f0d",
710
1396
  blockNumber: "49",
711
- blockHash: "0x3e0f326cba3dd019b86431b4c22145758a7f10c121a696a81a094746b04495b5",
712
- calldataBytes: 10564
1397
+ blockHash: "0xf59c57e63ec2f03abc36d28f273b0af5290184dc97197df740b23d79a851a887",
1398
+ calldataBytes: 11012
713
1399
  },
714
1400
  {
715
- gasUsed: "1597715",
716
- transactionHash: "0x2e3a15157ac9c07e4717bbd4641481ce3bc0068d26157752815b6ec6b30acdd0",
1401
+ gasUsed: "1617516",
1402
+ transactionHash: "0xf8d11286f1f2a4db006ff6b06900c47d0fbf685984499e1e5d4aea49478ba8e5",
717
1403
  blockNumber: "49",
718
- blockHash: "0xab7fceac97d55e8702d1202b98d3a05c4b1e0f71e51b6d88d7e80e91cc338596",
719
- calldataBytes: 10564
1404
+ blockHash: "0xeb5a800190be3534c9e2675c97ac56d0e0be8adef55f60bd32d375776a7d150c",
1405
+ calldataBytes: 11012
720
1406
  },
721
1407
  {
722
- gasUsed: "1597595",
723
- transactionHash: "0x5052e94a67520c43416cdcb60a1365a126560861173d0eef46bcbf0a566fe947",
1408
+ gasUsed: "1617504",
1409
+ transactionHash: "0x8939fcea97079a3c5118b9e94325455e2ad1cdb47310ae499a277272654b3eb6",
724
1410
  blockNumber: "49",
725
- blockHash: "0x9a64cf76b646b5a07b72fcc61266e87f17365fec891701c331982a93e5ba9b89",
726
- calldataBytes: 10564
1411
+ blockHash: "0xecffefb593e2fec5d5827cfd39d0cc4d0efb67dbff6f8dbbd0d2db2439a80cf9",
1412
+ calldataBytes: 11012
727
1413
  }
728
1414
  ]
729
1415
  },
730
1416
  {
731
- id: "sweep-1x0",
1417
+ id: "transfer-1x14",
732
1418
  shape: {
733
- kind: "sweep",
1419
+ kind: "transfer",
734
1420
  target: "evm",
735
- capacity: 14,
1421
+ capacity: 56,
736
1422
  noteInputs: 1,
737
- noteOutputs: 0,
1423
+ noteOutputs: 14,
738
1424
  sourceTrees: 1,
739
1425
  creditInputs: 0,
740
1426
  creditOutputs: 0,
741
1427
  creditRemainders: 0,
742
1428
  funding: "none",
743
1429
  permit: false,
744
- deliveryBytes: 0
1430
+ deliveryBytes: 3164
745
1431
  },
746
1432
  circuit: {
747
- circuitName: "transact_user_slots14",
1433
+ circuitName: "transact_user_slots56",
748
1434
  target: "evm",
749
- artifactSha256: "2a6a20839e90b88b1ecd629f59a01821bad3ee11dbe04db1fd9cdce7a3de0e84",
750
- vkSha256: "ffe0e1a4e690792ecb4eb1fc1acc9ff60f13d3b5af03cfc6ae6d6bf26e99bdea"
1435
+ artifactSha256: "ba83ec2f177d16fa88ea04bc54f2e99920f1ac195cdb05b88b9b3bbc245fd953",
1436
+ vkSha256: "6ad5d3aff0c72a632fb19895658af093a6a92478a9994985e838a71e61237720"
751
1437
  },
752
1438
  samples: [
753
1439
  {
754
- gasUsed: "1069308",
755
- transactionHash: "0xb1ab469d05ca5f49659f54a332cc172892dcce37e475342fbf52fa9cfb4d3927",
1440
+ gasUsed: "2489010",
1441
+ transactionHash: "0x053557acea930a869d6469c91e9bc015d0893607a6ab18d2af684986f7074676",
756
1442
  blockNumber: "49",
757
- blockHash: "0xe5b04579149987198801f1ca19ab771d5262de2aaf9861a6c962d50d1c6baef0",
758
- calldataBytes: 10116
1443
+ blockHash: "0x734873097eb5e4cb66bfc2cdb61fac6753b53a4b9450fb22895281100af3aaf3",
1444
+ calldataBytes: 17156
759
1445
  },
760
1446
  {
761
- gasUsed: "1069284",
762
- transactionHash: "0xd6adee997f7e1e19e3918f913f6ee48d94df69c09ed74e333325023089e7f6df",
1447
+ gasUsed: "2489106",
1448
+ transactionHash: "0xb3990edb994011775e275bc1eb38c527b7206a2bfadf510e8aa53e260f3594b8",
763
1449
  blockNumber: "49",
764
- blockHash: "0xcb225566f8f1ea6ae8da30158b8f1aef03d50fa4ea352a00aa42b7f41a05d63c",
765
- calldataBytes: 10116
1450
+ blockHash: "0xf8cb019ebb0ecd0ec5d6634198292883c63fe93a7c65c34f9f3120c6cc54f1cf",
1451
+ calldataBytes: 17156
766
1452
  },
767
1453
  {
768
- gasUsed: "1069308",
769
- transactionHash: "0xe06dd7f3a2718bc9a9412c2d6f505960ce225b2e5fe6c1c66bb5b0e8f427006f",
1454
+ gasUsed: "2489094",
1455
+ transactionHash: "0xc97079019567ff8a79d285421351ee4bc48d14092a0e12ff634151719e991088",
770
1456
  blockNumber: "49",
771
- blockHash: "0x37a08c5918892e1c19df017c746ab0ede03c1bb195c3be593d70c1f9de91897e",
772
- calldataBytes: 10116
1457
+ blockHash: "0x5a6947839165c8961eeeb9190331415c40366a78b4a6a5771e7b8954dbb8b3c7",
1458
+ calldataBytes: 17156
773
1459
  }
774
1460
  ]
775
1461
  },
776
1462
  {
777
- id: "create-credit-1x1",
1463
+ id: "transfer-1x56",
778
1464
  shape: {
779
- kind: "create-credit",
1465
+ kind: "transfer",
780
1466
  target: "evm",
781
- capacity: 10,
1467
+ capacity: 112,
782
1468
  noteInputs: 1,
783
- noteOutputs: 1,
1469
+ noteOutputs: 56,
784
1470
  sourceTrees: 1,
785
1471
  creditInputs: 0,
786
- creditOutputs: 1,
1472
+ creditOutputs: 0,
787
1473
  creditRemainders: 0,
788
1474
  funding: "none",
789
1475
  permit: false,
790
- deliveryBytes: 1162
1476
+ deliveryBytes: 12656
791
1477
  },
792
1478
  circuit: {
793
- circuitName: "create_credit",
1479
+ circuitName: "transact_user_slots112",
794
1480
  target: "evm",
795
- artifactSha256: "ab97cd5a036851a9748a5cfd8e6f9834e23090c8e95db4531aabfc37d3abb353",
796
- vkSha256: "fac0e65b768a28750323cca851990598af936611125b6cfa3f5c16b04c7d084f"
1481
+ artifactSha256: "713b78469b6e97711122210f8497942120c1c9d66d3604bc184566c4eba59cc3",
1482
+ vkSha256: "d6a46e297949c28b9a62fd9aef1f202870fdca97b8bfb15beefd27b9e9f3d86e"
797
1483
  },
798
1484
  samples: [
799
1485
  {
800
- gasUsed: "1627325",
801
- transactionHash: "0x7763d93a5b1e8797b5f4af2e1e5b1bb029a8b0f9f7b90bcc04f581947d826803",
1486
+ gasUsed: "5389227",
1487
+ transactionHash: "0xb820d3c358724c1d64422017f232d074e4ff1ffaf1b1ce5ee719409427cf2208",
802
1488
  blockNumber: "49",
803
- blockHash: "0x93e51ae5e99c68dc642693d478e444330d8e26255ff5bb9aafc4a3f4e70d3a45",
804
- calldataBytes: 11940
1489
+ blockHash: "0x474bd1e52457801d1a596a9f23aeb6d365a17be028ee0c8cf8fd4758eaa1106b",
1490
+ calldataBytes: 36356
805
1491
  },
806
1492
  {
807
- gasUsed: "1627385",
808
- transactionHash: "0xe246d59cafa2a26dddf21c8385dd843be4d4596388ebe23e936df84e7f906635",
1493
+ gasUsed: "5389095",
1494
+ transactionHash: "0x16514d8cf1136d7a7f40591859e2ea2d256af66520498e1fc81eb28837db600d",
809
1495
  blockNumber: "49",
810
- blockHash: "0x3c24b2d6ed2a998562d34b49e0517515742a9b39d59aec38a9ac6b22be1b694b",
811
- calldataBytes: 11940
1496
+ blockHash: "0x42314a0d6eb9e765869e1b66b279444c78f919d2c28aed544d9fa7ac3bd2acb4",
1497
+ calldataBytes: 36356
812
1498
  },
813
1499
  {
814
- gasUsed: "1627157",
815
- transactionHash: "0x2f7ed0b75435cc6a820d0cd90fd82d362f74787057413722b6eb3c6e37db87d3",
1500
+ gasUsed: "5389203",
1501
+ transactionHash: "0xee69d565a7eafb60ad7a47afe80a49d4fa40b50660669d9141e7dc6f4c3dbe0d",
816
1502
  blockNumber: "49",
817
- blockHash: "0x0a0301670b46017da772800c68bb941245ac1941c79fde9c85717632154e15ee",
818
- calldataBytes: 11940
1503
+ blockHash: "0x0dcdada663ee04dd63e06fcdb79dacc5623201d29b687f63deede2b4762a994e",
1504
+ calldataBytes: 36356
819
1505
  }
820
1506
  ]
821
1507
  },
822
1508
  {
823
- id: "draw-credit-1-partial",
1509
+ id: "transfer-1x112",
824
1510
  shape: {
825
- kind: "draw-credit",
1511
+ kind: "transfer",
826
1512
  target: "evm",
827
- capacity: 1,
828
- noteInputs: 0,
829
- noteOutputs: 0,
1513
+ capacity: 168,
1514
+ noteInputs: 1,
1515
+ noteOutputs: 112,
830
1516
  sourceTrees: 1,
831
- creditInputs: 1,
832
- creditOutputs: 1,
833
- creditRemainders: 1,
1517
+ creditInputs: 0,
1518
+ creditOutputs: 0,
1519
+ creditRemainders: 0,
834
1520
  funding: "none",
835
1521
  permit: false,
836
- deliveryBytes: 936
1522
+ deliveryBytes: 25312
837
1523
  },
838
1524
  circuit: {
839
- circuitName: "credit_draw_slots1",
1525
+ circuitName: "transact_user_slots168",
840
1526
  target: "evm",
841
- artifactSha256: "f5e458790948f37a61a833fad52cf2cc3b26a59515d271de32e0caaa4e229eb5",
842
- vkSha256: "613699a440f50a0937e4c57e5152b5fdea42c31b10157d6b93226fef313df553"
1527
+ artifactSha256: "f7b3b1384e961367702f544299ca3521d8205fac31b7691c45ff84325d5a31c3",
1528
+ vkSha256: "e00181533d7e35d2307570528f9e7f8f88e2909b6ae338d93373b608dea96881"
843
1529
  },
844
1530
  samples: [
845
1531
  {
846
- gasUsed: "1581294",
847
- transactionHash: "0xd438e22b0fa07a657279f182537e4996f1936f0881d5b7d637845f8ca2808aab",
1532
+ gasUsed: "9139842",
1533
+ transactionHash: "0x09951c4e00b868b6660429d187a482004646e4c84ef341d3b98352c249db6a06",
848
1534
  blockNumber: "49",
849
- blockHash: "0x9e384a3054530b1ff237a639bca1a559afb2b73b30e21c262aac85ebf480fc9b",
850
- calldataBytes: 11396
1535
+ blockHash: "0xba9da3c08189335acff1eb33554f5f12475e4a6510324cf6ec9eadf340ce15d2",
1536
+ calldataBytes: 61444
851
1537
  },
852
1538
  {
853
- gasUsed: "1581402",
854
- transactionHash: "0xa70ac3e7284b6e98f8591a6ba88e4ddfb23ecbd05343641d0532f34920e10b56",
1539
+ gasUsed: "9139650",
1540
+ transactionHash: "0xb06f69d1c6e5406758918d5d296ab889bab4c3814f616cc581ad312cc7ebb2f3",
855
1541
  blockNumber: "49",
856
- blockHash: "0x37c5eb34ce96a841e96c36103a7ab65c1a3e08603dc9843efb0c0752c069f1d4",
857
- calldataBytes: 11396
1542
+ blockHash: "0x5516a76b4b366f2e539a67bb848b7d232c3e6f328d34ca5bd3dba43a14c316bf",
1543
+ calldataBytes: 61444
858
1544
  },
859
1545
  {
860
- gasUsed: "1581174",
861
- transactionHash: "0xd062494979d0bc0e284ccb070f87b48f3e8e5befb6001f15a006dd2a4a72ca24",
1546
+ gasUsed: "9139530",
1547
+ transactionHash: "0x116c4875b7712b7cb51cdb0fcb6e66a95733dca272aa272bc0b1fd265edbe26c",
862
1548
  blockNumber: "49",
863
- blockHash: "0x12840d920f14163b2d29491f28cee616e1bb9fd9514a4debe10ae35256345fc1",
864
- calldataBytes: 11396
1549
+ blockHash: "0xd36340fddd1eace21b73f785c6589bf73b07bef782f2e78a5e3d3d828b0b607c",
1550
+ calldataBytes: 61444
865
1551
  }
866
1552
  ]
867
1553
  },
868
1554
  {
869
- id: "top-up-credit-1x1",
1555
+ id: "withdraw-1x1",
870
1556
  shape: {
871
- kind: "top-up-credit",
1557
+ kind: "withdraw",
872
1558
  target: "evm",
873
- capacity: 10,
1559
+ capacity: 14,
874
1560
  noteInputs: 1,
875
1561
  noteOutputs: 1,
876
- sourceTrees: 2,
877
- creditInputs: 1,
878
- creditOutputs: 1,
1562
+ sourceTrees: 1,
1563
+ creditInputs: 0,
1564
+ creditOutputs: 0,
879
1565
  creditRemainders: 0,
880
1566
  funding: "none",
881
1567
  permit: false,
882
- deliveryBytes: 1162
1568
+ deliveryBytes: 226
883
1569
  },
884
1570
  circuit: {
885
- circuitName: "credit_top_up",
1571
+ circuitName: "transact_user_slots14",
886
1572
  target: "evm",
887
- artifactSha256: "ee9dbcf8be6f6c09478190996e90b1d39d4a10a00245950f69fc1d2c329c6e9b",
888
- vkSha256: "0c369fec0469b60baebb3be650bad42f3ccae6f0ff139cce6ad9a3f451ed7513"
1573
+ artifactSha256: "2a6a20839e90b88b1ecd629f59a01821bad3ee11dbe04db1fd9cdce7a3de0e84",
1574
+ vkSha256: "ffe0e1a4e690792ecb4eb1fc1acc9ff60f13d3b5af03cfc6ae6d6bf26e99bdea"
889
1575
  },
890
1576
  samples: [
891
1577
  {
892
- gasUsed: "1666948",
893
- transactionHash: "0x1403da01167962a4349d2655ea217bfcfc1a2390138bea0279792c44b4381dd2",
1578
+ gasUsed: "1597571",
1579
+ transactionHash: "0x326892d32146e0bc36b396fd3973151a629312df68ed25a4ffbb6a3da23ba274",
894
1580
  blockNumber: "49",
895
- blockHash: "0xcb554ffcdb4afe5f6458e5d23ffbdd1fdbef9c23f982343065772c0b3e3dd633",
896
- calldataBytes: 12100
1581
+ blockHash: "0x3e0f326cba3dd019b86431b4c22145758a7f10c121a696a81a094746b04495b5",
1582
+ calldataBytes: 10564
897
1583
  },
898
1584
  {
899
- gasUsed: "1666900",
900
- transactionHash: "0x3b5e54f29e3f888a443526cf23ab9255b3f0c7adf1d0d127c16b85f4c6a324d9",
1585
+ gasUsed: "1597715",
1586
+ transactionHash: "0x2e3a15157ac9c07e4717bbd4641481ce3bc0068d26157752815b6ec6b30acdd0",
901
1587
  blockNumber: "49",
902
- blockHash: "0xeb304df6bdd24b249cac3197b543b0eaa6381ed75ad812dff248f914864105ed",
903
- calldataBytes: 12100
1588
+ blockHash: "0xab7fceac97d55e8702d1202b98d3a05c4b1e0f71e51b6d88d7e80e91cc338596",
1589
+ calldataBytes: 10564
904
1590
  },
905
1591
  {
906
- gasUsed: "1666780",
907
- transactionHash: "0x81c5ef25268a719275cb3b80618c2af291e1f7b3f91d7e82cc26bc894a8c332a",
1592
+ gasUsed: "1597595",
1593
+ transactionHash: "0x5052e94a67520c43416cdcb60a1365a126560861173d0eef46bcbf0a566fe947",
908
1594
  blockNumber: "49",
909
- blockHash: "0xfa42070d6349fc8d559b8bd4ad0ee6b79089107540c4472b9e492b8f5a6bd3e4",
910
- calldataBytes: 12100
1595
+ blockHash: "0x9a64cf76b646b5a07b72fcc61266e87f17365fec891701c331982a93e5ba9b89",
1596
+ calldataBytes: 10564
911
1597
  }
912
1598
  ]
913
1599
  },
914
1600
  {
915
- id: "cancel-credit-1",
1601
+ id: "sweep-1x0",
916
1602
  shape: {
917
- kind: "cancel-credit",
1603
+ kind: "sweep",
918
1604
  target: "evm",
919
- capacity: 1,
920
- noteInputs: 0,
1605
+ capacity: 14,
1606
+ noteInputs: 1,
921
1607
  noteOutputs: 0,
922
1608
  sourceTrees: 1,
923
- creditInputs: 1,
1609
+ creditInputs: 0,
924
1610
  creditOutputs: 0,
925
1611
  creditRemainders: 0,
926
1612
  funding: "none",
@@ -928,32 +1614,32 @@ var gas_benchmarks_default = [
928
1614
  deliveryBytes: 0
929
1615
  },
930
1616
  circuit: {
931
- circuitName: "credit_cancel",
1617
+ circuitName: "transact_user_slots14",
932
1618
  target: "evm",
933
- artifactSha256: "d332453a2b8c2c544747ac8d5f01912c9757f48d986226fd6a9b0e24d8321474",
934
- vkSha256: "1f8a3c20cb081d6a90962556da3124919cc4e5675e59ad31562af39299da02fb"
1619
+ artifactSha256: "2a6a20839e90b88b1ecd629f59a01821bad3ee11dbe04db1fd9cdce7a3de0e84",
1620
+ vkSha256: "ffe0e1a4e690792ecb4eb1fc1acc9ff60f13d3b5af03cfc6ae6d6bf26e99bdea"
935
1621
  },
936
1622
  samples: [
937
1623
  {
938
- gasUsed: "998146",
939
- transactionHash: "0x97bc72692d241e2c344b912804f9939061db5ef59cf4bb23922d93812e382160",
1624
+ gasUsed: "1069308",
1625
+ transactionHash: "0xb1ab469d05ca5f49659f54a332cc172892dcce37e475342fbf52fa9cfb4d3927",
940
1626
  blockNumber: "49",
941
- blockHash: "0x2e09df4df84a1c25961386febe8404531bb5da274836d50cc15a26c91b433a98",
942
- calldataBytes: 9540
1627
+ blockHash: "0xe5b04579149987198801f1ca19ab771d5262de2aaf9861a6c962d50d1c6baef0",
1628
+ calldataBytes: 10116
943
1629
  },
944
1630
  {
945
- gasUsed: "998134",
946
- transactionHash: "0x26c5067b12c2bc4b694070784e6b19d4855efa6e77c2422f0c6b1567f061570a",
1631
+ gasUsed: "1069284",
1632
+ transactionHash: "0xd6adee997f7e1e19e3918f913f6ee48d94df69c09ed74e333325023089e7f6df",
947
1633
  blockNumber: "49",
948
- blockHash: "0xdd3f20520c09e001374cab58387e52c82446db053539e30dad28b0de679a333c",
949
- calldataBytes: 9540
1634
+ blockHash: "0xcb225566f8f1ea6ae8da30158b8f1aef03d50fa4ea352a00aa42b7f41a05d63c",
1635
+ calldataBytes: 10116
950
1636
  },
951
1637
  {
952
- gasUsed: "998230",
953
- transactionHash: "0x5dc09445a405150da1445c22f50d6dd10d8d428a6a3f41ee90db7d3574657e31",
1638
+ gasUsed: "1069308",
1639
+ transactionHash: "0xe06dd7f3a2718bc9a9412c2d6f505960ce225b2e5fe6c1c66bb5b0e8f427006f",
954
1640
  blockNumber: "49",
955
- blockHash: "0x5c8f8223a50d2c8d48188a2db28ffa33c1b150a2fb465e99db4430949db3664b",
956
- calldataBytes: 9540
1641
+ blockHash: "0x37a08c5918892e1c19df017c746ab0ede03c1bb195c3be593d70c1f9de91897e",
1642
+ calldataBytes: 10116
957
1643
  }
958
1644
  ]
959
1645
  }
@@ -984,6 +1670,29 @@ function copyGasBenchmarks(profiles) {
984
1670
  for (const p of copy) {
985
1671
  if (p.formatVersion !== 1 || !p.id || !decimal.test(p.deployment.chainId) || !address.test(p.deployment.protocolAddress) || !address.test(p.deployment.tokenAddress) || !p.deployment.runtimeCodeHash || !word.test(p.deployment.runtimeCodeHash) || p.source.verifier !== "real" || !/^[0-9a-f]{40}$/i.test(p.source.protocolCommit) || !p.source.measuredAt || !Array.isArray(p.source.assumptions) || !p.source.assumptions.every((assumption) => typeof assumption === "string") || !p.measurements.length)
986
1672
  throw new Error("invalid gas benchmark profile");
1673
+ if (p.source.fingerprints && ![
1674
+ "protocolSourceSha256",
1675
+ "dirtyDiffSha256",
1676
+ "compiledArtifactsSha256",
1677
+ "creditManifestSha256",
1678
+ "userManifestSha256",
1679
+ "sdkSourceSha256"
1680
+ ].every((key) => {
1681
+ const v = p.source.fingerprints[key];
1682
+ return typeof v === "string" && /^[a-f0-9]{64}$/i.test(v);
1683
+ }))
1684
+ throw new Error("invalid benchmark source fingerprint");
1685
+ if (p.source.blockGasLimit !== void 0 && (!decimal.test(p.source.blockGasLimit) || BigInt(p.source.blockGasLimit) <= 0n))
1686
+ throw new Error("invalid benchmark block gas limit");
1687
+ if (p.source.runtimeContracts && !Object.values(p.source.runtimeContracts).every(
1688
+ (v) => address.test(v.address) && word.test(v.runtimeCodeHash)
1689
+ ))
1690
+ throw new Error("invalid benchmark runtime identity");
1691
+ if (p.source.toolchain && (!["solidity", "barretenberg", "noir", "evmVersion", "anvil"].every((key) => {
1692
+ const v = p.source.toolchain[key];
1693
+ return typeof v === "string" && v.length > 0;
1694
+ }) || !Number.isSafeInteger(p.source.toolchain.optimizerRuns) || p.source.toolchain.optimizerRuns < 0))
1695
+ throw new Error("invalid benchmark toolchain");
987
1696
  for (const m of p.measurements) {
988
1697
  if (!m.id || !m.samples.length || !["none", "caller", "signature"].includes(m.shape.funding) || typeof m.shape.permit !== "boolean")
989
1698
  throw new Error("invalid gas benchmark measurement");
@@ -1063,11 +1772,20 @@ function estimateBenchmarkGas(plan, protocol, profiles) {
1063
1772
  );
1064
1773
  if (!request.deployment.runtimeCodeHash || !candidates.length)
1065
1774
  return { ...base, available: false, reason: "deployment-not-covered" };
1066
- for (const profile of candidates) {
1067
- const measurement = profile.measurements.find(
1775
+ const exact = candidates.flatMap(
1776
+ (profile) => profile.measurements.filter(
1068
1777
  (m) => shapeKeys.every((key) => m.shape[key] === request.shape[key]) && sameCircuit(m.circuit, request.circuit)
1069
- );
1070
- if (!measurement) continue;
1778
+ ).map((measurement) => ({ profile, measurement }))
1779
+ );
1780
+ const mean = (measurement) => {
1781
+ const count = BigInt(measurement.samples.length);
1782
+ return (measurement.samples.reduce((sum, s) => sum + BigInt(s.gasUsed), 0n) + count - 1n) / count;
1783
+ };
1784
+ exact.sort(
1785
+ (a, b) => mean(a.measurement) > mean(b.measurement) ? -1 : mean(a.measurement) < mean(b.measurement) ? 1 : a.measurement.id.localeCompare(b.measurement.id)
1786
+ );
1787
+ if (exact.length) {
1788
+ const { profile, measurement } = exact[0];
1071
1789
  const gas = measurement.samples.map((sample) => BigInt(sample.gasUsed));
1072
1790
  const count = BigInt(gas.length);
1073
1791
  return {
@@ -1097,14 +1815,20 @@ function estimateShapeGas(request, profiles = defaultProfiles) {
1097
1815
  const matching = measurements.filter(
1098
1816
  (measurement) => measurement.shape.kind === request.shape.kind && measurement.shape.target === request.shape.target && sameCircuit(measurement.circuit, request.circuit)
1099
1817
  );
1100
- const exact = matching.find(
1818
+ const exact = matching.filter(
1101
1819
  (measurement) => shapeKeys.every((key) => measurement.shape[key] === request.shape[key])
1102
1820
  );
1103
- if (exact) {
1104
- const gas = exact.samples.map((sample) => BigInt(sample.gasUsed));
1105
- const count = BigInt(gas.length);
1106
- return { gasUnits: (gas.reduce((sum, value) => sum + value, 0n) + count - 1n) / count };
1821
+ if (exact.length) {
1822
+ const means = exact.map((m) => {
1823
+ const count = BigInt(m.samples.length);
1824
+ return (m.samples.reduce((sum, s) => sum + BigInt(s.gasUsed), 0n) + count - 1n) / count;
1825
+ });
1826
+ return { gasUnits: means.reduce((max, v) => v > max ? v : max) };
1107
1827
  }
1828
+ if (["create-credit", "draw-credit", "top-up-credit", "cancel-credit"].includes(
1829
+ request.shape.kind
1830
+ ) && !matching.length)
1831
+ throw new Error("No current Credit gas reference for this artifact and verification key");
1108
1832
  const candidates = matching.length ? matching : measurements.filter(
1109
1833
  (measurement) => measurement.shape.kind === request.shape.kind && measurement.shape.target === request.shape.target
1110
1834
  );
@@ -1119,7 +1843,22 @@ function estimateShapeGas(request, profiles = defaultProfiles) {
1119
1843
  "deliveryBytes",
1120
1844
  ...!matching.length ? ["capacity"] : []
1121
1845
  ];
1122
- const estimates = candidates.map((measurement) => {
1846
+ const groups = /* @__PURE__ */ new Map();
1847
+ for (const candidate of candidates) {
1848
+ const key = JSON.stringify([
1849
+ shapeKeys.map((k) => candidate.shape[k]),
1850
+ candidate.circuit?.circuitName,
1851
+ candidate.circuit?.target,
1852
+ candidate.circuit?.artifactSha256.toLowerCase(),
1853
+ candidate.circuit?.vkSha256.toLowerCase()
1854
+ ]);
1855
+ const previous = groups.get(key);
1856
+ groups.set(
1857
+ key,
1858
+ previous ? { ...candidate, samples: [...previous.samples, ...candidate.samples] } : candidate
1859
+ );
1860
+ }
1861
+ const estimates = [...groups.values()].map((measurement) => {
1123
1862
  let numerator = 1n;
1124
1863
  let denominator = 1n;
1125
1864
  for (const key of dimensions) {
@@ -1214,12 +1953,13 @@ function readProtocolLogs(receipt, protocolAddress) {
1214
1953
  }
1215
1954
 
1216
1955
  // src/session/discovery.ts
1956
+ import { MAX_CIPHERTEXT_BYTES } from "@invisi-labs/core";
1217
1957
  import { isAddress } from "ethers";
1218
1958
  import {
1219
1959
  decodeAddress,
1220
1960
  ReceivingAddress
1221
1961
  } from "@invisi-labs/core";
1222
- import { normalizeDelivery } from "@invisi-labs/protocol";
1962
+ import { normalizeOpaqueDelivery } from "@invisi-labs/protocol";
1223
1963
  var EVENTS = /* @__PURE__ */ new Set([
1224
1964
  "CommitmentsInserted",
1225
1965
  "BatchOutputs",
@@ -1312,7 +2052,7 @@ function extractDeliveryCandidates(logs, context, confirmedThrough) {
1312
2052
  check(inserted, "delivery has no matching canonical insertion");
1313
2053
  if (commitment !== void 0)
1314
2054
  check(hash(commitment) === inserted, "delivery commitment conflicts with insertion");
1315
- const delivery = normalizeDelivery(wire, { credit: role !== "funds" });
2055
+ const delivery = normalizeOpaqueDelivery(wire);
1316
2056
  check(
1317
2057
  typeof token === "string" && isAddress(token) && BigInt(token) !== 0n,
1318
2058
  "invalid event token"
@@ -1343,7 +2083,7 @@ function extractDeliveryCandidates(logs, context, confirmedThrough) {
1343
2083
  add(log, tree, index(leaves[0]), fields.creditCommitment, "owner", ds[0]);
1344
2084
  add(log, tree, index(leaves[0]), fields.creditCommitment, "spender", ds[1]);
1345
2085
  if (hasChange) add(log, tree, index(leaves[1]), change, "funds", ds[2]);
1346
- else normalizeDelivery(ds[2], { empty: true });
2086
+ else normalizeOpaqueDelivery(ds[2], { empty: true });
1347
2087
  };
1348
2088
  for (const log of relevant) {
1349
2089
  const a = object(log.args);
@@ -1373,7 +2113,7 @@ function extractDeliveryCandidates(logs, context, confirmedThrough) {
1373
2113
  const length = Number.parseInt(packed.slice(offset, offset + 4), 16);
1374
2114
  offset += 4;
1375
2115
  check(
1376
- length >= 160 && length <= 416 && offset + length * 2 + 136 <= packed.length,
2116
+ length >= 1 && length <= MAX_CIPHERTEXT_BYTES && offset + length * 2 + 136 <= packed.length,
1377
2117
  "invalid packed delivery length"
1378
2118
  );
1379
2119
  const ciphertext = `0x${packed.slice(offset, offset + length * 2)}`;
@@ -1395,8 +2135,8 @@ function extractDeliveryCandidates(logs, context, confirmedThrough) {
1395
2135
  cs.forEach((c, i) => {
1396
2136
  if (BigInt(hash(c)) === 0n) {
1397
2137
  check(integer(leaves[i]) === 0n, "absent remainder has nonzero position");
1398
- normalizeDelivery(ds[2 * i], { empty: true });
1399
- normalizeDelivery(ds[2 * i + 1], { empty: true });
2138
+ normalizeOpaqueDelivery(ds[2 * i], { empty: true });
2139
+ normalizeOpaqueDelivery(ds[2 * i + 1], { empty: true });
1400
2140
  } else {
1401
2141
  add(log, tree, index(leaves[i]), c, "owner", ds[2 * i]);
1402
2142
  add(log, tree, index(leaves[i]), c, "spender", ds[2 * i + 1]);
@@ -1590,7 +2330,7 @@ function scopeKey(scope) {
1590
2330
  return bytesToHex(
1591
2331
  sha256(
1592
2332
  utf8ToBytes(
1593
- "Invisi.WalletScope.v2:" + JSON.stringify([
2333
+ "Invisi.WalletScope.v1:" + JSON.stringify([
1594
2334
  scope.namespace,
1595
2335
  scope.chainId.toString(),
1596
2336
  scope.protocolAddress.toLowerCase(),
@@ -1705,10 +2445,15 @@ var MemoryAtomicRecords = class {
1705
2445
  };
1706
2446
 
1707
2447
  // src/session/operation-execution.ts
1708
- import { verifyTypedData } from "ethers";
2448
+ import { Signature, SigningKey, getBytes as getBytes2, concat, verifyTypedData } from "ethers";
1709
2449
  import {
1710
- computeWalletAuthorizationDigest
2450
+ computeWalletAuthorizationDigest,
2451
+ AuthorizedStatement,
2452
+ computeWalletIdentity,
2453
+ createSigningRequest,
2454
+ walletAuthorizationTypedData
1711
2455
  } from "@invisi-labs/core";
2456
+ import { WitnessBuilder as WitnessBuilder2 } from "@invisi-labs/protocol";
1712
2457
 
1713
2458
  // src/session/proof-integrity.ts
1714
2459
  import { getBytes } from "ethers";
@@ -1744,16 +2489,34 @@ async function authorizeOperation(plan, provider) {
1744
2489
  return signed;
1745
2490
  }
1746
2491
  async function proveOperation(protocol, plan, authorization, prover, options) {
2492
+ if (Object.hasOwn(options, "target")) {
2493
+ throw new Error("prove accepts execution, not a backend target");
2494
+ }
2495
+ const { execution = "single", ...proverOptions } = options;
2496
+ if (execution !== "single" && execution !== "aggregate") {
2497
+ throw new Error("execution must be single or aggregate");
2498
+ }
2499
+ const frozen = statement(plan);
2500
+ if (execution === "aggregate" && (plan.kind !== "transfer" || plan.capacity !== 14)) {
2501
+ throw new Error("aggregate execution requires a 14-slot transfer");
2502
+ }
2503
+ if (plan.kind === "transfer") {
2504
+ plan.statement = WitnessBuilder2.statement(
2505
+ frozen.circuitName,
2506
+ frozen.expectedPublicInputs,
2507
+ execution === "aggregate" ? "noir-recursive" : "evm"
2508
+ );
2509
+ }
1747
2510
  const request = await witnessFor(protocol, plan, authorization);
1748
2511
  if (JSON.stringify({ ...request, witness: void 0 }) !== JSON.stringify(plan.statement))
1749
2512
  throw new Error("prepared proof statement changed");
1750
2513
  try {
1751
- const proof = publicProof(await prover.prove(request, options));
2514
+ const proof = publicProof(await prover.prove(request, proverOptions));
1752
2515
  sameStatement(proof, plan.statement);
1753
2516
  if (await prover.verify(
1754
2517
  structuredClone(proof),
1755
2518
  structuredClone(plan.statement),
1756
- options
2519
+ proverOptions
1757
2520
  ) !== true)
1758
2521
  throw new Error("proof verification failed");
1759
2522
  return proof;
@@ -1768,19 +2531,88 @@ async function signOperationFunding(saved, signer, verifier) {
1768
2531
  throw new Error("funding signer is not the payer");
1769
2532
  const typed = await fundingTypedData(saved);
1770
2533
  const signature = await signer.signTypedData(structuredClone(typed));
2534
+ return verifyFundingSignature(typed, payer, signature, verifier);
2535
+ }
2536
+ function walletSigningRequest(plan) {
2537
+ return createSigningRequest(walletAuthorizationTypedData(authorizationRequest(plan)));
2538
+ }
2539
+ async function acceptWalletSignature(plan, signature) {
2540
+ const request = authorizationRequest(plan);
2541
+ const digest = computeWalletAuthorizationDigest(request);
2542
+ try {
2543
+ const signed = Signature.from(signature);
2544
+ const publicKey = getBytes2(SigningKey.recoverPublicKey(digest, signed));
2545
+ const owner = await computeWalletIdentity(publicKey);
2546
+ if (owner.toLowerCase() !== plan.scope.walletIdentity.toLowerCase()) {
2547
+ throw new Error("wallet signature identity mismatch");
2548
+ }
2549
+ return new AuthorizedStatement(plan.scope.walletIdentity, digest, {
2550
+ public_key_x: Array.from(publicKey.slice(1, 33)),
2551
+ public_key_y: Array.from(publicKey.slice(33)),
2552
+ signature: Array.from(getBytes2(concat([signed.r, signed.s])))
2553
+ });
2554
+ } catch {
2555
+ throw new Error("invalid wallet authorization signature");
2556
+ }
2557
+ }
2558
+ async function fundingSigningRequest(saved, runtime) {
2559
+ const plan = saved.plan;
2560
+ if (plan.fundingMode !== "signature") {
2561
+ throw new Error("operation does not require a funding signature");
2562
+ }
2563
+ if (plan.kind !== "shield" && !saved.proof) {
2564
+ throw new Error("proof must precede funding authorization");
2565
+ }
2566
+ await runtime.options.protocol.validateDeployment(runtime.reader);
2567
+ const block = await runtime.reader.getBlock(await runtime.reader.getLatestBlockNumber());
2568
+ if (block.timestamp > plan.deadline || block.timestamp > (plan.funding.deadline ?? 0n)) {
2569
+ throw new Error("funding authorization expired");
2570
+ }
2571
+ if (await runtime.reader.getFundingNonce(plan.context, plan.funding.payer, block) !== plan.funding.sigNonce) {
2572
+ throw new Error("funding nonce changed; prepare again");
2573
+ }
2574
+ const request = createSigningRequest(await fundingTypedData(saved));
2575
+ if ((await runtime.reader.getBlock(block.number)).hash !== block.hash) {
2576
+ throw new Error("canonical funding block changed");
2577
+ }
2578
+ return request;
2579
+ }
2580
+ async function acceptFundingSignature(saved, signature, runtime) {
2581
+ if (!/^0x(?:[a-fA-F0-9]{2})+$/.test(signature)) {
2582
+ throw new Error("invalid EVM funding signature");
2583
+ }
2584
+ const request = await fundingSigningRequest(saved, runtime);
2585
+ return verifyFundingSignature(
2586
+ request,
2587
+ saved.plan.funding.payer,
2588
+ signature,
2589
+ runtime.options.fundingVerifier
2590
+ );
2591
+ }
2592
+ async function verifyFundingSignature(request, payer, signature, verifier) {
2593
+ if (!/^0x(?:[a-fA-F0-9]{2})+$/.test(signature)) {
2594
+ throw new Error("invalid EVM funding signature");
2595
+ }
2596
+ const types = Object.fromEntries(
2597
+ Object.entries(request.types).map(([name, fields]) => [name, [...fields]])
2598
+ );
2599
+ let validEOA = false;
2600
+ try {
2601
+ validEOA = verifyTypedData(request.domain, types, request.message, signature).toLowerCase() === payer.toLowerCase();
2602
+ if (validEOA) {
2603
+ signature = Signature.from(signature).serialized;
2604
+ }
2605
+ } catch {
2606
+ validEOA = false;
2607
+ }
1771
2608
  const valid = verifier ? await verifier.verifyTypedData({
1772
- ...structuredClone(typed),
2609
+ ...structuredClone(request),
1773
2610
  address: payer,
1774
2611
  signature
1775
- }) : verifyTypedData(
1776
- typed.domain,
1777
- Object.fromEntries(
1778
- Object.entries(typed.types).map(([name, fields]) => [name, [...fields]])
1779
- ),
1780
- typed.message,
1781
- signature
1782
- ).toLowerCase() === payer.toLowerCase();
1783
- if (valid !== true) throw new Error("invalid EVM funding signature");
2612
+ }) : validEOA;
2613
+ if (valid !== true) {
2614
+ throw new Error("invalid EVM funding signature");
2615
+ }
1784
2616
  return signature;
1785
2617
  }
1786
2618
 
@@ -1821,7 +2653,7 @@ function operationPreview(plan, status) {
1821
2653
  }
1822
2654
 
1823
2655
  // src/session/Operation.ts
1824
- import { MissingCapabilityError } from "@invisi-labs/core";
2656
+ import { MissingCapabilityError as MissingCapabilityError2 } from "@invisi-labs/core";
1825
2657
  import { normalizeFunding } from "@invisi-labs/protocol";
1826
2658
 
1827
2659
  // src/session/operation-confirmation.ts
@@ -1897,7 +2729,8 @@ async function creditLeaf(state) {
1897
2729
  n.amount,
1898
2730
  n.nonce,
1899
2731
  n.expiry,
1900
- await computeCreditSharedKeyHash(n.creditSharedKey)
2732
+ await computeCreditSharedKeyHash(n.creditSharedKey),
2733
+ n
1901
2734
  );
1902
2735
  }
1903
2736
 
@@ -2507,6 +3340,81 @@ var Operation = class _Operation {
2507
3340
  throw error;
2508
3341
  }
2509
3342
  }
3343
+ async signingCurrent() {
3344
+ await this.#runtime.store.transaction(this.#runtime.scope, (state) => {
3345
+ check5(!state.invalidated, "wallet state requires canonical resync");
3346
+ this.current(state.operations[this.id]);
3347
+ });
3348
+ }
3349
+ /** Public EIP-712 request; signing transport and key custody belong to the caller. */
3350
+ async exportWalletAuthorization(options = {}) {
3351
+ options.signal?.throwIfAborted();
3352
+ await this.signingCurrent();
3353
+ check5(
3354
+ requiresAuthorization(this.#saved.plan),
3355
+ "operation does not require wallet authorization"
3356
+ );
3357
+ check5(
3358
+ ["prepared", "authorized"].includes(this.status),
3359
+ "operation is not awaiting wallet authorization"
3360
+ );
3361
+ return walletSigningRequest(this.#saved.plan);
3362
+ }
3363
+ /** Attach an external EOA signature, retaining its witness only at the private proving boundary. */
3364
+ async withWalletSignature(signature, options = {}) {
3365
+ options.signal?.throwIfAborted();
3366
+ await this.signingCurrent();
3367
+ check5(
3368
+ requiresAuthorization(this.#saved.plan),
3369
+ "operation does not require wallet authorization"
3370
+ );
3371
+ check5(
3372
+ ["prepared", "authorized"].includes(this.status),
3373
+ "operation is not awaiting wallet authorization"
3374
+ );
3375
+ const authorization = await acceptWalletSignature(this.#saved.plan, signature);
3376
+ return this.stage(
3377
+ "wallet authorization",
3378
+ ["prepared", "authorized"],
3379
+ async () => ({ status: "authorized", authorization }),
3380
+ options.signal
3381
+ );
3382
+ }
3383
+ /** Export only after proving when the funding authorization binds an actual proof hash. */
3384
+ async exportFundingAuthorization(options = {}) {
3385
+ options.signal?.throwIfAborted();
3386
+ await this.signingCurrent();
3387
+ check5(
3388
+ this.status === (this.kind === "shield" ? "prepared" : "proved"),
3389
+ "operation is not awaiting funding authorization or proof"
3390
+ );
3391
+ const request = await fundingSigningRequest(this.#saved, this.#runtime);
3392
+ options.signal?.throwIfAborted();
3393
+ await this.signingCurrent();
3394
+ return request;
3395
+ }
3396
+ /** Verify an external signature against this handle's own frozen operation. */
3397
+ async withFundingSignature(signature, options = {}) {
3398
+ options.signal?.throwIfAborted();
3399
+ await this.signingCurrent();
3400
+ check5(
3401
+ this.status === (this.kind === "shield" ? "prepared" : "proved"),
3402
+ "operation is not awaiting funding authorization or proof"
3403
+ );
3404
+ const verified = await acceptFundingSignature(this.#saved, signature, this.#runtime);
3405
+ return this.stage(
3406
+ "funding authorization",
3407
+ this.kind === "shield" ? ["prepared"] : ["proved"],
3408
+ async (saved) => {
3409
+ saved.plan.funding.signature = verified;
3410
+ if (saved.plan.statement?.target !== "noir-recursive") {
3411
+ saved.call = await this.encode(saved);
3412
+ }
3413
+ return { status: "ready" };
3414
+ },
3415
+ options.signal
3416
+ );
3417
+ }
2510
3418
  async authorize(options = {}) {
2511
3419
  check5(
2512
3420
  requiresAuthorization(this.#saved.plan),
@@ -2527,7 +3435,8 @@ var Operation = class _Operation {
2527
3435
  options.signal
2528
3436
  );
2529
3437
  }
2530
- async prove(options = {}) {
3438
+ async prove(suppliedOptions = {}) {
3439
+ const options = { ...suppliedOptions };
2531
3440
  const plan = this.#saved.plan;
2532
3441
  check5(plan.kind !== "shield", "shield requires no proof");
2533
3442
  if (requiresAuthorization(plan)) {
@@ -2538,7 +3447,7 @@ var Operation = class _Operation {
2538
3447
  }
2539
3448
  const prover = this.#runtime.options.prover;
2540
3449
  if (!prover) {
2541
- throw new MissingCapabilityError("prover");
3450
+ throw new MissingCapabilityError2("prover");
2542
3451
  }
2543
3452
  return this.stage(
2544
3453
  "proof",
@@ -2572,7 +3481,7 @@ var Operation = class _Operation {
2572
3481
  check5(p.kind === "shield" || this.#saved.proof, "proof must precede funding authorization");
2573
3482
  const signer = this.#runtime.options.fundingSigner;
2574
3483
  if (!signer) {
2575
- throw new MissingCapabilityError("EVM funding signer");
3484
+ throw new MissingCapabilityError2("EVM funding signer");
2576
3485
  }
2577
3486
  check5(
2578
3487
  signer.address.toLowerCase() === p.funding.payer.toLowerCase(),
@@ -2761,25 +3670,142 @@ var Operation = class _Operation {
2761
3670
  }
2762
3671
  };
2763
3672
 
3673
+ // src/session/WalletSession.ts
3674
+ import { Wallet } from "@invisi-labs/core";
3675
+
3676
+ // src/session/history.ts
3677
+ function walletHistory(state, options = {}) {
3678
+ const token = options.tokenAddress?.toLowerCase();
3679
+ const outgoing = [];
3680
+ for (const record of Object.values(state.operations)) {
3681
+ const saved = record.payload;
3682
+ if (!saved?.plan || token && saved.plan.context.tokenAddress.toLowerCase() !== token) {
3683
+ continue;
3684
+ }
3685
+ const plan = saved.plan;
3686
+ outgoing.push({
3687
+ ...operationPreview(plan, record.status),
3688
+ preparedAt: { ...plan.preparedAt },
3689
+ ...record.transactionHash ? { transactionHash: record.transactionHash } : {},
3690
+ outputs: plan.outputs.map((output) => ({
3691
+ to: output.address,
3692
+ amount: output.note.amount,
3693
+ change: output.change,
3694
+ commitment: output.commitment,
3695
+ payload: Uint8Array.from(output.note.payload ?? [])
3696
+ }))
3697
+ });
3698
+ }
3699
+ outgoing.sort(
3700
+ (a, b) => a.preparedAt.number === b.preparedAt.number ? a.id.localeCompare(b.id) : a.preparedAt.number > b.preparedAt.number ? -1 : 1
3701
+ );
3702
+ const incoming = [];
3703
+ for (const record of Object.values(state.notes)) {
3704
+ const tokenAddress = `0x${record.note.tokenAddress.toString(16).padStart(40, "0")}`;
3705
+ if (token && tokenAddress !== token) continue;
3706
+ incoming.push({
3707
+ commitment: record.commitment,
3708
+ treeId: record.treeId,
3709
+ leafIndex: record.leafIndex,
3710
+ blockNumber: record.blockNumber,
3711
+ blockHash: record.blockHash,
3712
+ ...record.transactionHash ? { transactionHash: record.transactionHash } : {},
3713
+ tokenAddress,
3714
+ amount: record.note.amount,
3715
+ payload: Uint8Array.from(record.note.payload ?? []),
3716
+ spent: record.spent
3717
+ });
3718
+ }
3719
+ incoming.sort(
3720
+ (a, b) => a.blockNumber === b.blockNumber ? a.commitment.localeCompare(b.commitment) : a.blockNumber > b.blockNumber ? -1 : 1
3721
+ );
3722
+ return structuredClone({
3723
+ revision: state.revision,
3724
+ checkedThrough: state.discoveryThrough ?? null,
3725
+ invalidated: !!state.invalidated,
3726
+ outgoing,
3727
+ incoming
3728
+ });
3729
+ }
3730
+
2764
3731
  // src/session/WalletSession.ts
2765
3732
  import { getAddress as getAddress4 } from "ethers";
2766
- import { MissingCapabilityError as MissingCapabilityError3 } from "@invisi-labs/core";
3733
+ import { MissingCapabilityError as MissingCapabilityError5 } from "@invisi-labs/core";
2767
3734
 
2768
3735
  // src/session/transaction-preparation.ts
2769
3736
  import { getAddress as getAddress3 } from "ethers";
2770
3737
  import {
2771
3738
  normalizeTransactRequest,
2772
3739
  transactUserPublicInputs as transactUserPublicInputs2,
2773
- WitnessBuilder as WitnessBuilder3,
3740
+ WitnessBuilder as WitnessBuilder4,
2774
3741
  ZERO_ADDRESS
2775
3742
  } from "@invisi-labs/protocol";
2776
3743
 
3744
+ // src/resolve-recipient.ts
3745
+ import {
3746
+ MissingCapabilityError as MissingCapabilityError3,
3747
+ ReceivingAddress as ReceivingAddress2
3748
+ } from "@invisi-labs/core";
3749
+ async function resolveRecipient(address2, lookup, details = {}) {
3750
+ const context = { ...details, address: address2 };
3751
+ let recipient;
3752
+ try {
3753
+ recipient = ReceivingAddress2.parse(address2);
3754
+ } catch (cause) {
3755
+ throw new InvisiError("INVALID_RECIPIENT", "Invalid recipient address", {
3756
+ ...context,
3757
+ cause
3758
+ });
3759
+ }
3760
+ if (recipient.kind === "long") return recipient;
3761
+ if (!lookup) {
3762
+ throw new InvisiError("MISSING_CAPABILITY", "Missing registry lookup capability", {
3763
+ ...context,
3764
+ capability: "registry lookup"
3765
+ });
3766
+ }
3767
+ let keys;
3768
+ try {
3769
+ keys = await lookup(recipient.walletIdentity);
3770
+ } catch (cause) {
3771
+ if (cause instanceof MissingCapabilityError3) {
3772
+ throw new InvisiError("MISSING_CAPABILITY", cause.message, {
3773
+ ...context,
3774
+ cause,
3775
+ capability: cause.capability
3776
+ });
3777
+ }
3778
+ throw new InvisiError("RECIPIENT_LOOKUP_FAILED", "Recipient registry lookup failed", {
3779
+ ...context,
3780
+ cause
3781
+ });
3782
+ }
3783
+ if (keys == null) {
3784
+ throw new InvisiError(
3785
+ "EVM_ADDRESS_NOT_REGISTERED",
3786
+ "EVM address has no registered receiving keys",
3787
+ context
3788
+ );
3789
+ }
3790
+ try {
3791
+ return ReceivingAddress2.from({
3792
+ walletIdentity: recipient.walletIdentity,
3793
+ viewingPublicKey: keys.viewingPublicKey,
3794
+ clueKey: keys.clueKey
3795
+ });
3796
+ } catch (cause) {
3797
+ throw new InvisiError(
3798
+ "RECIPIENT_LOOKUP_FAILED",
3799
+ "Registry returned invalid receiving keys",
3800
+ { ...context, cause }
3801
+ );
3802
+ }
3803
+ }
3804
+
2777
3805
  // src/session/prepare-common.ts
2778
3806
  import { getAddress, hexlify } from "ethers";
2779
3807
  import {
2780
- encodeMemo,
2781
- MissingCapabilityError as MissingCapabilityError2,
2782
- ReceivingAddress as ReceivingAddress2,
3808
+ MissingCapabilityError as MissingCapabilityError4,
2783
3809
  computeNoteCommitment,
2784
3810
  computeNoteIdentity,
2785
3811
  createClue,
@@ -2821,6 +3847,27 @@ function positiveAmount(value, bits = 128) {
2821
3847
  }
2822
3848
  return value;
2823
3849
  }
3850
+ function copyApplicationPayload(value) {
3851
+ if (value === void 0) return new Uint8Array();
3852
+ if (!(value instanceof Uint8Array)) throw new TypeError("payload must be Uint8Array");
3853
+ return Uint8Array.from(value);
3854
+ }
3855
+ function positiveOutputAmount(payment, outputIndex) {
3856
+ try {
3857
+ return positiveAmount(payment.amount);
3858
+ } catch (cause) {
3859
+ throw new InvisiError(
3860
+ "PREPARATION_FAILED",
3861
+ cause instanceof Error ? cause.message : "Invalid output amount",
3862
+ {
3863
+ address: payment.to,
3864
+ field: "amount",
3865
+ ...outputIndex === void 0 ? {} : { outputIndex },
3866
+ cause
3867
+ }
3868
+ );
3869
+ }
3870
+ }
2824
3871
  var Preparation = class {
2825
3872
  constructor(runtime) {
2826
3873
  this.runtime = runtime;
@@ -2843,7 +3890,15 @@ var Preparation = class {
2843
3890
  throw new Error("canonical wallet checkpoint changed; resync required");
2844
3891
  }
2845
3892
  }
2846
- return { context: { ...options.protocol.context, now: block.timestamp }, block, deadline };
3893
+ return {
3894
+ context: {
3895
+ ...options.protocol.context,
3896
+ now: block.timestamp,
3897
+ timestamp: block.timestamp
3898
+ },
3899
+ block,
3900
+ deadline
3901
+ };
2847
3902
  }
2848
3903
  async assertBlock(frame) {
2849
3904
  if ((await this.runtime.reader.getBlock(frame.block.number)).hash !== frame.block.hash) {
@@ -2882,52 +3937,70 @@ var Preparation = class {
2882
3937
  }
2883
3938
  return { funding, fundingMode: mode };
2884
3939
  }
2885
- async output(payment, context, change = false) {
2886
- positiveAmount(payment.amount);
2887
- const recipient = await ReceivingAddress2.parse(payment.to).resolve(
2888
- this.runtime.options.addressResolver
2889
- );
2890
- const memo = encodeMemo(payment.memo);
2891
- const nonce = generateNonce();
2892
- const identity = await computeNoteIdentity(BigInt(recipient.walletIdentity), nonce);
2893
- const keys = recipient.getReceivingKeys();
2894
- const note = {
2895
- chainId: context.chainId,
2896
- protocolAddress: BigInt(context.protocolAddress),
2897
- tokenAddress: BigInt(context.tokenAddress),
2898
- walletIdentity: recipient.walletIdentity,
2899
- amount: payment.amount,
2900
- ...memo.length === 0 ? {} : { memo },
2901
- nonce
2902
- };
2903
- const commitment = await computeNoteCommitment(
2904
- context.chainId,
2905
- identity,
2906
- note.tokenAddress,
2907
- note.amount
2908
- );
2909
- return {
2910
- note,
2911
- commitment,
2912
- identity,
2913
- address: payment.to,
2914
- change,
2915
- delivery: {
2916
- ciphertext: hexlify(
2917
- await encryptPrivateTransferNote(keys.viewingPublicKey, note, {
2918
- chainId: context.chainId,
2919
- protocolAddress: note.protocolAddress,
2920
- outputCommitment: commitment
2921
- })
2922
- ),
2923
- clue: hexlify(createClue(keys.clueKey))
2924
- }
2925
- };
3940
+ async output(payment, context, change = false, outputIndex) {
3941
+ try {
3942
+ positiveOutputAmount(payment, outputIndex);
3943
+ const recipient = await resolveRecipient(
3944
+ payment.to,
3945
+ this.runtime.options.addressResolver,
3946
+ {
3947
+ field: change ? "changeAddress" : "to",
3948
+ ...outputIndex === void 0 ? {} : { outputIndex }
3949
+ }
3950
+ );
3951
+ const nonce = generateNonce();
3952
+ const identity = await computeNoteIdentity(BigInt(recipient.walletIdentity), nonce);
3953
+ const keys = recipient.getReceivingKeys();
3954
+ const note = {
3955
+ chainId: context.chainId,
3956
+ protocolAddress: BigInt(context.protocolAddress),
3957
+ tokenAddress: BigInt(context.tokenAddress),
3958
+ walletIdentity: recipient.walletIdentity,
3959
+ amount: payment.amount,
3960
+ payload: copyApplicationPayload(payment.payload),
3961
+ nonce
3962
+ };
3963
+ const commitment = await computeNoteCommitment(
3964
+ context.chainId,
3965
+ identity,
3966
+ note.tokenAddress,
3967
+ note.amount
3968
+ );
3969
+ return {
3970
+ note,
3971
+ commitment,
3972
+ identity,
3973
+ address: payment.to,
3974
+ change,
3975
+ delivery: {
3976
+ ciphertext: hexlify(
3977
+ await encryptPrivateTransferNote(keys.viewingPublicKey, note, {
3978
+ chainId: context.chainId,
3979
+ protocolAddress: note.protocolAddress,
3980
+ outputCommitment: commitment
3981
+ })
3982
+ ),
3983
+ clue: hexlify(createClue(keys.clueKey))
3984
+ }
3985
+ };
3986
+ } catch (cause) {
3987
+ if (cause instanceof InvisiError) throw cause;
3988
+ throw new InvisiError(
3989
+ "PREPARATION_FAILED",
3990
+ cause instanceof Error ? cause.message : "Output preparation failed",
3991
+ {
3992
+ address: payment.to,
3993
+ field: change ? "changeAddress" : "to",
3994
+ ...outputIndex === void 0 ? {} : { outputIndex },
3995
+ cause
3996
+ }
3997
+ );
3998
+ }
2926
3999
  }
2927
4000
  async membership(input, frame) {
2928
4001
  const { options, reader } = this.runtime;
2929
4002
  if (!options.protocolRpc)
2930
- throw new MissingCapabilityError2("Protocol RPC membership provider");
4003
+ throw new MissingCapabilityError4("Protocol RPC membership provider");
2931
4004
  const root = this.#roots.get(input.treeId);
2932
4005
  const proof = await options.protocolRpc.getMembership(
2933
4006
  frame.context,
@@ -3030,7 +4103,8 @@ function storedCandidates(inputs) {
3030
4103
  import { getAddress as getAddress2, hexlify as hexlify2, toBeHex } from "ethers";
3031
4104
  import {
3032
4105
  FIELD_MODULUS as FIELD_MODULUS3,
3033
- ReceivingAddress as ReceivingAddress3,
4106
+ normalizeCreditPolicy,
4107
+ applyCreditDrawUsage,
3034
4108
  computeCreditNullifier as computeCreditNullifier2,
3035
4109
  computeCreditRecoveryPad,
3036
4110
  createClue as createClue2,
@@ -3041,7 +4115,7 @@ import {
3041
4115
  normalizeCreditDeliveryState as normalizeCreditDeliveryState2
3042
4116
  } from "@invisi-labs/core";
3043
4117
  import {
3044
- WitnessBuilder as WitnessBuilder2,
4118
+ WitnessBuilder as WitnessBuilder3,
3045
4119
  cancelCreditPublicInputs as cancelCreditPublicInputs2,
3046
4120
  createCreditPublicInputs as createCreditPublicInputs2,
3047
4121
  creditDrawPublicInputs as creditDrawPublicInputs2,
@@ -3132,10 +4206,16 @@ var CreditPreparation = class {
3132
4206
  positiveAmount(options.amount, 126);
3133
4207
  const frame = await this.#prepare.frame(options.deadline);
3134
4208
  const expiry = this.expiry(options.expiry, frame);
3135
- const spender = await ReceivingAddress3.parse(options.spender).resolve(
3136
- this.runtime.options.addressResolver
4209
+ const spender = await resolveRecipient(
4210
+ options.spender,
4211
+ this.runtime.options.addressResolver,
4212
+ { field: "spender" }
4213
+ );
4214
+ const owner = await resolveRecipient(
4215
+ this.runtime.options.wallet.getReceivingAddress().toString(),
4216
+ this.runtime.options.addressResolver,
4217
+ { field: "wallet" }
3137
4218
  );
3138
- const owner = await this.runtime.options.wallet.getReceivingAddress().resolve(this.runtime.options.addressResolver);
3139
4219
  const ownerPayout = getAddress2(owner.walletIdentity);
3140
4220
  const spenderPayout = getAddress2(spender.walletIdentity);
3141
4221
  if (BigInt(ownerPayout) === 0n || BigInt(spenderPayout) === 0n) {
@@ -3151,8 +4231,13 @@ var CreditPreparation = class {
3151
4231
  spenderWalletIdentity: spender.walletIdentity,
3152
4232
  ownerPayout: BigInt(ownerPayout),
3153
4233
  spenderPayout: BigInt(spenderPayout),
4234
+ ...normalizeCreditPolicy({
4235
+ singleLimit: options.singleLimit ?? 0n,
4236
+ dailyLimit: options.dailyLimit ?? 0n,
4237
+ monthlyLimit: options.monthlyLimit ?? 0n
4238
+ }),
3154
4239
  amount: options.amount,
3155
- ...options.memo === void 0 ? {} : { memo: options.memo },
4240
+ payload: copyApplicationPayload(options.payload),
3156
4241
  expiry,
3157
4242
  nonce: generateNonce2(),
3158
4243
  creditSharedKey: generateCreditSharedKey()
@@ -3217,12 +4302,12 @@ var CreditPreparation = class {
3217
4302
  creditNullifier: previous.nullifier,
3218
4303
  previousExpiry: previous.input.state.note.expiry
3219
4304
  };
3220
- plan.statement = WitnessBuilder2.statement(
4305
+ plan.statement = WitnessBuilder3.statement(
3221
4306
  "credit_top_up",
3222
4307
  topUpCreditPublicInputs2(frame.context, plan.credit.topUp, deliveries, plan.funding)
3223
4308
  );
3224
4309
  } else {
3225
- plan.statement = WitnessBuilder2.statement(
4310
+ plan.statement = WitnessBuilder3.statement(
3226
4311
  "create_credit",
3227
4312
  createCreditPublicInputs2(frame.context, creation, deliveries, plan.funding)
3228
4313
  );
@@ -3248,10 +4333,15 @@ var CreditPreparation = class {
3248
4333
  ...old,
3249
4334
  note: {
3250
4335
  ...old.note,
4336
+ singleLimit: options.singleLimit ?? old.note.singleLimit ?? 0n,
4337
+ dailyLimit: options.dailyLimit ?? old.note.dailyLimit ?? 0n,
4338
+ monthlyLimit: options.monthlyLimit ?? old.note.monthlyLimit ?? 0n,
3251
4339
  amount,
3252
4340
  expiry,
3253
4341
  nonce: generateNonce2(),
3254
- ...options.memo === void 0 ? {} : { memo: options.memo }
4342
+ payload: copyApplicationPayload(
4343
+ options.payload === void 0 ? old.note.payload : options.payload
4344
+ )
3255
4345
  }
3256
4346
  },
3257
4347
  frame
@@ -3299,6 +4389,7 @@ var CreditPreparation = class {
3299
4389
  }
3300
4390
  sources.set(member.source.treeId, member.source.merkleRoot);
3301
4391
  amounts.push(amount);
4392
+ const usage = applyCreditDrawUsage(n, amount, frame.block.timestamp);
3302
4393
  const remaining = n.amount - amount;
3303
4394
  if (remaining === 0n) {
3304
4395
  remainders.push(word2(0n));
@@ -3318,8 +4409,11 @@ var CreditPreparation = class {
3318
4409
  ...state,
3319
4410
  note: {
3320
4411
  ...n,
4412
+ ...usage,
3321
4413
  amount: remaining,
3322
- ...options.credits[i].memo === void 0 ? {} : { memo: options.credits[i].memo },
4414
+ payload: copyApplicationPayload(
4415
+ options.credits[i].payload === void 0 ? n.payload : options.credits[i].payload
4416
+ ),
3323
4417
  nonce: await deriveRemainderNonce(...args)
3324
4418
  }
3325
4419
  },
@@ -3352,7 +4446,7 @@ var CreditPreparation = class {
3352
4446
  draw: params,
3353
4447
  amounts
3354
4448
  };
3355
- plan.statement = WitnessBuilder2.statement(
4449
+ plan.statement = WitnessBuilder3.statement(
3356
4450
  profile.name,
3357
4451
  creditDrawPublicInputs2(frame.context, params, deliveries)
3358
4452
  );
@@ -3374,7 +4468,7 @@ var CreditPreparation = class {
3374
4468
  };
3375
4469
  plan.capacity = 1;
3376
4470
  plan.credit = { inputs: [previous.input], outputs: [], deliveries: [], cancel: params };
3377
- plan.statement = WitnessBuilder2.statement(
4471
+ plan.statement = WitnessBuilder3.statement(
3378
4472
  "credit_cancel",
3379
4473
  cancelCreditPublicInputs2(frame.context, params)
3380
4474
  );
@@ -3397,87 +4491,48 @@ var TransactionPreparation = class {
3397
4491
  return this.context.scope;
3398
4492
  }
3399
4493
  async prepareTransfer(options) {
4494
+ if (Object.hasOwn(options, "target") || Object.hasOwn(options, "execution")) {
4495
+ throw new Error(
4496
+ "prepareTransfer accepts no target or execution; choose execution in prove()"
4497
+ );
4498
+ }
3400
4499
  const copied = structuredClone(options);
3401
- const preparation = new Preparation(this.runtime(copied.tokenAddress));
4500
+ const runtime = this.runtime(copied.tokenAddress);
4501
+ if (copied.commitments !== void 0 && copied.commitments.length === 0)
4502
+ throw new Error("empty explicit input selection");
4503
+ const preparation = new Preparation({
4504
+ ...runtime,
4505
+ ...copied.commitments !== void 0 ? { inputSelection: copied.commitments } : {}
4506
+ });
3402
4507
  const frame = await preparation.frame(copied.deadline);
3403
- if (copied.outputs.length < 1 || copied.outputs.length > 168) {
3404
- throw new Error("transfer requires 1..168 outputs");
4508
+ if (copied.outputs.length > 168) throw new Error("transfer supports at most 168 outputs");
4509
+ let withdrawalAddress = ZERO_ADDRESS;
4510
+ let withdrawalAmount = 0n;
4511
+ if (copied.withdrawal !== void 0) {
4512
+ withdrawalAddress = getAddress3(copied.withdrawal.to);
4513
+ positiveAmount(copied.withdrawal.amount);
4514
+ if (BigInt(withdrawalAddress) === 0n)
4515
+ throw new Error("withdrawal destination must be nonzero");
4516
+ withdrawalAmount = copied.withdrawal.amount;
3405
4517
  }
4518
+ if (copied.outputs.length === 0 && withdrawalAmount === 0n)
4519
+ throw new Error("transfer requires a private output or public withdrawal");
3406
4520
  const total = copied.outputs.reduce(
3407
- (sum, output) => sum + positiveAmount(output.amount),
3408
- 0n
4521
+ (sum, output, index2) => sum + positiveOutputAmount(output, index2),
4522
+ withdrawalAmount
3409
4523
  );
3410
4524
  const funding = await preparation.funding(copied.funding, frame);
3411
4525
  return this.funds(
3412
- "transfer",
3413
4526
  copied.outputs,
3414
4527
  total,
3415
- ZERO_ADDRESS,
3416
- 0n,
4528
+ withdrawalAddress,
4529
+ withdrawalAmount,
3417
4530
  frame,
3418
4531
  funding,
3419
- copied.target,
3420
- preparation
3421
- );
3422
- }
3423
- async prepareWithdraw(options) {
3424
- const copied = structuredClone(options);
3425
- const preparation = new Preparation(this.runtime(copied.tokenAddress));
3426
- const frame = await preparation.frame(copied.deadline);
3427
- const to = getAddress3(copied.to);
3428
- positiveAmount(copied.amount);
3429
- if (BigInt(to) === 0n) {
3430
- throw new Error("withdrawal destination must be nonzero");
3431
- }
3432
- return this.funds(
3433
- "withdraw",
3434
- [],
3435
- copied.amount,
3436
- to,
3437
- copied.amount,
3438
- frame,
3439
- { funding: {}, fundingMode: "none" },
3440
- copied.target,
3441
- preparation
3442
- );
3443
- }
3444
- /** Full payout to the note owner; no arbitrary destination, change or spending signature. */
3445
- async prepareSweep(options) {
3446
- const copied = structuredClone(options);
3447
- const runtime = this.runtime(copied.tokenAddress);
3448
- const state = await runtime.readInventory();
3449
- const available = Object.values(state.notes).filter(
3450
- (record) => record.note.tokenAddress === BigInt(copied.tokenAddress) && record.spent === "unspent" && !state.reservations[record.commitment]
3451
- );
3452
- const selected = copied.commitments ?? available.map((record) => record.commitment);
3453
- if (selected.length === 0) throw new Error("empty sweep input selection");
3454
- if (new Set(selected).size !== selected.length) throw new Error("duplicate sweep inputs");
3455
- const byId = new Map(available.map((record) => [record.commitment, record]));
3456
- let amount = 0n;
3457
- for (const id of selected) {
3458
- const record = byId.get(id);
3459
- if (!record) throw new Error("sweep input unavailable");
3460
- amount += record.note.amount;
3461
- }
3462
- positiveAmount(amount);
3463
- const preparation = new Preparation({
3464
- ...runtime,
3465
- inputSelection: selected
3466
- });
3467
- const frame = await preparation.frame(copied.deadline);
3468
- return this.funds(
3469
- "sweep",
3470
- [],
3471
- amount,
3472
- this.scope.walletIdentity,
3473
- amount,
3474
- frame,
3475
- { funding: {}, fundingMode: "none" },
3476
- copied.target,
3477
4532
  preparation
3478
4533
  );
3479
4534
  }
3480
- async funds(kind, payments, total, withdrawalAddress, withdrawalAmount, frame, funding, target, preparation) {
4535
+ async funds(payments, total, withdrawalAddress, withdrawalAmount, frame, funding, preparation) {
3481
4536
  if (total >= 1n << 135n) {
3482
4537
  throw new Error("transaction sum exceeds uint135");
3483
4538
  }
@@ -3487,7 +4542,7 @@ var TransactionPreparation = class {
3487
4542
  frame
3488
4543
  );
3489
4544
  const outputs = await Promise.all(
3490
- payments.map((payment) => preparation.output(payment, context))
4545
+ payments.map((payment, index2) => preparation.output(payment, context, false, index2))
3491
4546
  );
3492
4547
  const change = selection.amount + (funding.funding.amount ?? 0n) - total;
3493
4548
  if (change > 0n) {
@@ -3513,16 +4568,16 @@ var TransactionPreparation = class {
3513
4568
  };
3514
4569
  const deliveries = outputs.map((output) => output.delivery);
3515
4570
  const normalized = normalizeTransactRequest(context, params, deliveries, funding.funding);
3516
- const statement2 = WitnessBuilder3.statement(
4571
+ const statement2 = WitnessBuilder4.statement(
3517
4572
  `transact_user_slots${normalized.capacity}`,
3518
4573
  transactUserPublicInputs2(context, params, deliveries, funding.funding),
3519
- target ?? "evm"
4574
+ "evm"
3520
4575
  );
3521
4576
  await preparation.assertBlock(frame);
3522
4577
  return preparation.runtime.complete({
3523
4578
  version: 1,
3524
4579
  id: crypto.randomUUID(),
3525
- kind,
4580
+ kind: "transfer",
3526
4581
  context,
3527
4582
  scope: this.scope,
3528
4583
  preparedAt: block,
@@ -3544,7 +4599,9 @@ var TransactionPreparation = class {
3544
4599
  throw new Error("shield requires 1..10 outputs");
3545
4600
  }
3546
4601
  const outputs = await Promise.all(
3547
- copied.outputs.map((output) => preparation.output(output, frame.context))
4602
+ copied.outputs.map(
4603
+ (output, index2) => preparation.output(output, frame.context, false, index2)
4604
+ )
3548
4605
  );
3549
4606
  if (outputs.reduce((sum, output) => sum + output.note.amount, 0n) !== (funding.funding.amount ?? 0n)) {
3550
4607
  throw new Error("shield funding must equal output total");
@@ -3653,7 +4710,6 @@ import { NullifierCapability } from "@invisi-labs/core";
3653
4710
 
3654
4711
  // src/session/inventory.ts
3655
4712
  import {
3656
- encodeMemo as encodeMemo2,
3657
4713
  computeCreditCommitment as computeCreditCommitment2,
3658
4714
  computeCreditNullifier as computeCreditNullifier3,
3659
4715
  computeCreditSharedKeyHash as computeCreditSharedKeyHash2,
@@ -3723,7 +4779,8 @@ var InventoryProcessor = class {
3723
4779
  n.amount,
3724
4780
  n.nonce,
3725
4781
  n.expiry,
3726
- await computeCreditSharedKeyHash2(n.creditSharedKey)
4782
+ await computeCreditSharedKeyHash2(n.creditSharedKey),
4783
+ n
3727
4784
  )
3728
4785
  );
3729
4786
  }
@@ -3770,6 +4827,9 @@ var InventoryProcessor = class {
3770
4827
  };
3771
4828
  for (const event of logs) {
3772
4829
  if (event.eventName === "CreditDraw") {
4830
+ const block = await this.#options.reader.getBlock(event.blockNumber);
4831
+ if (block.hash !== event.blockHash)
4832
+ throw new CanonicalConflict("draw block changed during Credit recovery");
3773
4833
  const args = event.args;
3774
4834
  const params = args.params;
3775
4835
  const indices = args.remainderLeafIndices;
@@ -3787,6 +4847,7 @@ var InventoryProcessor = class {
3787
4847
  context,
3788
4848
  previous.state.note,
3789
4849
  {
4850
+ timestamp: block.timestamp,
3790
4851
  creditNullifier: nullifier,
3791
4852
  remainderCommitment: params.remainderCommitments[index2],
3792
4853
  recoveryAmount: BigInt(params.recoveryAmounts[index2])
@@ -3798,7 +4859,7 @@ var InventoryProcessor = class {
3798
4859
  const child = foundByKey.get(
3799
4860
  params.remainderCommitments[index2] + ":" + previous.role
3800
4861
  );
3801
- const memo = child?.state.note.memo;
4862
+ const payload = child?.state.note.payload;
3802
4863
  const record = {
3803
4864
  commitment: params.remainderCommitments[index2],
3804
4865
  treeId: BigInt(args.outputTreeId),
@@ -3811,7 +4872,7 @@ var InventoryProcessor = class {
3811
4872
  ...clone(previous.state),
3812
4873
  note: {
3813
4874
  ...remainder,
3814
- ...memo === void 0 ? {} : { memo: encodeMemo2(memo) }
4875
+ ...payload === void 0 ? {} : { payload: clone(payload) }
3815
4876
  }
3816
4877
  },
3817
4878
  receivingKeySource: { kind: "draw", commitment: previous.commitment },
@@ -4059,6 +5120,7 @@ var WalletUpdater = class extends InventoryProcessor {
4059
5120
  draft.notes = {};
4060
5121
  draft.credits = {};
4061
5122
  delete draft.observedThrough;
5123
+ delete draft.discoveryThrough;
4062
5124
  delete draft.invalidated;
4063
5125
  }
4064
5126
  mergeReceiptRecords(draft, { notes, credits, checkpoint: block });
@@ -4090,13 +5152,38 @@ var WalletUpdater = class extends InventoryProcessor {
4090
5152
  var WalletSession = class {
4091
5153
  #options;
4092
5154
  #updater;
5155
+ #listeners = /* @__PURE__ */ new Set();
4093
5156
  #sending = /* @__PURE__ */ new Set();
4094
5157
  #refreshQueue = Promise.resolve();
4095
5158
  scope;
4096
5159
  protocol;
4097
5160
  constructor(options) {
5161
+ if ("ciphertextCodecs" in options || "envelopeVersion" in options) {
5162
+ throw new Error(
5163
+ "SDK envelope versions are fixed; encode application payload bytes externally"
5164
+ );
5165
+ }
5166
+ const store = options.store;
4098
5167
  this.#options = {
4099
5168
  ...options,
5169
+ ...store ? {
5170
+ store: {
5171
+ persistent: store.persistent,
5172
+ readSnapshot: (scope) => store.readSnapshot(scope),
5173
+ transaction: async (scope, action) => {
5174
+ const result = await store.transaction(scope, action);
5175
+ if (scopeKey(scope) === scopeKey(this.scope)) {
5176
+ for (const listener of [...this.#listeners]) {
5177
+ try {
5178
+ listener();
5179
+ } catch {
5180
+ }
5181
+ }
5182
+ }
5183
+ return result;
5184
+ }
5185
+ }
5186
+ } : {},
4100
5187
  ...options.gasBenchmarks ? { gasBenchmarks: copyGasBenchmarks(options.gasBenchmarks) } : {}
4101
5188
  };
4102
5189
  this.protocol = options.protocol;
@@ -4111,7 +5198,7 @@ var WalletSession = class {
4111
5198
  /** Delegate sending to ethers; managed operations additionally retain the resulting hash. */
4112
5199
  async sendTransaction(input, options = {}) {
4113
5200
  const signer = this.#options.signer;
4114
- if (!signer) throw new MissingCapabilityError3("ethers signer");
5201
+ if (!signer) throw new MissingCapabilityError5("ethers signer");
4115
5202
  const operation = input instanceof Operation ? input : void 0;
4116
5203
  if (operation && this.#sending.has(operation.id))
4117
5204
  throw new Error("operation is already being sent by this session");
@@ -4119,12 +5206,12 @@ var WalletSession = class {
4119
5206
  const overrides = { ...options };
4120
5207
  const plain = operation ? void 0 : { ...input };
4121
5208
  try {
4122
- if (!signer.provider) throw new MissingCapabilityError3("connected ethers signer");
5209
+ if (!signer.provider) throw new MissingCapabilityError5("connected ethers signer");
4123
5210
  if ((await signer.provider.getNetwork()).chainId !== this.protocol.context.chainId) {
4124
5211
  throw new Error("signer-provider session chain mismatch");
4125
5212
  }
4126
5213
  if (operation) {
4127
- if (!this.#options.store) throw new MissingCapabilityError3("wallet store");
5214
+ if (!this.#options.store) throw new MissingCapabilityError5("wallet store");
4128
5215
  const state = await this.#options.store.readSnapshot(this.scope);
4129
5216
  if (!state.operations[operation.id])
4130
5217
  throw new Error("operation does not belong to this wallet session");
@@ -4155,25 +5242,30 @@ var WalletSession = class {
4155
5242
  runtime(tokenAddress) {
4156
5243
  const options = this.#options;
4157
5244
  if (!options.store) {
4158
- throw new MissingCapabilityError3("wallet store");
5245
+ throw new MissingCapabilityError5("wallet store");
4159
5246
  }
4160
5247
  if (!options.chainReader) {
4161
- throw new MissingCapabilityError3("chain reader");
5248
+ throw new MissingCapabilityError5("chain reader");
4162
5249
  }
4163
5250
  return {
4164
5251
  options: { ...options, protocol: options.protocol.forToken(tokenAddress) },
4165
5252
  scope: this.scope,
4166
5253
  store: options.store,
4167
5254
  reader: options.chainReader,
4168
- authorization: () => options.authorization ?? options.wallet.exportAuthorization()
5255
+ authorization: () => {
5256
+ if (options.authorization) return options.authorization;
5257
+ if (options.wallet instanceof Wallet) return options.wallet.exportAuthorization();
5258
+ throw new MissingCapabilityError5("wallet authorization");
5259
+ }
4169
5260
  };
4170
5261
  }
4171
5262
  updater() {
4172
5263
  if (this.#updater) return this.#updater;
4173
5264
  const options = this.#options;
4174
5265
  if (!options.store || !options.chainReader || !options.protocolRpc)
4175
- throw new MissingCapabilityError3("wallet store, chain reader and Protocol RPC");
4176
- const viewing = options.viewing ?? options.wallet.getViewer();
5266
+ throw new MissingCapabilityError5("wallet store, chain reader and Protocol RPC");
5267
+ const viewing = options.viewing ?? (options.wallet instanceof Wallet ? options.wallet.getViewer() : void 0);
5268
+ if (!viewing) throw new MissingCapabilityError5("viewing");
4177
5269
  const receivingAddress = options.wallet.getReceivingAddress();
4178
5270
  const receivingKeys = receivingAddress.kind === "long" ? receivingAddress.getReceivingKeys() : void 0;
4179
5271
  this.#updater = new WalletUpdater({
@@ -4187,10 +5279,27 @@ var WalletSession = class {
4187
5279
  });
4188
5280
  return this.#updater;
4189
5281
  }
5282
+ /** Local session commits only. Host applications own cross-tab/store subscriptions. */
5283
+ subscribe(listener) {
5284
+ this.#listeners.add(listener);
5285
+ return () => {
5286
+ this.#listeners.delete(listener);
5287
+ };
5288
+ }
5289
+ /** Detached history for wallet UI; construction records do not imply chain success. */
5290
+ async getHistory(options = {}) {
5291
+ const tokenAddress = options.tokenAddress ? getAddress4(options.tokenAddress) : void 0;
5292
+ const store = this.#options.store;
5293
+ if (!store) throw new MissingCapabilityError5("wallet store");
5294
+ return walletHistory(
5295
+ await store.readSnapshot(this.scope),
5296
+ tokenAddress ? { tokenAddress } : {}
5297
+ );
5298
+ }
4190
5299
  async balance(tokenAddress) {
4191
5300
  const store = this.#options.store;
4192
5301
  if (!store) {
4193
- throw new MissingCapabilityError3("wallet store");
5302
+ throw new MissingCapabilityError5("wallet store");
4194
5303
  }
4195
5304
  return walletBalance(await store.readSnapshot(this.scope), getAddress4(tokenAddress));
4196
5305
  }
@@ -4198,15 +5307,15 @@ var WalletSession = class {
4198
5307
  async refresh(options) {
4199
5308
  const provider = this.#options.protocolRpc;
4200
5309
  const reader = this.#options.chainReader;
4201
- if (!reader) throw new MissingCapabilityError3("chain reader");
4202
- if (!provider) throw new MissingCapabilityError3("Protocol RPC");
5310
+ if (!reader) throw new MissingCapabilityError5("chain reader");
5311
+ if (!provider) throw new MissingCapabilityError5("Protocol RPC");
4203
5312
  const updater = this.updater();
4204
5313
  const request = {
4205
5314
  ...options,
4206
5315
  ...options.detectionKey ? { detectionKey: options.detectionKey.slice() } : {}
4207
5316
  };
4208
- const task = this.#refreshQueue.then(
4209
- () => refreshWallet(
5317
+ const task = this.#refreshQueue.then(async () => {
5318
+ const result = await refreshWallet(
4210
5319
  {
4211
5320
  provider,
4212
5321
  reader,
@@ -4215,8 +5324,21 @@ var WalletSession = class {
4215
5324
  apply: (batch, settings) => updater.applyUpdates(batch, settings)
4216
5325
  },
4217
5326
  request
4218
- )
4219
- );
5327
+ );
5328
+ await this.#options.store.transaction(this.scope, (state) => {
5329
+ request.signal?.throwIfAborted();
5330
+ if (state.invalidated) throw new Error("wallet requires canonical resync");
5331
+ const previous = state.discoveryThrough;
5332
+ const start = previous ? previous.number + 1n : this.protocol.deployment.protocol.fromBlock;
5333
+ if (request.fromBlock <= start && (!previous || result.block.number >= previous.number)) {
5334
+ state.discoveryThrough = {
5335
+ number: result.block.number,
5336
+ hash: result.block.hash
5337
+ };
5338
+ }
5339
+ });
5340
+ return result;
5341
+ });
4220
5342
  this.#refreshQueue = task.catch(() => {
4221
5343
  });
4222
5344
  return task;
@@ -4227,38 +5349,43 @@ var WalletSession = class {
4227
5349
  options: runtime.options,
4228
5350
  scope: runtime.scope,
4229
5351
  reader: runtime.reader,
4230
- authorization: runtime.authorization,
4231
5352
  readInventory: () => runtime.store.readSnapshot(runtime.scope),
4232
5353
  complete: (plan) => Operation.prepare(runtime, plan)
4233
5354
  });
4234
5355
  }
4235
5356
  async prepareTransfer(options) {
4236
- return this.preparation(options.tokenAddress).prepareTransfer(options);
4237
- }
4238
- async prepareWithdraw(options) {
4239
- return this.preparation(options.tokenAddress).prepareWithdraw(options);
4240
- }
4241
- async prepareSweep(options) {
4242
- return this.preparation(options.tokenAddress).prepareSweep(options);
5357
+ return prepareWithErrors("prepareTransfer", async () => {
5358
+ return this.preparation(options.tokenAddress).prepareTransfer(options);
5359
+ });
4243
5360
  }
4244
5361
  async prepareShield(options) {
4245
- return this.preparation(options.tokenAddress).prepareShield(options);
5362
+ return prepareWithErrors("prepareShield", async () => {
5363
+ return this.preparation(options.tokenAddress).prepareShield(options);
5364
+ });
4246
5365
  }
4247
5366
  async prepareCreateCredit(options) {
4248
- return this.preparation(options.tokenAddress).prepareCreateCredit(options);
5367
+ return prepareWithErrors("prepareCreateCredit", async () => {
5368
+ return this.preparation(options.tokenAddress).prepareCreateCredit(options);
5369
+ });
4249
5370
  }
4250
5371
  async prepareDrawCredit(options) {
4251
- return this.preparation(options.tokenAddress).prepareDrawCredit(options);
5372
+ return prepareWithErrors("prepareDrawCredit", async () => {
5373
+ return this.preparation(options.tokenAddress).prepareDrawCredit(options);
5374
+ });
4252
5375
  }
4253
5376
  async prepareTopUpCredit(options) {
4254
- return this.preparation(options.tokenAddress).prepareTopUpCredit(options);
5377
+ return prepareWithErrors("prepareTopUpCredit", async () => {
5378
+ return this.preparation(options.tokenAddress).prepareTopUpCredit(options);
5379
+ });
4255
5380
  }
4256
5381
  async prepareCancelCredit(options) {
4257
- return this.preparation(options.tokenAddress).prepareCancelCredit(options);
5382
+ return prepareWithErrors("prepareCancelCredit", async () => {
5383
+ return this.preparation(options.tokenAddress).prepareCancelCredit(options);
5384
+ });
4258
5385
  }
4259
5386
  async resume(operationId) {
4260
5387
  const store = this.#options.store;
4261
- if (!store) throw new MissingCapabilityError3("wallet store");
5388
+ if (!store) throw new MissingCapabilityError5("wallet store");
4262
5389
  const state = await store.readSnapshot(this.scope);
4263
5390
  const saved = state.operations[operationId]?.payload;
4264
5391
  if (!saved?.plan) throw new Error("operation not found");
@@ -4330,6 +5457,8 @@ var MemoryWalletStore = class extends TransactionalWalletStore {
4330
5457
  };
4331
5458
 
4332
5459
  export {
5460
+ InvisiError,
5461
+ prepareWithErrors,
4333
5462
  walletBalance,
4334
5463
  requiresAuthorization,
4335
5464
  statement,
@@ -4339,14 +5468,18 @@ export {
4339
5468
  defineGasBenchmarks,
4340
5469
  estimateGasReference,
4341
5470
  sameStatement,
4342
- authorizeOperation,
4343
5471
  proveOperation,
4344
- signOperationFunding,
5472
+ walletSigningRequest,
5473
+ acceptWalletSignature,
5474
+ fundingSigningRequest,
5475
+ acceptFundingSignature,
4345
5476
  operationPreview,
4346
5477
  positiveAmount,
4347
5478
  TransactionPreparation,
4348
5479
  serializeState,
4349
5480
  deserializeState,
5481
+ readProtocolLogs,
5482
+ decryptCandidates,
4350
5483
  DisclosureVerifier,
4351
5484
  TransactionalWalletStore,
4352
5485
  MemoryAtomicRecords,
@@ -4354,4 +5487,4 @@ export {
4354
5487
  WalletSession,
4355
5488
  MemoryWalletStore
4356
5489
  };
4357
- //# sourceMappingURL=chunk-Z6NDXVBL.js.map
5490
+ //# sourceMappingURL=chunk-BE52B32Z.js.map