@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.
package/dist/memory.cjs CHANGED
@@ -371,8 +371,9 @@ function readProtocolLogs(receipt, protocolAddress) {
371
371
  }
372
372
 
373
373
  // src/session/discovery.ts
374
- var import_ethers3 = require("ethers");
375
374
  var import_core = require("@invisi-labs/core");
375
+ var import_ethers3 = require("ethers");
376
+ var import_core2 = require("@invisi-labs/core");
376
377
  var import_protocol = require("@invisi-labs/protocol");
377
378
  var EVENTS = /* @__PURE__ */ new Set([
378
379
  "CommitmentsInserted",
@@ -466,7 +467,7 @@ function extractDeliveryCandidates(logs, context, confirmedThrough) {
466
467
  check2(inserted, "delivery has no matching canonical insertion");
467
468
  if (commitment !== void 0)
468
469
  check2(hash(commitment) === inserted, "delivery commitment conflicts with insertion");
469
- const delivery = (0, import_protocol.normalizeDelivery)(wire, { credit: role !== "funds" });
470
+ const delivery = (0, import_protocol.normalizeOpaqueDelivery)(wire);
470
471
  check2(
471
472
  typeof token === "string" && (0, import_ethers3.isAddress)(token) && BigInt(token) !== 0n,
472
473
  "invalid event token"
@@ -497,7 +498,7 @@ function extractDeliveryCandidates(logs, context, confirmedThrough) {
497
498
  add(log, tree, index(leaves[0]), fields.creditCommitment, "owner", ds[0]);
498
499
  add(log, tree, index(leaves[0]), fields.creditCommitment, "spender", ds[1]);
499
500
  if (hasChange) add(log, tree, index(leaves[1]), change, "funds", ds[2]);
500
- else (0, import_protocol.normalizeDelivery)(ds[2], { empty: true });
501
+ else (0, import_protocol.normalizeOpaqueDelivery)(ds[2], { empty: true });
501
502
  };
502
503
  for (const log of relevant) {
503
504
  const a = object(log.args);
@@ -527,7 +528,7 @@ function extractDeliveryCandidates(logs, context, confirmedThrough) {
527
528
  const length = Number.parseInt(packed.slice(offset, offset + 4), 16);
528
529
  offset += 4;
529
530
  check2(
530
- length >= 160 && length <= 416 && offset + length * 2 + 136 <= packed.length,
531
+ length >= 1 && length <= import_core.MAX_CIPHERTEXT_BYTES && offset + length * 2 + 136 <= packed.length,
531
532
  "invalid packed delivery length"
532
533
  );
533
534
  const ciphertext = `0x${packed.slice(offset, offset + length * 2)}`;
@@ -549,8 +550,8 @@ function extractDeliveryCandidates(logs, context, confirmedThrough) {
549
550
  cs.forEach((c, i) => {
550
551
  if (BigInt(hash(c)) === 0n) {
551
552
  check2(integer(leaves[i]) === 0n, "absent remainder has nonzero position");
552
- (0, import_protocol.normalizeDelivery)(ds[2 * i], { empty: true });
553
- (0, import_protocol.normalizeDelivery)(ds[2 * i + 1], { empty: true });
553
+ (0, import_protocol.normalizeOpaqueDelivery)(ds[2 * i], { empty: true });
554
+ (0, import_protocol.normalizeOpaqueDelivery)(ds[2 * i + 1], { empty: true });
554
555
  } else {
555
556
  add(log, tree, index(leaves[i]), c, "owner", ds[2 * i]);
556
557
  add(log, tree, index(leaves[i]), c, "spender", ds[2 * i + 1]);
@@ -562,7 +563,7 @@ function extractDeliveryCandidates(logs, context, confirmedThrough) {
562
563
  }
563
564
  async function decryptCandidates(logs, options) {
564
565
  contextCheck(options.context);
565
- (0, import_core.decodeAddress)(import_core.ReceivingAddress.fromIdentity(options.viewing.walletIdentity).toString());
566
+ (0, import_core2.decodeAddress)(import_core2.ReceivingAddress.fromIdentity(options.viewing.walletIdentity).toString());
566
567
  check2(
567
568
  !logs.some(
568
569
  (log) => log.address.toLowerCase() === options.context.protocolAddress.toLowerCase() && log.removed
@@ -904,7 +905,7 @@ function walletBalances(state) {
904
905
  }
905
906
 
906
907
  // src/session/store.ts
907
- var import_core2 = require("@invisi-labs/core");
908
+ var import_core3 = require("@invisi-labs/core");
908
909
  var import_sha256 = require("@noble/hashes/sha256");
909
910
  var import_utils = require("@noble/hashes/utils");
910
911
  function scopeKey(scope) {
@@ -920,7 +921,7 @@ function scopeKey(scope) {
920
921
  return (0, import_utils.bytesToHex)(
921
922
  (0, import_sha256.sha256)(
922
923
  (0, import_utils.utf8ToBytes)(
923
- "Invisi.WalletScope.v2:" + JSON.stringify([
924
+ "Invisi.WalletScope.v1:" + JSON.stringify([
924
925
  scope.namespace,
925
926
  scope.chainId.toString(),
926
927
  scope.protocolAddress.toLowerCase(),
@@ -957,12 +958,12 @@ function validateState(state, scope, revision) {
957
958
  throw new Error("invalid spent state");
958
959
  }
959
960
  for (const record of Object.values(state.credits)) {
960
- const note = (0, import_core2.normalizeCreditDeliveryState)(record.state).note;
961
+ const note = (0, import_core3.normalizeCreditDeliveryState)(record.state).note;
961
962
  if (note.chainId !== scope.chainId || note.protocolAddress !== BigInt(scope.protocolAddress) || !["owner", "spender"].includes(record.role) || (record.role === "owner" ? note.ownerWalletIdentity : note.spenderWalletIdentity).toLowerCase() !== scope.walletIdentity.toLowerCase() || !["unspent", "unknown", "spent"].includes(record.spent))
962
963
  throw new Error("invalid stored Credit context or role");
963
964
  }
964
965
  for (const record of [...Object.values(state.notes), ...Object.values(state.credits)]) {
965
- if (!/^0x[0-9a-fA-F]{64}$/.test(record.commitment) || BigInt(record.commitment) <= 0n || BigInt(record.commitment) >= import_core2.FIELD_MODULUS || typeof record.treeId !== "bigint" || record.treeId < 1n || record.treeId >= 1n << 64n || !Number.isInteger(record.leafIndex) || record.leafIndex < 0 || record.leafIndex >= 65536 || typeof record.blockNumber !== "bigint" || record.blockNumber < 0n || !/^0x[0-9a-fA-F]{64}$/.test(record.blockHash))
966
+ if (!/^0x[0-9a-fA-F]{64}$/.test(record.commitment) || BigInt(record.commitment) <= 0n || BigInt(record.commitment) >= import_core3.FIELD_MODULUS || typeof record.treeId !== "bigint" || record.treeId < 1n || record.treeId >= 1n << 64n || !Number.isInteger(record.leafIndex) || record.leafIndex < 0 || record.leafIndex >= 65536 || typeof record.blockNumber !== "bigint" || record.blockNumber < 0n || !/^0x[0-9a-fA-F]{64}$/.test(record.blockHash))
966
967
  throw new Error("invalid stored receipt position");
967
968
  }
968
969
  for (const [id, operation] of Object.entries(state.reservations))
@@ -1035,13 +1036,11 @@ var MemoryAtomicRecords = class {
1035
1036
  };
1036
1037
 
1037
1038
  // src/session/operation-protocol.ts
1039
+ var import_core4 = require("@invisi-labs/core");
1038
1040
  var import_protocol2 = require("@invisi-labs/protocol");
1039
1041
  function requiresAuthorization(plan) {
1040
- if (plan.kind === "sweep") {
1041
- 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))
1042
- throw new Error("invalid owner-only sweep plan");
1043
- return false;
1044
- }
1042
+ 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);
1043
+ if (ownerOnlyFullWithdrawal) return false;
1045
1044
  return !!plan.credit || plan.inputs.length > 0;
1046
1045
  }
1047
1046
  function inputFacts(plan) {
@@ -1172,6 +1171,7 @@ async function witnessFor(protocol, plan, authorization) {
1172
1171
  }
1173
1172
  if (credit.draw) {
1174
1173
  return builder.drawCredit({
1174
+ timestamp: plan.preparedAt.timestamp,
1175
1175
  params: credit.draw,
1176
1176
  deliveries: credit.deliveries,
1177
1177
  inputs: credit.inputs,
@@ -1302,7 +1302,12 @@ function operationExpired(plan, now) {
1302
1302
  const credit = plan.credit;
1303
1303
  if (credit?.topUp && now >= credit.topUp.previousExpiry) return true;
1304
1304
  if (credit?.creation && now >= credit.creation.expiry) return true;
1305
- if (credit?.draw && credit.draw.expiries.some((expiry) => now >= expiry)) return true;
1305
+ if (credit?.draw) {
1306
+ if (credit.draw.expiries.some((expiry) => now >= expiry)) return true;
1307
+ const prepared = (0, import_core4.creditPeriods)(plan.preparedAt.timestamp), current2 = (0, import_core4.creditPeriods)(now);
1308
+ if (prepared.currentDay !== current2.currentDay || prepared.currentMonth !== current2.currentMonth)
1309
+ return true;
1310
+ }
1306
1311
  return false;
1307
1312
  }
1308
1313
 
@@ -1310,352 +1315,987 @@ function operationExpired(plan, now) {
1310
1315
  var gas_benchmarks_default = [
1311
1316
  {
1312
1317
  formatVersion: 1,
1313
- id: "protocol-92ef274-osaka-real",
1318
+ id: "protocol-42f2546-621cbef5f84a-prague-credit-real",
1314
1319
  deployment: {
1315
1320
  chainId: "31337",
1316
- protocolAddress: "0x8870C63A18a9480C7de9B860b849fD293832856D",
1317
- runtimeCodeHash: "0x604572c0da90ea139b774cd0d2962a2972fac46e0556c7cec6f6f9aac5deef14",
1318
- tokenAddress: "0x4826533B4897376654Bb4d4AD88B7faFD0C98528"
1321
+ protocolAddress: "0xEeD9be753bccbCB21463C49f0c56cC0E48bEcf3c",
1322
+ runtimeCodeHash: "0x80228a2080d224b4481fc5df24fe8ce080d4536c663b13ec7829ecf0ef46abbd",
1323
+ tokenAddress: "0x99bbA657f2BbC93c02D617f8bA121cB8Fc104Acf"
1319
1324
  },
1320
1325
  source: {
1321
- protocolCommit: "92ef274c6b36d783507699a33ee20e52192c83c7",
1322
- measuredAt: "2026-10-27T08:42:15.991Z",
1326
+ protocolCommit: "42f2546b62312e4c11e21b8e6b2ff6f72187d6a6",
1327
+ measuredAt: "2026-10-29T10:56:24.758Z",
1323
1328
  chain: "Anvil 31337",
1324
- hardfork: "osaka",
1329
+ hardfork: "prague",
1325
1330
  token: "MockERC20",
1326
1331
  verifier: "real",
1332
+ fingerprints: {
1333
+ protocolSourceSha256: "621cbef5f84a133ca96674a2dba39b21b5f9fbc022977d4d2ab296d9d6e685e0",
1334
+ dirtyDiffSha256: "eb2c41cca3802a47196181648397ec6f47fb2ba0efa8aa3800508d8d255fae3f",
1335
+ compiledArtifactsSha256: "c0e658d74fe49caeebf5ef9deadc1751d9e48add690f7e9ab478de7a00dab7e4",
1336
+ creditManifestSha256: "da819378af60471905cc902a43e464b58159e0c75bd46fb804ea9d34d8aa7ef6",
1337
+ userManifestSha256: "067b6c50e4bc4d9c19dd29f25352db88d189a5f49aed0ed603daa70760e699df",
1338
+ sdkSourceSha256: "37e1f82a447db741f46e1490b866ddf85718eab42c33d369cf5f5d2ec3a25c78"
1339
+ },
1340
+ toolchain: {
1341
+ solidity: "0.8.38",
1342
+ barretenberg: "6.0.0",
1343
+ noir: "1.0.0-rc.6",
1344
+ evmVersion: "prague",
1345
+ optimizerRuns: 200,
1346
+ anvil: "anvil Version: 1.8.6"
1347
+ },
1348
+ blockGasLimit: "500000000",
1349
+ runtimeContracts: {
1350
+ transact_user_slots14_direct_Verifier: {
1351
+ address: "0x5FbDB2315678afecb367f032d93F642f64180aa3",
1352
+ runtimeCodeHash: "0xedab185b2b9fc7d98660db2cdc99fe30b9d1341dfe568172a1626e322d208f7e"
1353
+ },
1354
+ "transact_user_slots14-adapter": {
1355
+ address: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
1356
+ runtimeCodeHash: "0xe222cd9c142bc2b13e083e6fe66ea76c0e1e9a194715bfa57082b625c55d867f"
1357
+ },
1358
+ transact_user_slots56_direct_Verifier: {
1359
+ address: "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0",
1360
+ runtimeCodeHash: "0x8913eb7060f38234aca199c4a1007892f68e703de48b588c436b24faaeb23a53"
1361
+ },
1362
+ "transact_user_slots56-adapter": {
1363
+ address: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
1364
+ runtimeCodeHash: "0x97c416d190da0b9b8111a5ee17367e8a702ba7884019bf724155ae629a783477"
1365
+ },
1366
+ transact_user_slots112_direct_Verifier: {
1367
+ address: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9",
1368
+ runtimeCodeHash: "0x501a4791ff0c0a96465ab5e0d42d0ce763bbbb7fd8aebe21929de4d460e1b42c"
1369
+ },
1370
+ "transact_user_slots112-adapter": {
1371
+ address: "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707",
1372
+ runtimeCodeHash: "0xf22ed8ea34a4011650a41c1b9f664b5259ea5a8d66a82d706dab9611a38c109f"
1373
+ },
1374
+ transact_user_slots168_direct_Verifier: {
1375
+ address: "0x0165878A594ca255338adfa4d48449f69242Eb8F",
1376
+ runtimeCodeHash: "0xc22acdfa6f3e278ae46d194a1c50b905e4815fd7b61e39edb52334570670fdce"
1377
+ },
1378
+ "transact_user_slots168-adapter": {
1379
+ address: "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853",
1380
+ runtimeCodeHash: "0x05a318f54d93440a501b6fc6be88e4e76e89d72f1be8333553cb4a61f4f9a0d7"
1381
+ },
1382
+ transact_aggregate_14_4_Verifier: {
1383
+ address: "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6",
1384
+ runtimeCodeHash: "0x7a6f2bafe4c61a72a99a195e188f2f4a32900c0cc63cc132e33881d8199fd446"
1385
+ },
1386
+ "transact_aggregate_14_4-adapter": {
1387
+ address: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318",
1388
+ runtimeCodeHash: "0x15877da9940d5b8dd4868ffa92ded3b93d6092c3963ba9e18b50f1ea15d89898"
1389
+ },
1390
+ transact_aggregate_14_8_Verifier: {
1391
+ address: "0x610178dA211FEF7D417bC0e6FeD39F05609AD788",
1392
+ runtimeCodeHash: "0x5667d16b39973813a499375f6885a3082d7bfcd6e3c0f3548d7de3131cd285f3"
1393
+ },
1394
+ "transact_aggregate_14_8-adapter": {
1395
+ address: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e",
1396
+ runtimeCodeHash: "0x9d1a93c78edf7e81b4b6da10ab209b3fb009ed8355594f670559a67842d88cfc"
1397
+ },
1398
+ transact_aggregate_14_12_Verifier: {
1399
+ address: "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0",
1400
+ runtimeCodeHash: "0xa4e67840a47182d4011d577981c2477bb4ab2bc36845bb136375f19f12c0800b"
1401
+ },
1402
+ "transact_aggregate_14_12-adapter": {
1403
+ address: "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82",
1404
+ runtimeCodeHash: "0x96a6e170aafc0af9d46232ba00206d950bba85e65962d43501bafb6d7f9fe61d"
1405
+ },
1406
+ create_credit_direct_Verifier: {
1407
+ address: "0x9A676e781A523b5d0C0e43731313A708CB607508",
1408
+ runtimeCodeHash: "0xbdc6450bf9ba01001082f345b8bd21006a4f75274f32d026cf6e14270e6d56e6"
1409
+ },
1410
+ "create_credit-adapter": {
1411
+ address: "0x0B306BF915C4d645ff596e518fAf3F9669b97016",
1412
+ runtimeCodeHash: "0x3a95a22b32aef18ce053a7110056bbfbf13bb0b07932a49765ebb136528a4707"
1413
+ },
1414
+ credit_draw_slots1_direct_Verifier: {
1415
+ address: "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1",
1416
+ runtimeCodeHash: "0x47be80e72c3a22ea044638f6004de8c3a0264d5a0d17189c01153cdabfd7bab6"
1417
+ },
1418
+ "credit_draw_slots1-adapter": {
1419
+ address: "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE",
1420
+ runtimeCodeHash: "0x28f25aeb97659fb9253ae67f2ff284789710bc59e1ed077ffc7a07b800cbfcc1"
1421
+ },
1422
+ credit_draw_slots12_direct_Verifier: {
1423
+ address: "0x68B1D87F95878fE05B998F19b66F4baba5De1aed",
1424
+ runtimeCodeHash: "0x244d9ba22f5c736c2a5c42c466701e2a8ba7ae8108665133541026ea45d56e04"
1425
+ },
1426
+ "credit_draw_slots12-adapter": {
1427
+ address: "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c",
1428
+ runtimeCodeHash: "0x60d48a35279d318a0621e5f59b293f44074463b8002ce180b7e6a31b995ac195"
1429
+ },
1430
+ credit_draw_slots50_direct_Verifier: {
1431
+ address: "0xc6e7DF5E7b4f2A278906862b61205850344D4e7d",
1432
+ runtimeCodeHash: "0x2ad5eb64bcfae34ef04111dd8f9c1ffc5fc8aa6c1ad3a65d8da78233f3390660"
1433
+ },
1434
+ "credit_draw_slots50-adapter": {
1435
+ address: "0x59b670e9fA9D0A427751Af201D676719a970857b",
1436
+ runtimeCodeHash: "0x468966de20e5c71cf7b6f3cda7fa7a76b5d80dc5ddf82119f441ea6a7c6c1e70"
1437
+ },
1438
+ credit_draw_slots120_direct_Verifier: {
1439
+ address: "0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1",
1440
+ runtimeCodeHash: "0x523b6d211618bbd33d708f8198b9f3daafc10e2fa7a6a857db5795ed748a24e4"
1441
+ },
1442
+ "credit_draw_slots120-adapter": {
1443
+ address: "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44",
1444
+ runtimeCodeHash: "0xa91d585ce6037e703efb914205bf193881fde4f470d2fc63b615699b56175239"
1445
+ },
1446
+ credit_cancel_direct_Verifier: {
1447
+ address: "0xa85233C63b9Ee964Add6F2cffe00Fd84eb32338f",
1448
+ runtimeCodeHash: "0x182e86861a73f712071e40a6b8497b80c58c383eaa799182e7a50e39196399fd"
1449
+ },
1450
+ "credit_cancel-adapter": {
1451
+ address: "0x4A679253410272dd5232B3Ff7cF5dbB88f295319",
1452
+ runtimeCodeHash: "0xea1f0f22445eed5a92c8d6990219059b7e241ad66c55a6d9ddef22a94a0f015f"
1453
+ },
1454
+ credit_top_up_direct_Verifier: {
1455
+ address: "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F",
1456
+ runtimeCodeHash: "0xeeb42a2b6377ab305b713d1caf4ca96edb302c6d1e1007239e5c70091819c266"
1457
+ },
1458
+ "credit_top_up-adapter": {
1459
+ address: "0x09635F643e140090A9A8Dcd712eD6285858ceBef",
1460
+ runtimeCodeHash: "0xbcf35a1d0e6c16dd01b09f944889aa5917d358d986fe399a0343d06bbdedaa61"
1461
+ },
1462
+ PrivateTransferVerifierRegistry: {
1463
+ address: "0xc5a5C42992dECbae36851359345FE25997F5C42d",
1464
+ runtimeCodeHash: "0x678684af147cb42c872184b6e22c8439748139ae0c5885032941ab8832fcb142"
1465
+ },
1466
+ CrossTreeVerifierRegistry: {
1467
+ address: "0x67d269191c92Caf3cD7723F116c85e6E9bf55933",
1468
+ runtimeCodeHash: "0xa5ee16fc7ed9f982450e42a48365a93bfca784fa884adcb8695b557e921cb93b"
1469
+ },
1470
+ DualVerifierRouter: {
1471
+ address: "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E",
1472
+ runtimeCodeHash: "0xcc094ed6f1bcc9270c597f62b817e4fc0a54770f373320133c2836e5b07ef2cc"
1473
+ },
1474
+ AtomicBatchOutputLib: {
1475
+ address: "0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690",
1476
+ runtimeCodeHash: "0x7c138c13e40b3ad0fee3b319d6c1580a21855cb5ecdda92571d530509d9b7316"
1477
+ },
1478
+ FundingLib: {
1479
+ address: "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB",
1480
+ runtimeCodeHash: "0x898d13d6ec4123df85f21ee0f98678dcd9f9b9a60134f88e35c1ef1aaa0a45f9"
1481
+ },
1482
+ PrivateTransferLib: {
1483
+ address: "0x9E545E3C0baAB3E08CdfD552C960A1050f373042",
1484
+ runtimeCodeHash: "0xfb18f2dd0a39af1b99ae35c25e2746cb5bc85c205e041db5f440671d84c82e5e"
1485
+ },
1486
+ CrossTreeTransferLib: {
1487
+ address: "0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9",
1488
+ runtimeCodeHash: "0x7b33a08f2feb9da462b951c95482cb2909796a85c0fde7cc9a6b65ff8b7ff253"
1489
+ },
1490
+ AggregateTransferLib: {
1491
+ address: "0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8",
1492
+ runtimeCodeHash: "0xb3b4bd3a428f5c35712a57180f07b2249774d399ca87d4494929148ea26c5b99"
1493
+ },
1494
+ CreateCreditLib: {
1495
+ address: "0x851356ae760d987E095750cCeb3bC6014560891C",
1496
+ runtimeCodeHash: "0xe37a4b7c129c4fba5615d25ed8b7e898e64a306c68f7e599ade911db98fe881c"
1497
+ },
1498
+ CreditLifecycleLib: {
1499
+ address: "0xf5059a5D33d5853360D16C683c16e67980206f36",
1500
+ runtimeCodeHash: "0xf87a2227680efa7070071516587793e2e847c172b83261b8983c826f8a8c79bb"
1501
+ },
1502
+ ShieldLib: {
1503
+ address: "0x95401dc811bb5740090279Ba06cfA8fcF6113778",
1504
+ runtimeCodeHash: "0x371e57d8d324e44445a4ec30303b89a8bc98bbdbd03aeaa80faf0f821a65451d"
1505
+ },
1506
+ InvisiFactory: {
1507
+ address: "0x998abeb3E57409262aE5b751f60747921B33613E",
1508
+ runtimeCodeHash: "0xc56e5a0b71f4a1f63576a6663efb62b17c0d7520b6885a8d3483a356e12edf9b"
1509
+ },
1510
+ InvisiAddressRegistry: {
1511
+ address: "0x70e0bA845a1A0F2DA3359C97E0285013525FFC49",
1512
+ runtimeCodeHash: "0x007da3f4e888366ba0eed52cd511c4a369359291387ad19ca37e89eb395fce30"
1513
+ },
1514
+ InvisiProtocol: {
1515
+ address: "0xEeD9be753bccbCB21463C49f0c56cC0E48bEcf3c",
1516
+ runtimeCodeHash: "0x80228a2080d224b4481fc5df24fe8ce080d4536c663b13ec7829ecf0ef46abbd"
1517
+ },
1518
+ MockERC20: {
1519
+ address: "0x99bbA657f2BbC93c02D617f8bA121cB8Fc104Acf",
1520
+ runtimeCodeHash: "0xf7f676b5c54f6e94f82f0de65a0117468a0d915e8a79d150e74f76bd6d7f708b"
1521
+ }
1522
+ },
1327
1523
  assumptions: [
1328
- "normal CREATE/Factory deployment; no code or storage injection",
1329
- "Solidity 0.8.27 optimizer 200; real BB 5.2.1 verifiers",
1330
- "one source tree; two existing leaves; no rollover or screener",
1331
- "funding/approval setup excluded; complete transaction receipt gas included",
1332
- "exact allowance for caller funding; configured benchmark payout balances",
1333
- "observed local samples, not a confidence interval or gas limit"
1524
+ "normal CREATE/Factory deployment and fresh registry; EIP170/EIP3860 unchanged; no code/storage injection",
1525
+ "Solidity0.8.38 optimizer200 Prague; pinned BB6.0.0 real verifiers; every native proof independently verified",
1526
+ "one physical source tree and 123 existing leaves shared by every sample; top-up has two authenticated source groups; no rollover or screener",
1527
+ "funding/approvals/121 genuine Credit seeds/usage-seed draw/payout reset excluded from business gas",
1528
+ "each round restores identical token balances, exact caller allowance100, note cursor, nullifiers and baseline; spender payout starts zero",
1529
+ "complete receipt.gasUsed is measured, including verifier/calldata/logging/output insertion; memo0",
1530
+ "Prague local block gas limit500000000; measured transactions may be unmineable under lower network transaction/block limits",
1531
+ "observed three-sample ranges are neither a confidence interval nor a recommended transaction gas limit"
1334
1532
  ]
1335
1533
  },
1336
1534
  measurements: [
1337
1535
  {
1338
- id: "shield-1",
1536
+ id: "create-credit-caller-0x0",
1339
1537
  shape: {
1340
- kind: "shield",
1538
+ kind: "create-credit",
1341
1539
  target: "evm",
1342
- capacity: 0,
1540
+ capacity: 10,
1343
1541
  noteInputs: 0,
1344
- noteOutputs: 1,
1542
+ noteOutputs: 0,
1345
1543
  sourceTrees: 0,
1346
1544
  creditInputs: 0,
1347
- creditOutputs: 0,
1545
+ creditOutputs: 1,
1348
1546
  creditRemainders: 0,
1349
1547
  funding: "caller",
1350
1548
  permit: false,
1351
- deliveryBytes: 226
1549
+ deliveryBytes: 1132
1550
+ },
1551
+ circuit: {
1552
+ circuitName: "create_credit",
1553
+ target: "evm",
1554
+ artifactSha256: "3ed6cfdee4f5fd840f023580f76c208768777fea79737f2511377e5c55be0230",
1555
+ vkSha256: "56f663c6053be0d158a271022d200c732597efd3a2e0be48fe94549d0b1795e0"
1352
1556
  },
1353
- circuit: null,
1354
1557
  samples: [
1355
1558
  {
1356
- gasUsed: "649286",
1357
- transactionHash: "0xcc299d1780ada9a69b1d9f0f3d06a165db15fccbd2b7ff407834f02f5d563a18",
1358
- blockNumber: "50",
1359
- blockHash: "0xbcb868e781a20588d2fa099a4d7f87c1600044a2e5ec1e369e384d7a5f22f00a",
1360
- calldataBytes: 1156
1559
+ gasUsed: "1574696",
1560
+ transactionHash: "0x76112c532a1b5f24ad84fb83f91789ba4acd15ed9473ec9a0267cd5fe605448d",
1561
+ blockNumber: "172",
1562
+ blockHash: "0x0d91421e94947132a19f38ffdd76932c2d85add201de3d9189325ed3568125a7",
1563
+ calldataBytes: 11780
1361
1564
  },
1362
1565
  {
1363
- gasUsed: "649322",
1364
- transactionHash: "0x95139dff109725989f0769e3e6fb9bd3e7e1bf581fd475f14e822875eb90fda4",
1365
- blockNumber: "50",
1366
- blockHash: "0x7ace353fea4fc8c856c0fd45521d200b02619921977709ff4f910e0ff41c06fe",
1367
- calldataBytes: 1156
1566
+ gasUsed: "1574576",
1567
+ transactionHash: "0x545f72d9d207329bfc69ef0d1e96470c614924d5e463d974cc001712bf619fd8",
1568
+ blockNumber: "172",
1569
+ blockHash: "0x2053f97a2b2f3cf66e14da0ab9c1d7bd462d2d4f3ef2b13021aefcddedb71cf8",
1570
+ calldataBytes: 11780
1368
1571
  },
1369
1572
  {
1370
- gasUsed: "649322",
1371
- transactionHash: "0xef578bb38dc8ff8bfd47d2e76e3ab4273019ea9a385f5d2fd99add32ceaecb58",
1372
- blockNumber: "50",
1373
- blockHash: "0xded817f8ef89637e2443e3b626c0837f184ca134fe753be913d5570554c649a6",
1374
- calldataBytes: 1156
1573
+ gasUsed: "1574612",
1574
+ transactionHash: "0x880ec0c666068d0756fba39947dc5b211aeebb31f41bd1e1e54856b090f65d34",
1575
+ blockNumber: "172",
1576
+ blockHash: "0xbb86ed21379a917e9688a3c90364ae8fbe1ba633ac068360e0a82bf4d3113b6d",
1577
+ calldataBytes: 11780
1375
1578
  }
1376
1579
  ]
1377
1580
  },
1378
1581
  {
1379
- id: "shield-2",
1582
+ id: "create-credit-1x1",
1380
1583
  shape: {
1381
- kind: "shield",
1584
+ kind: "create-credit",
1382
1585
  target: "evm",
1383
- capacity: 0,
1384
- noteInputs: 0,
1385
- noteOutputs: 2,
1386
- sourceTrees: 0,
1586
+ capacity: 10,
1587
+ noteInputs: 1,
1588
+ noteOutputs: 1,
1589
+ sourceTrees: 1,
1387
1590
  creditInputs: 0,
1388
- creditOutputs: 0,
1591
+ creditOutputs: 1,
1389
1592
  creditRemainders: 0,
1390
- funding: "caller",
1593
+ funding: "none",
1391
1594
  permit: false,
1392
- deliveryBytes: 452
1595
+ deliveryBytes: 1360
1596
+ },
1597
+ circuit: {
1598
+ circuitName: "create_credit",
1599
+ target: "evm",
1600
+ artifactSha256: "3ed6cfdee4f5fd840f023580f76c208768777fea79737f2511377e5c55be0230",
1601
+ vkSha256: "56f663c6053be0d158a271022d200c732597efd3a2e0be48fe94549d0b1795e0"
1393
1602
  },
1394
- circuit: null,
1395
1603
  samples: [
1396
1604
  {
1397
- gasUsed: "757063",
1398
- transactionHash: "0x024e2dfbd6f50c368e2a4aa347e3029de668f4ebd36b80227aa003bb7ac21c74",
1399
- blockNumber: "50",
1400
- blockHash: "0x8ed63973c158d706ac54bb646626e4f0db5777b4bd56d179b94503af6c417c50",
1401
- calldataBytes: 1668
1605
+ gasUsed: "1671641",
1606
+ transactionHash: "0x24ca3f03681aeb188b48989d5eaf7dd264a8c32e828acd34ff1b44be74f17ea6",
1607
+ blockNumber: "172",
1608
+ blockHash: "0xcdac07aa5d3ec187874dc1fc9be65503235289c7036ebe455feaf5161db42bb5",
1609
+ calldataBytes: 12132
1402
1610
  },
1403
1611
  {
1404
- gasUsed: "757063",
1405
- transactionHash: "0x898d852ab28f68adac4d30b160a3dbfee33fa7ca875f70df9eb7763b6b1cd1f0",
1406
- blockNumber: "50",
1407
- blockHash: "0x9bb6810de38193933a9f26fa03d3d9bad1ca0151ff5e04544c56520e09da3043",
1408
- calldataBytes: 1668
1612
+ gasUsed: "1671509",
1613
+ transactionHash: "0x31a7f69ab02effa5fdd2e02bd02fb7e715a54786813261113fd7c07a0d3ef549",
1614
+ blockNumber: "172",
1615
+ blockHash: "0xc78ca874aa22cc6b8ea19e12a2806ba448a0f844345450d3fedc9841ea71c3a8",
1616
+ calldataBytes: 12132
1409
1617
  },
1410
1618
  {
1411
- gasUsed: "757039",
1412
- transactionHash: "0x8ff9720e3197aab2d741fbd8d0fa2969203ea8cd051d9649d1e5eb890bcc2be3",
1413
- blockNumber: "50",
1414
- blockHash: "0x8604c75eb6363aaae774276e638f5b749aae1f8f815eb99ab1183137eef5730e",
1415
- calldataBytes: 1668
1619
+ gasUsed: "1671485",
1620
+ transactionHash: "0xc5a30116885dcac8b3631c15847544cfeb91c46bde44c3765ac0ce42e3259157",
1621
+ blockNumber: "172",
1622
+ blockHash: "0x4a2c90ff972da4d37408567062779762efbb5790d4784d03842ee2c926c8c894",
1623
+ calldataBytes: 12132
1416
1624
  }
1417
1625
  ]
1418
1626
  },
1419
1627
  {
1420
- id: "shield-10",
1628
+ id: "draw-credit-1-partial",
1421
1629
  shape: {
1422
- kind: "shield",
1630
+ kind: "draw-credit",
1423
1631
  target: "evm",
1424
- capacity: 0,
1632
+ capacity: 1,
1425
1633
  noteInputs: 0,
1426
- noteOutputs: 10,
1427
- sourceTrees: 0,
1428
- creditInputs: 0,
1429
- creditOutputs: 0,
1430
- creditRemainders: 0,
1431
- funding: "caller",
1634
+ noteOutputs: 0,
1635
+ sourceTrees: 1,
1636
+ creditInputs: 1,
1637
+ creditOutputs: 1,
1638
+ creditRemainders: 1,
1639
+ funding: "none",
1432
1640
  permit: false,
1433
- deliveryBytes: 2260
1641
+ deliveryBytes: 1132
1642
+ },
1643
+ circuit: {
1644
+ circuitName: "credit_draw_slots1",
1645
+ target: "evm",
1646
+ artifactSha256: "4542b227e0552b45c302f1dace21cadeba4962c96244e021472f1f7531cff8d1",
1647
+ vkSha256: "43c051a2bedf9454c12e70b10156361e414944823ba23e80662c16c7ced0a2ce"
1434
1648
  },
1435
- circuit: null,
1436
1649
  samples: [
1437
1650
  {
1438
- gasUsed: "1692143",
1439
- transactionHash: "0x6c13db8bd8a8599daf5034e56712abefbf406982fafe7647b6d22291ba4199ed",
1440
- blockNumber: "50",
1441
- blockHash: "0x1ab2ae514f408a79e0c40ca10cee74b2e23d7c8a5f24641b8eea3e1cf58ce700",
1442
- calldataBytes: 5764
1651
+ gasUsed: "1588303",
1652
+ transactionHash: "0x85c5180692470aa952aa13eb29ca0404d4f5b5192cb31475f90d03d78864895e",
1653
+ blockNumber: "172",
1654
+ blockHash: "0xfe4876c0a2ebf05385a46562bca693b6df80da731fd9651117593916015dc38c",
1655
+ calldataBytes: 11588
1443
1656
  },
1444
1657
  {
1445
- gasUsed: "1692083",
1446
- transactionHash: "0x5e476c9d3838b782a51332af9bf5c372d29fc411c2168a7af619c52bd5309c7b",
1447
- blockNumber: "50",
1448
- blockHash: "0x9c62bc72fc90f990c6711b48865ff922a1856ae05c4fef61dad5f4da7d948401",
1449
- calldataBytes: 5764
1658
+ gasUsed: "1588303",
1659
+ transactionHash: "0x61684313840623187ca1205b4b07b43a08038448524ee1a028c7e14050032682",
1660
+ blockNumber: "172",
1661
+ blockHash: "0x9726d31c10e6516e38e3f63c84fc4b9a8a161486d35e0d8d07e6829261a88fe7",
1662
+ calldataBytes: 11588
1450
1663
  },
1451
1664
  {
1452
- gasUsed: "1692203",
1453
- transactionHash: "0x0092e2d9160fad95279cde586fc6c79c713244f55db8a2060a5abab9d98c176a",
1454
- blockNumber: "50",
1455
- blockHash: "0xac1bf780b4cc05b4dcc7ee5d741c049ba99ab4af9bdcd25104add730c2a14152",
1456
- calldataBytes: 5764
1665
+ gasUsed: "1588255",
1666
+ transactionHash: "0x0aa052fb8e356cc81dd73bcdae72f760937cd2e56bd4a3e8eb5878208b4f7596",
1667
+ blockNumber: "172",
1668
+ blockHash: "0x2c958cfba0627e18cd5cb47001b278628c305071929596e3335d770b92c1dc16",
1669
+ calldataBytes: 11588
1457
1670
  }
1458
1671
  ]
1459
1672
  },
1460
1673
  {
1461
- id: "transfer-1x2",
1674
+ id: "draw-credit-1-full",
1462
1675
  shape: {
1463
- kind: "transfer",
1676
+ kind: "draw-credit",
1464
1677
  target: "evm",
1465
- capacity: 14,
1466
- noteInputs: 1,
1467
- noteOutputs: 2,
1678
+ capacity: 1,
1679
+ noteInputs: 0,
1680
+ noteOutputs: 0,
1468
1681
  sourceTrees: 1,
1469
- creditInputs: 0,
1682
+ creditInputs: 1,
1470
1683
  creditOutputs: 0,
1471
1684
  creditRemainders: 0,
1472
1685
  funding: "none",
1473
1686
  permit: false,
1474
- deliveryBytes: 452
1687
+ deliveryBytes: 0
1475
1688
  },
1476
1689
  circuit: {
1477
- circuitName: "transact_user_slots14",
1690
+ circuitName: "credit_draw_slots1",
1478
1691
  target: "evm",
1479
- artifactSha256: "2a6a20839e90b88b1ecd629f59a01821bad3ee11dbe04db1fd9cdce7a3de0e84",
1480
- vkSha256: "ffe0e1a4e690792ecb4eb1fc1acc9ff60f13d3b5af03cfc6ae6d6bf26e99bdea"
1692
+ artifactSha256: "4542b227e0552b45c302f1dace21cadeba4962c96244e021472f1f7531cff8d1",
1693
+ vkSha256: "43c051a2bedf9454c12e70b10156361e414944823ba23e80662c16c7ced0a2ce"
1481
1694
  },
1482
1695
  samples: [
1483
1696
  {
1484
- gasUsed: "1617516",
1485
- transactionHash: "0xf49ea3d31cc1346472172e2dee84f9360f60a3fe948a3ef6e87f727af6d42f0d",
1486
- blockNumber: "49",
1487
- blockHash: "0xf59c57e63ec2f03abc36d28f273b0af5290184dc97197df740b23d79a851a887",
1488
- calldataBytes: 11012
1697
+ gasUsed: "1042812",
1698
+ transactionHash: "0xb5d55729d975abdc92ca44c0b72e44a0d5841da8b23dc11b5bd31f46d88a341a",
1699
+ blockNumber: "172",
1700
+ blockHash: "0x8a6ddbe2f1630e1956485cac7984fb9cdc4fbb26b10522e158b38e2970ee4f3b",
1701
+ calldataBytes: 10372
1489
1702
  },
1490
1703
  {
1491
- gasUsed: "1617516",
1492
- transactionHash: "0xf8d11286f1f2a4db006ff6b06900c47d0fbf685984499e1e5d4aea49478ba8e5",
1493
- blockNumber: "49",
1494
- blockHash: "0xeb5a800190be3534c9e2675c97ac56d0e0be8adef55f60bd32d375776a7d150c",
1495
- calldataBytes: 11012
1704
+ gasUsed: "1042824",
1705
+ transactionHash: "0xf64f3186fbf94fcbd9fb12426c714b4a8425599e1a7e5677866fae3d6873b7ae",
1706
+ blockNumber: "172",
1707
+ blockHash: "0xd630c44d8ce96234ec836dd2178caac2a6d0bc2df5cf37df1534eb8896be48d3",
1708
+ calldataBytes: 10372
1496
1709
  },
1497
1710
  {
1498
- gasUsed: "1617504",
1499
- transactionHash: "0x8939fcea97079a3c5118b9e94325455e2ad1cdb47310ae499a277272654b3eb6",
1500
- blockNumber: "49",
1501
- blockHash: "0xecffefb593e2fec5d5827cfd39d0cc4d0efb67dbff6f8dbbd0d2db2439a80cf9",
1502
- calldataBytes: 11012
1711
+ gasUsed: "1042884",
1712
+ transactionHash: "0xdf634e809b87603a62292ef046fa5e84715561fa76ef121c768303dd779568f1",
1713
+ blockNumber: "172",
1714
+ blockHash: "0x09cad4a799360bdf825c3ad70fe374b7fe2df802f8ee37ccb7f26ffc49aa2a3a",
1715
+ calldataBytes: 10372
1503
1716
  }
1504
1717
  ]
1505
1718
  },
1506
1719
  {
1507
- id: "transfer-1x14",
1720
+ id: "draw-credit-12-partial",
1508
1721
  shape: {
1509
- kind: "transfer",
1722
+ kind: "draw-credit",
1510
1723
  target: "evm",
1511
- capacity: 56,
1512
- noteInputs: 1,
1513
- noteOutputs: 14,
1724
+ capacity: 12,
1725
+ noteInputs: 0,
1726
+ noteOutputs: 0,
1514
1727
  sourceTrees: 1,
1515
- creditInputs: 0,
1516
- creditOutputs: 0,
1517
- creditRemainders: 0,
1728
+ creditInputs: 12,
1729
+ creditOutputs: 12,
1730
+ creditRemainders: 12,
1518
1731
  funding: "none",
1519
1732
  permit: false,
1520
- deliveryBytes: 3164
1733
+ deliveryBytes: 13584
1521
1734
  },
1522
1735
  circuit: {
1523
- circuitName: "transact_user_slots56",
1736
+ circuitName: "credit_draw_slots12",
1524
1737
  target: "evm",
1525
- artifactSha256: "ba83ec2f177d16fa88ea04bc54f2e99920f1ac195cdb05b88b9b3bbc245fd953",
1526
- vkSha256: "6ad5d3aff0c72a632fb19895658af093a6a92478a9994985e838a71e61237720"
1738
+ artifactSha256: "dd72b0867fc3be7cd90de263bd2d0892075cb18eb4f6dd671b13111710f10369",
1739
+ vkSha256: "5e31d771e6294993736078596d9c69f21fe7595eda50e3cce6d7406b65cf1443"
1527
1740
  },
1528
1741
  samples: [
1529
1742
  {
1530
- gasUsed: "2489010",
1531
- transactionHash: "0x053557acea930a869d6469c91e9bc015d0893607a6ab18d2af684986f7074676",
1532
- blockNumber: "49",
1533
- blockHash: "0x734873097eb5e4cb66bfc2cdb61fac6753b53a4b9450fb22895281100af3aaf3",
1534
- calldataBytes: 17156
1743
+ gasUsed: "3102895",
1744
+ transactionHash: "0x699ba81f296f4af397a8dfaf96adf14d00d0f7dd69c0b09608641fc9b99fc28f",
1745
+ blockNumber: "172",
1746
+ blockHash: "0x8d318f563f5563fa5c213617481089f75aab3a6e9d14818db107ac20a8c20ffb",
1747
+ calldataBytes: 30276
1535
1748
  },
1536
1749
  {
1537
- gasUsed: "2489106",
1538
- transactionHash: "0xb3990edb994011775e275bc1eb38c527b7206a2bfadf510e8aa53e260f3594b8",
1539
- blockNumber: "49",
1540
- blockHash: "0xf8cb019ebb0ecd0ec5d6634198292883c63fe93a7c65c34f9f3120c6cc54f1cf",
1541
- calldataBytes: 17156
1750
+ gasUsed: "3102871",
1751
+ transactionHash: "0xddfc1c6c505f6c54f4d9aabc96a02eb6b606182e8ad708a578eacd274d885dee",
1752
+ blockNumber: "172",
1753
+ blockHash: "0xcc7738fe329a608241615dc43b7d16e075eb62be202ea8aaf4ae27a5278bf438",
1754
+ calldataBytes: 30276
1542
1755
  },
1543
1756
  {
1544
- gasUsed: "2489094",
1545
- transactionHash: "0xc97079019567ff8a79d285421351ee4bc48d14092a0e12ff634151719e991088",
1546
- blockNumber: "49",
1547
- blockHash: "0x5a6947839165c8961eeeb9190331415c40366a78b4a6a5771e7b8954dbb8b3c7",
1548
- calldataBytes: 17156
1757
+ gasUsed: "3103171",
1758
+ transactionHash: "0x6efab6408d927e1877f1f6c33ecd285a128382f7d1dfe6e123927b035781c8aa",
1759
+ blockNumber: "172",
1760
+ blockHash: "0xcb4588df9ecdca0d353ccbd226e1d5d07f21e6dc93875e41cdd5f64568859f4d",
1761
+ calldataBytes: 30276
1549
1762
  }
1550
1763
  ]
1551
1764
  },
1552
1765
  {
1553
- id: "transfer-1x56",
1766
+ id: "draw-credit-12-full",
1554
1767
  shape: {
1555
- kind: "transfer",
1768
+ kind: "draw-credit",
1556
1769
  target: "evm",
1557
- capacity: 112,
1558
- noteInputs: 1,
1559
- noteOutputs: 56,
1770
+ capacity: 12,
1771
+ noteInputs: 0,
1772
+ noteOutputs: 0,
1560
1773
  sourceTrees: 1,
1561
- creditInputs: 0,
1774
+ creditInputs: 12,
1562
1775
  creditOutputs: 0,
1563
1776
  creditRemainders: 0,
1564
1777
  funding: "none",
1565
1778
  permit: false,
1566
- deliveryBytes: 12656
1779
+ deliveryBytes: 0
1567
1780
  },
1568
1781
  circuit: {
1569
- circuitName: "transact_user_slots112",
1782
+ circuitName: "credit_draw_slots12",
1570
1783
  target: "evm",
1571
- artifactSha256: "713b78469b6e97711122210f8497942120c1c9d66d3604bc184566c4eba59cc3",
1572
- vkSha256: "d6a46e297949c28b9a62fd9aef1f202870fdca97b8bfb15beefd27b9e9f3d86e"
1784
+ artifactSha256: "dd72b0867fc3be7cd90de263bd2d0892075cb18eb4f6dd671b13111710f10369",
1785
+ vkSha256: "5e31d771e6294993736078596d9c69f21fe7595eda50e3cce6d7406b65cf1443"
1573
1786
  },
1574
1787
  samples: [
1575
1788
  {
1576
- gasUsed: "5389227",
1577
- transactionHash: "0xb820d3c358724c1d64422017f232d074e4ff1ffaf1b1ce5ee719409427cf2208",
1578
- blockNumber: "49",
1579
- blockHash: "0x474bd1e52457801d1a596a9f23aeb6d365a17be028ee0c8cf8fd4758eaa1106b",
1580
- calldataBytes: 36356
1789
+ gasUsed: "1536675",
1790
+ transactionHash: "0xc0d3eef8e6b0e90984d776a5e41bcdce1e0ca0bc6dc3a71616e4768e80c01546",
1791
+ blockNumber: "172",
1792
+ blockHash: "0x22dfac3d8e9913a6a1f2ff84faaece4ed59bfe1cb74e06a60131ff28cc6c2f9d",
1793
+ calldataBytes: 15684
1581
1794
  },
1582
1795
  {
1583
- gasUsed: "5389095",
1584
- transactionHash: "0x16514d8cf1136d7a7f40591859e2ea2d256af66520498e1fc81eb28837db600d",
1585
- blockNumber: "49",
1586
- blockHash: "0x42314a0d6eb9e765869e1b66b279444c78f919d2c28aed544d9fa7ac3bd2acb4",
1587
- calldataBytes: 36356
1796
+ gasUsed: "1536675",
1797
+ transactionHash: "0x9879d86a1eaa550a6a6afaeeb0f5f07745d5dcd9caa07b660d7fb512911dc67e",
1798
+ blockNumber: "172",
1799
+ blockHash: "0xf88ba9f1b7a0c627338a61bbabe1c650bdfcd7fa1c56433d6853f492135b753d",
1800
+ calldataBytes: 15684
1801
+ },
1802
+ {
1803
+ gasUsed: "1536711",
1804
+ transactionHash: "0xbd8f75a021a8ce8dc1900bd2d84d723acc6a64018844050a5aa2f8712cf7fd6b",
1805
+ blockNumber: "172",
1806
+ blockHash: "0xa55b539c2ea4e10ce9a9ee8e6de9cf1daa97263b51f32cfef8342c100b663b0f",
1807
+ calldataBytes: 15684
1808
+ }
1809
+ ]
1810
+ },
1811
+ {
1812
+ id: "draw-credit-50-partial",
1813
+ shape: {
1814
+ kind: "draw-credit",
1815
+ target: "evm",
1816
+ capacity: 50,
1817
+ noteInputs: 0,
1818
+ noteOutputs: 0,
1819
+ sourceTrees: 1,
1820
+ creditInputs: 50,
1821
+ creditOutputs: 50,
1822
+ creditRemainders: 50,
1823
+ funding: "none",
1824
+ permit: false,
1825
+ deliveryBytes: 56600
1826
+ },
1827
+ circuit: {
1828
+ circuitName: "credit_draw_slots50",
1829
+ target: "evm",
1830
+ artifactSha256: "09c7469866748b4c0c4bbf2b040844771948a170999f6dc7a38fe5c0ecda4054",
1831
+ vkSha256: "7b613225b6f32a077011d4196c356e836d22dcd116efe687fde53144fbd8db9f"
1832
+ },
1833
+ samples: [
1834
+ {
1835
+ gasUsed: "8015473",
1836
+ transactionHash: "0x5dcc0fa08abaf5212424ac6f3e2f3bb8a0bd333f90ef6e421f8d3fe370ca1acf",
1837
+ blockNumber: "172",
1838
+ blockHash: "0x3197c523dece3492226c5021f974e7c02db2e686265943d03a5550c6cb96a12e",
1839
+ calldataBytes: 94276
1840
+ },
1841
+ {
1842
+ gasUsed: "8015449",
1843
+ transactionHash: "0x6a55f88551a45b3e118cde0607cfff1ef0b6ab15ad9472e838412d9ce714b42a",
1844
+ blockNumber: "172",
1845
+ blockHash: "0xea82c8962d45db8361bd67ed326806f21c511bd51550adc453d0c3e5cab3a7ae",
1846
+ calldataBytes: 94276
1847
+ },
1848
+ {
1849
+ gasUsed: "8015149",
1850
+ transactionHash: "0x2cc8d474a92abe91f8025109a70cf1f9f081dbec43aa4a475ab9f33222cfc76b",
1851
+ blockNumber: "172",
1852
+ blockHash: "0x4398f419da699ccca33867852d4975b5c461a40bb01cd5241a0e6dcacaeb78b3",
1853
+ calldataBytes: 94276
1854
+ }
1855
+ ]
1856
+ },
1857
+ {
1858
+ id: "draw-credit-50-full",
1859
+ shape: {
1860
+ kind: "draw-credit",
1861
+ target: "evm",
1862
+ capacity: 50,
1863
+ noteInputs: 0,
1864
+ noteOutputs: 0,
1865
+ sourceTrees: 1,
1866
+ creditInputs: 50,
1867
+ creditOutputs: 0,
1868
+ creditRemainders: 0,
1869
+ funding: "none",
1870
+ permit: false,
1871
+ deliveryBytes: 0
1872
+ },
1873
+ circuit: {
1874
+ circuitName: "credit_draw_slots50",
1875
+ target: "evm",
1876
+ artifactSha256: "09c7469866748b4c0c4bbf2b040844771948a170999f6dc7a38fe5c0ecda4054",
1877
+ vkSha256: "7b613225b6f32a077011d4196c356e836d22dcd116efe687fde53144fbd8db9f"
1878
+ },
1879
+ samples: [
1880
+ {
1881
+ gasUsed: "3216708",
1882
+ transactionHash: "0x16933368d26ea1d7fbe69027c700671df832ad308944eeff42e7c2da40297b06",
1883
+ blockNumber: "172",
1884
+ blockHash: "0x0739a6f4188b8bdeae7bd5460960086d04adfea993d07d65b2b3630ad01b8cab",
1885
+ calldataBytes: 33476
1886
+ },
1887
+ {
1888
+ gasUsed: "3216840",
1889
+ transactionHash: "0x45dc15a62b1661f54e167cf13b9693770370c926a8a7af959da7354e9bb4aa6e",
1890
+ blockNumber: "172",
1891
+ blockHash: "0xf2e294db9af3b11814fed1dec358b8370ea28a99189211f883c9b0012349d677",
1892
+ calldataBytes: 33476
1893
+ },
1894
+ {
1895
+ gasUsed: "3216744",
1896
+ transactionHash: "0x2c827753026ea421497534a01bcc2adaca866a7612f570dad3fcf18c660f8590",
1897
+ blockNumber: "172",
1898
+ blockHash: "0x3ccd465528ff22e6d1955670220df3565899a16dd683f71c83c9810f2df420b4",
1899
+ calldataBytes: 33476
1900
+ }
1901
+ ]
1902
+ },
1903
+ {
1904
+ id: "draw-credit-120-partial",
1905
+ shape: {
1906
+ kind: "draw-credit",
1907
+ target: "evm",
1908
+ capacity: 120,
1909
+ noteInputs: 0,
1910
+ noteOutputs: 0,
1911
+ sourceTrees: 1,
1912
+ creditInputs: 120,
1913
+ creditOutputs: 120,
1914
+ creditRemainders: 120,
1915
+ funding: "none",
1916
+ permit: false,
1917
+ deliveryBytes: 135840
1918
+ },
1919
+ circuit: {
1920
+ circuitName: "credit_draw_slots120",
1921
+ target: "evm",
1922
+ artifactSha256: "6ccd0366a669c50fd5da875c3eae194fe8aa4c36d35a5f9ebfd64636ea599b48",
1923
+ vkSha256: "d715848afc5c1ecdfcef5ed5026865abef5040a3bc232fd65330a5ffee8475fb"
1924
+ },
1925
+ samples: [
1926
+ {
1927
+ gasUsed: "17458512",
1928
+ transactionHash: "0x84dd6bda5f3172a53e899051fd226dc5869edb796bd513a33e7f224bed13f4ae",
1929
+ blockNumber: "172",
1930
+ blockHash: "0xfca82de1e112b92319185d8c3f0115e0aa339d0247ea65970eb0d37ba958b08e",
1931
+ calldataBytes: 211140
1932
+ },
1933
+ {
1934
+ gasUsed: "17458224",
1935
+ transactionHash: "0xae26838942cf8b5499d43cb5e74681ae87aec77890a8eabddd692ff83830e013",
1936
+ blockNumber: "172",
1937
+ blockHash: "0x3e513447e0cfdbb682a95b7a719b0d300ec46b0ee22b518eaae7fb082f6436e7",
1938
+ calldataBytes: 211140
1939
+ },
1940
+ {
1941
+ gasUsed: "17458524",
1942
+ transactionHash: "0xeaa07e77fe958f4317e71b07ddb876482ae9c5172fd6d6cefaacc551dbbda7d5",
1943
+ blockNumber: "172",
1944
+ blockHash: "0x12b34c1fd2e15480276052842157c2a6355acdd43d7bd01ae7511c3f39e0ecfc",
1945
+ calldataBytes: 211140
1946
+ }
1947
+ ]
1948
+ },
1949
+ {
1950
+ id: "draw-credit-120-full",
1951
+ shape: {
1952
+ kind: "draw-credit",
1953
+ target: "evm",
1954
+ capacity: 120,
1955
+ noteInputs: 0,
1956
+ noteOutputs: 0,
1957
+ sourceTrees: 1,
1958
+ creditInputs: 120,
1959
+ creditOutputs: 0,
1960
+ creditRemainders: 0,
1961
+ funding: "none",
1962
+ permit: false,
1963
+ deliveryBytes: 0
1964
+ },
1965
+ circuit: {
1966
+ circuitName: "credit_draw_slots120",
1967
+ target: "evm",
1968
+ artifactSha256: "6ccd0366a669c50fd5da875c3eae194fe8aa4c36d35a5f9ebfd64636ea599b48",
1969
+ vkSha256: "d715848afc5c1ecdfcef5ed5026865abef5040a3bc232fd65330a5ffee8475fb"
1970
+ },
1971
+ samples: [
1972
+ {
1973
+ gasUsed: "6289576",
1974
+ transactionHash: "0xbf11743f7edc5ed5ff334efc5e35634f45e48e4940d33ddd9c87d8fe444dafc5",
1975
+ blockNumber: "172",
1976
+ blockHash: "0x774de17971107b73cab2cd20f26b60665f55a37b0cc1147166babf16743e34d5",
1977
+ calldataBytes: 65220
1978
+ },
1979
+ {
1980
+ gasUsed: "6289768",
1981
+ transactionHash: "0x651bb13e0645ee8a08657db627f1072f5e964ddaff44f70f829440ed68488dea",
1982
+ blockNumber: "172",
1983
+ blockHash: "0xa9795828565fb0ce65bda295073106b8bbdc110bb8317d269839d3db3e312d5b",
1984
+ calldataBytes: 65220
1985
+ },
1986
+ {
1987
+ gasUsed: "6289720",
1988
+ transactionHash: "0x2a859d381cb4b50830971b1ffc9789b11569fc96147e130dae6fecd141f5ceb0",
1989
+ blockNumber: "172",
1990
+ blockHash: "0x7d990830157bfeff8e5cbe580e9effe97faa7676c9957ce32891b76c83961430",
1991
+ calldataBytes: 65220
1992
+ }
1993
+ ]
1994
+ },
1995
+ {
1996
+ id: "top-up-credit-1x1-unchanged-limits",
1997
+ shape: {
1998
+ kind: "top-up-credit",
1999
+ target: "evm",
2000
+ capacity: 10,
2001
+ noteInputs: 1,
2002
+ noteOutputs: 1,
2003
+ sourceTrees: 2,
2004
+ creditInputs: 1,
2005
+ creditOutputs: 1,
2006
+ creditRemainders: 0,
2007
+ funding: "none",
2008
+ permit: false,
2009
+ deliveryBytes: 1360
2010
+ },
2011
+ circuit: {
2012
+ circuitName: "credit_top_up",
2013
+ target: "evm",
2014
+ artifactSha256: "2ffebd5753ec1b0c050204d4f97498765fe61ea01a793a9b2466c2f97536345c",
2015
+ vkSha256: "40b02a9d2e7eb7b49daaac4b7760328537b7982fd5a225cc065bb74cd5ef44b3"
2016
+ },
2017
+ samples: [
2018
+ {
2019
+ gasUsed: "1711282",
2020
+ transactionHash: "0x74d45084bb07bacabbced09ee6ef69d8632a22a4493be783c326c47e929ba0ed",
2021
+ blockNumber: "172",
2022
+ blockHash: "0x3503643f7081b52ae20d4754a0e9b11f52034ae48059f5b5298546c2570fa091",
2023
+ calldataBytes: 12292
2024
+ },
2025
+ {
2026
+ gasUsed: "1711282",
2027
+ transactionHash: "0x4b5e2432d5571f6b56507b3ab995a8120560ba608959ff100f03b87873e72be6",
2028
+ blockNumber: "172",
2029
+ blockHash: "0xca15dc309371a5aa9c7bc5bf1d65c5b325c71528ce7856ba68a118114124fccc",
2030
+ calldataBytes: 12292
2031
+ },
2032
+ {
2033
+ gasUsed: "1711390",
2034
+ transactionHash: "0x304f3740b64c80dcc5c894fb30af59080d96a11e08371096ae695cbc46ef2c8b",
2035
+ blockNumber: "172",
2036
+ blockHash: "0x9671ed76d6b8e49a36ba229d3609289fcf70756f31277ac5fc0e3f08cd52304f",
2037
+ calldataBytes: 12292
2038
+ }
2039
+ ]
2040
+ },
2041
+ {
2042
+ id: "top-up-credit-1x1-changed-limits",
2043
+ shape: {
2044
+ kind: "top-up-credit",
2045
+ target: "evm",
2046
+ capacity: 10,
2047
+ noteInputs: 1,
2048
+ noteOutputs: 1,
2049
+ sourceTrees: 2,
2050
+ creditInputs: 1,
2051
+ creditOutputs: 1,
2052
+ creditRemainders: 0,
2053
+ funding: "none",
2054
+ permit: false,
2055
+ deliveryBytes: 1360
2056
+ },
2057
+ circuit: {
2058
+ circuitName: "credit_top_up",
2059
+ target: "evm",
2060
+ artifactSha256: "2ffebd5753ec1b0c050204d4f97498765fe61ea01a793a9b2466c2f97536345c",
2061
+ vkSha256: "40b02a9d2e7eb7b49daaac4b7760328537b7982fd5a225cc065bb74cd5ef44b3"
2062
+ },
2063
+ samples: [
2064
+ {
2065
+ gasUsed: "1711318",
2066
+ transactionHash: "0x65284df534b42631f8a592fb2a6efc16361a4cc122f1a8dd41418e7b950f48f1",
2067
+ blockNumber: "172",
2068
+ blockHash: "0xf198242a1edf5b133961568c9165648c829729e7bfbbf57a1e148551c971b87c",
2069
+ calldataBytes: 12292
2070
+ },
2071
+ {
2072
+ gasUsed: "1711438",
2073
+ transactionHash: "0xcee89a81e598974798365c4ebada806fb51196ee602334b0fffdbb25da0afe25",
2074
+ blockNumber: "172",
2075
+ blockHash: "0xb506a6fb54cc2f91b803211ed955aac0203fba93e2428f8f52ec0d413c90af09",
2076
+ calldataBytes: 12292
2077
+ },
2078
+ {
2079
+ gasUsed: "1711342",
2080
+ transactionHash: "0x957de5c79f365c9b0510b9e125a662317494aad50cb446edceef6f678d561cc7",
2081
+ blockNumber: "172",
2082
+ blockHash: "0xb1d5cffd6d6db58ade9d5e16d48b060b9ab2152415966dc809e7e70785472ab8",
2083
+ calldataBytes: 12292
2084
+ }
2085
+ ]
2086
+ },
2087
+ {
2088
+ id: "cancel-credit-1",
2089
+ shape: {
2090
+ kind: "cancel-credit",
2091
+ target: "evm",
2092
+ capacity: 1,
2093
+ noteInputs: 0,
2094
+ noteOutputs: 0,
2095
+ sourceTrees: 1,
2096
+ creditInputs: 1,
2097
+ creditOutputs: 0,
2098
+ creditRemainders: 0,
2099
+ funding: "none",
2100
+ permit: false,
2101
+ deliveryBytes: 0
2102
+ },
2103
+ circuit: {
2104
+ circuitName: "credit_cancel",
2105
+ target: "evm",
2106
+ artifactSha256: "b4459c2cf756d096e37291cf4d7cd129866b6d420b6d03c928f383b057112ccb",
2107
+ vkSha256: "fc8ad196ef15f3328afcc8f01d867a3ebefd15451c2813948442fab1923b73b2"
2108
+ },
2109
+ samples: [
2110
+ {
2111
+ gasUsed: "985543",
2112
+ transactionHash: "0x29ca63fbefcc5e92dbc86f67d6280993e567a5dd02ff3defd7f3251ce711865e",
2113
+ blockNumber: "172",
2114
+ blockHash: "0xecd7808fe9f7467af917069bd7a82ab0324e3cbab8dcad622b089d6e3eee9a58",
2115
+ calldataBytes: 9540
2116
+ },
2117
+ {
2118
+ gasUsed: "985795",
2119
+ transactionHash: "0xaf8bca0769330f89b647363f99b752dbbe6fdbb8b1aae912224f6a3a59f40faa",
2120
+ blockNumber: "172",
2121
+ blockHash: "0x58e1358e02f189d57628fa7c504b87fb000fe60eb9f0a0c3c0e58dae876e64da",
2122
+ calldataBytes: 9540
2123
+ },
2124
+ {
2125
+ gasUsed: "985711",
2126
+ transactionHash: "0x2c911fd5a422f6f72f2a00b16872b7e46e182d39b8f5bfa9e3b2bf99d3155da7",
2127
+ blockNumber: "172",
2128
+ blockHash: "0x9da571cbe63f52232261ee1527d5ed97a9e90e374b4fcda97d04feb25114d18e",
2129
+ calldataBytes: 9540
2130
+ }
2131
+ ]
2132
+ }
2133
+ ]
2134
+ },
2135
+ {
2136
+ formatVersion: 1,
2137
+ id: "protocol-92ef274-osaka-real",
2138
+ deployment: {
2139
+ chainId: "31337",
2140
+ protocolAddress: "0x8870C63A18a9480C7de9B860b849fD293832856D",
2141
+ runtimeCodeHash: "0x604572c0da90ea139b774cd0d2962a2972fac46e0556c7cec6f6f9aac5deef14",
2142
+ tokenAddress: "0x4826533B4897376654Bb4d4AD88B7faFD0C98528"
2143
+ },
2144
+ source: {
2145
+ protocolCommit: "92ef274c6b36d783507699a33ee20e52192c83c7",
2146
+ measuredAt: "2026-10-27T08:42:15.991Z",
2147
+ chain: "Anvil 31337",
2148
+ hardfork: "osaka",
2149
+ token: "MockERC20",
2150
+ verifier: "real",
2151
+ assumptions: [
2152
+ "normal CREATE/Factory deployment; no code or storage injection",
2153
+ "Solidity 0.8.27 optimizer 200; real BB 5.2.1 verifiers",
2154
+ "one source tree; two existing leaves; no rollover or screener",
2155
+ "funding/approval setup excluded; complete transaction receipt gas included",
2156
+ "exact allowance for caller funding; configured benchmark payout balances",
2157
+ "observed local samples, not a confidence interval or gas limit"
2158
+ ]
2159
+ },
2160
+ measurements: [
2161
+ {
2162
+ id: "shield-1",
2163
+ shape: {
2164
+ kind: "shield",
2165
+ target: "evm",
2166
+ capacity: 0,
2167
+ noteInputs: 0,
2168
+ noteOutputs: 1,
2169
+ sourceTrees: 0,
2170
+ creditInputs: 0,
2171
+ creditOutputs: 0,
2172
+ creditRemainders: 0,
2173
+ funding: "caller",
2174
+ permit: false,
2175
+ deliveryBytes: 226
2176
+ },
2177
+ circuit: null,
2178
+ samples: [
2179
+ {
2180
+ gasUsed: "649286",
2181
+ transactionHash: "0xcc299d1780ada9a69b1d9f0f3d06a165db15fccbd2b7ff407834f02f5d563a18",
2182
+ blockNumber: "50",
2183
+ blockHash: "0xbcb868e781a20588d2fa099a4d7f87c1600044a2e5ec1e369e384d7a5f22f00a",
2184
+ calldataBytes: 1156
2185
+ },
2186
+ {
2187
+ gasUsed: "649322",
2188
+ transactionHash: "0x95139dff109725989f0769e3e6fb9bd3e7e1bf581fd475f14e822875eb90fda4",
2189
+ blockNumber: "50",
2190
+ blockHash: "0x7ace353fea4fc8c856c0fd45521d200b02619921977709ff4f910e0ff41c06fe",
2191
+ calldataBytes: 1156
2192
+ },
2193
+ {
2194
+ gasUsed: "649322",
2195
+ transactionHash: "0xef578bb38dc8ff8bfd47d2e76e3ab4273019ea9a385f5d2fd99add32ceaecb58",
2196
+ blockNumber: "50",
2197
+ blockHash: "0xded817f8ef89637e2443e3b626c0837f184ca134fe753be913d5570554c649a6",
2198
+ calldataBytes: 1156
2199
+ }
2200
+ ]
2201
+ },
2202
+ {
2203
+ id: "shield-2",
2204
+ shape: {
2205
+ kind: "shield",
2206
+ target: "evm",
2207
+ capacity: 0,
2208
+ noteInputs: 0,
2209
+ noteOutputs: 2,
2210
+ sourceTrees: 0,
2211
+ creditInputs: 0,
2212
+ creditOutputs: 0,
2213
+ creditRemainders: 0,
2214
+ funding: "caller",
2215
+ permit: false,
2216
+ deliveryBytes: 452
2217
+ },
2218
+ circuit: null,
2219
+ samples: [
2220
+ {
2221
+ gasUsed: "757063",
2222
+ transactionHash: "0x024e2dfbd6f50c368e2a4aa347e3029de668f4ebd36b80227aa003bb7ac21c74",
2223
+ blockNumber: "50",
2224
+ blockHash: "0x8ed63973c158d706ac54bb646626e4f0db5777b4bd56d179b94503af6c417c50",
2225
+ calldataBytes: 1668
2226
+ },
2227
+ {
2228
+ gasUsed: "757063",
2229
+ transactionHash: "0x898d852ab28f68adac4d30b160a3dbfee33fa7ca875f70df9eb7763b6b1cd1f0",
2230
+ blockNumber: "50",
2231
+ blockHash: "0x9bb6810de38193933a9f26fa03d3d9bad1ca0151ff5e04544c56520e09da3043",
2232
+ calldataBytes: 1668
1588
2233
  },
1589
2234
  {
1590
- gasUsed: "5389203",
1591
- transactionHash: "0xee69d565a7eafb60ad7a47afe80a49d4fa40b50660669d9141e7dc6f4c3dbe0d",
1592
- blockNumber: "49",
1593
- blockHash: "0x0dcdada663ee04dd63e06fcdb79dacc5623201d29b687f63deede2b4762a994e",
1594
- calldataBytes: 36356
2235
+ gasUsed: "757039",
2236
+ transactionHash: "0x8ff9720e3197aab2d741fbd8d0fa2969203ea8cd051d9649d1e5eb890bcc2be3",
2237
+ blockNumber: "50",
2238
+ blockHash: "0x8604c75eb6363aaae774276e638f5b749aae1f8f815eb99ab1183137eef5730e",
2239
+ calldataBytes: 1668
1595
2240
  }
1596
2241
  ]
1597
2242
  },
1598
2243
  {
1599
- id: "transfer-1x112",
2244
+ id: "shield-10",
1600
2245
  shape: {
1601
- kind: "transfer",
2246
+ kind: "shield",
1602
2247
  target: "evm",
1603
- capacity: 168,
1604
- noteInputs: 1,
1605
- noteOutputs: 112,
1606
- sourceTrees: 1,
2248
+ capacity: 0,
2249
+ noteInputs: 0,
2250
+ noteOutputs: 10,
2251
+ sourceTrees: 0,
1607
2252
  creditInputs: 0,
1608
2253
  creditOutputs: 0,
1609
2254
  creditRemainders: 0,
1610
- funding: "none",
2255
+ funding: "caller",
1611
2256
  permit: false,
1612
- deliveryBytes: 25312
1613
- },
1614
- circuit: {
1615
- circuitName: "transact_user_slots168",
1616
- target: "evm",
1617
- artifactSha256: "f7b3b1384e961367702f544299ca3521d8205fac31b7691c45ff84325d5a31c3",
1618
- vkSha256: "e00181533d7e35d2307570528f9e7f8f88e2909b6ae338d93373b608dea96881"
2257
+ deliveryBytes: 2260
1619
2258
  },
2259
+ circuit: null,
1620
2260
  samples: [
1621
2261
  {
1622
- gasUsed: "9139842",
1623
- transactionHash: "0x09951c4e00b868b6660429d187a482004646e4c84ef341d3b98352c249db6a06",
1624
- blockNumber: "49",
1625
- blockHash: "0xba9da3c08189335acff1eb33554f5f12475e4a6510324cf6ec9eadf340ce15d2",
1626
- calldataBytes: 61444
2262
+ gasUsed: "1692143",
2263
+ transactionHash: "0x6c13db8bd8a8599daf5034e56712abefbf406982fafe7647b6d22291ba4199ed",
2264
+ blockNumber: "50",
2265
+ blockHash: "0x1ab2ae514f408a79e0c40ca10cee74b2e23d7c8a5f24641b8eea3e1cf58ce700",
2266
+ calldataBytes: 5764
1627
2267
  },
1628
2268
  {
1629
- gasUsed: "9139650",
1630
- transactionHash: "0xb06f69d1c6e5406758918d5d296ab889bab4c3814f616cc581ad312cc7ebb2f3",
1631
- blockNumber: "49",
1632
- blockHash: "0x5516a76b4b366f2e539a67bb848b7d232c3e6f328d34ca5bd3dba43a14c316bf",
1633
- calldataBytes: 61444
2269
+ gasUsed: "1692083",
2270
+ transactionHash: "0x5e476c9d3838b782a51332af9bf5c372d29fc411c2168a7af619c52bd5309c7b",
2271
+ blockNumber: "50",
2272
+ blockHash: "0x9c62bc72fc90f990c6711b48865ff922a1856ae05c4fef61dad5f4da7d948401",
2273
+ calldataBytes: 5764
1634
2274
  },
1635
2275
  {
1636
- gasUsed: "9139530",
1637
- transactionHash: "0x116c4875b7712b7cb51cdb0fcb6e66a95733dca272aa272bc0b1fd265edbe26c",
1638
- blockNumber: "49",
1639
- blockHash: "0xd36340fddd1eace21b73f785c6589bf73b07bef782f2e78a5e3d3d828b0b607c",
1640
- calldataBytes: 61444
2276
+ gasUsed: "1692203",
2277
+ transactionHash: "0x0092e2d9160fad95279cde586fc6c79c713244f55db8a2060a5abab9d98c176a",
2278
+ blockNumber: "50",
2279
+ blockHash: "0xac1bf780b4cc05b4dcc7ee5d741c049ba99ab4af9bdcd25104add730c2a14152",
2280
+ calldataBytes: 5764
1641
2281
  }
1642
2282
  ]
1643
2283
  },
1644
2284
  {
1645
- id: "withdraw-1x1",
2285
+ id: "transfer-1x2",
1646
2286
  shape: {
1647
- kind: "withdraw",
2287
+ kind: "transfer",
1648
2288
  target: "evm",
1649
2289
  capacity: 14,
1650
2290
  noteInputs: 1,
1651
- noteOutputs: 1,
2291
+ noteOutputs: 2,
1652
2292
  sourceTrees: 1,
1653
2293
  creditInputs: 0,
1654
2294
  creditOutputs: 0,
1655
2295
  creditRemainders: 0,
1656
2296
  funding: "none",
1657
2297
  permit: false,
1658
- deliveryBytes: 226
2298
+ deliveryBytes: 452
1659
2299
  },
1660
2300
  circuit: {
1661
2301
  circuitName: "transact_user_slots14",
@@ -1665,222 +2305,222 @@ var gas_benchmarks_default = [
1665
2305
  },
1666
2306
  samples: [
1667
2307
  {
1668
- gasUsed: "1597571",
1669
- transactionHash: "0x326892d32146e0bc36b396fd3973151a629312df68ed25a4ffbb6a3da23ba274",
2308
+ gasUsed: "1617516",
2309
+ transactionHash: "0xf49ea3d31cc1346472172e2dee84f9360f60a3fe948a3ef6e87f727af6d42f0d",
1670
2310
  blockNumber: "49",
1671
- blockHash: "0x3e0f326cba3dd019b86431b4c22145758a7f10c121a696a81a094746b04495b5",
1672
- calldataBytes: 10564
2311
+ blockHash: "0xf59c57e63ec2f03abc36d28f273b0af5290184dc97197df740b23d79a851a887",
2312
+ calldataBytes: 11012
1673
2313
  },
1674
2314
  {
1675
- gasUsed: "1597715",
1676
- transactionHash: "0x2e3a15157ac9c07e4717bbd4641481ce3bc0068d26157752815b6ec6b30acdd0",
2315
+ gasUsed: "1617516",
2316
+ transactionHash: "0xf8d11286f1f2a4db006ff6b06900c47d0fbf685984499e1e5d4aea49478ba8e5",
1677
2317
  blockNumber: "49",
1678
- blockHash: "0xab7fceac97d55e8702d1202b98d3a05c4b1e0f71e51b6d88d7e80e91cc338596",
1679
- calldataBytes: 10564
2318
+ blockHash: "0xeb5a800190be3534c9e2675c97ac56d0e0be8adef55f60bd32d375776a7d150c",
2319
+ calldataBytes: 11012
1680
2320
  },
1681
2321
  {
1682
- gasUsed: "1597595",
1683
- transactionHash: "0x5052e94a67520c43416cdcb60a1365a126560861173d0eef46bcbf0a566fe947",
2322
+ gasUsed: "1617504",
2323
+ transactionHash: "0x8939fcea97079a3c5118b9e94325455e2ad1cdb47310ae499a277272654b3eb6",
1684
2324
  blockNumber: "49",
1685
- blockHash: "0x9a64cf76b646b5a07b72fcc61266e87f17365fec891701c331982a93e5ba9b89",
1686
- calldataBytes: 10564
2325
+ blockHash: "0xecffefb593e2fec5d5827cfd39d0cc4d0efb67dbff6f8dbbd0d2db2439a80cf9",
2326
+ calldataBytes: 11012
1687
2327
  }
1688
2328
  ]
1689
2329
  },
1690
2330
  {
1691
- id: "sweep-1x0",
2331
+ id: "transfer-1x14",
1692
2332
  shape: {
1693
- kind: "sweep",
2333
+ kind: "transfer",
1694
2334
  target: "evm",
1695
- capacity: 14,
2335
+ capacity: 56,
1696
2336
  noteInputs: 1,
1697
- noteOutputs: 0,
2337
+ noteOutputs: 14,
1698
2338
  sourceTrees: 1,
1699
2339
  creditInputs: 0,
1700
2340
  creditOutputs: 0,
1701
2341
  creditRemainders: 0,
1702
2342
  funding: "none",
1703
2343
  permit: false,
1704
- deliveryBytes: 0
2344
+ deliveryBytes: 3164
1705
2345
  },
1706
2346
  circuit: {
1707
- circuitName: "transact_user_slots14",
2347
+ circuitName: "transact_user_slots56",
1708
2348
  target: "evm",
1709
- artifactSha256: "2a6a20839e90b88b1ecd629f59a01821bad3ee11dbe04db1fd9cdce7a3de0e84",
1710
- vkSha256: "ffe0e1a4e690792ecb4eb1fc1acc9ff60f13d3b5af03cfc6ae6d6bf26e99bdea"
2349
+ artifactSha256: "ba83ec2f177d16fa88ea04bc54f2e99920f1ac195cdb05b88b9b3bbc245fd953",
2350
+ vkSha256: "6ad5d3aff0c72a632fb19895658af093a6a92478a9994985e838a71e61237720"
1711
2351
  },
1712
2352
  samples: [
1713
2353
  {
1714
- gasUsed: "1069308",
1715
- transactionHash: "0xb1ab469d05ca5f49659f54a332cc172892dcce37e475342fbf52fa9cfb4d3927",
2354
+ gasUsed: "2489010",
2355
+ transactionHash: "0x053557acea930a869d6469c91e9bc015d0893607a6ab18d2af684986f7074676",
1716
2356
  blockNumber: "49",
1717
- blockHash: "0xe5b04579149987198801f1ca19ab771d5262de2aaf9861a6c962d50d1c6baef0",
1718
- calldataBytes: 10116
2357
+ blockHash: "0x734873097eb5e4cb66bfc2cdb61fac6753b53a4b9450fb22895281100af3aaf3",
2358
+ calldataBytes: 17156
1719
2359
  },
1720
2360
  {
1721
- gasUsed: "1069284",
1722
- transactionHash: "0xd6adee997f7e1e19e3918f913f6ee48d94df69c09ed74e333325023089e7f6df",
2361
+ gasUsed: "2489106",
2362
+ transactionHash: "0xb3990edb994011775e275bc1eb38c527b7206a2bfadf510e8aa53e260f3594b8",
1723
2363
  blockNumber: "49",
1724
- blockHash: "0xcb225566f8f1ea6ae8da30158b8f1aef03d50fa4ea352a00aa42b7f41a05d63c",
1725
- calldataBytes: 10116
2364
+ blockHash: "0xf8cb019ebb0ecd0ec5d6634198292883c63fe93a7c65c34f9f3120c6cc54f1cf",
2365
+ calldataBytes: 17156
1726
2366
  },
1727
2367
  {
1728
- gasUsed: "1069308",
1729
- transactionHash: "0xe06dd7f3a2718bc9a9412c2d6f505960ce225b2e5fe6c1c66bb5b0e8f427006f",
2368
+ gasUsed: "2489094",
2369
+ transactionHash: "0xc97079019567ff8a79d285421351ee4bc48d14092a0e12ff634151719e991088",
1730
2370
  blockNumber: "49",
1731
- blockHash: "0x37a08c5918892e1c19df017c746ab0ede03c1bb195c3be593d70c1f9de91897e",
1732
- calldataBytes: 10116
2371
+ blockHash: "0x5a6947839165c8961eeeb9190331415c40366a78b4a6a5771e7b8954dbb8b3c7",
2372
+ calldataBytes: 17156
1733
2373
  }
1734
2374
  ]
1735
2375
  },
1736
2376
  {
1737
- id: "create-credit-1x1",
2377
+ id: "transfer-1x56",
1738
2378
  shape: {
1739
- kind: "create-credit",
2379
+ kind: "transfer",
1740
2380
  target: "evm",
1741
- capacity: 10,
2381
+ capacity: 112,
1742
2382
  noteInputs: 1,
1743
- noteOutputs: 1,
2383
+ noteOutputs: 56,
1744
2384
  sourceTrees: 1,
1745
2385
  creditInputs: 0,
1746
- creditOutputs: 1,
2386
+ creditOutputs: 0,
1747
2387
  creditRemainders: 0,
1748
2388
  funding: "none",
1749
2389
  permit: false,
1750
- deliveryBytes: 1162
2390
+ deliveryBytes: 12656
1751
2391
  },
1752
2392
  circuit: {
1753
- circuitName: "create_credit",
2393
+ circuitName: "transact_user_slots112",
1754
2394
  target: "evm",
1755
- artifactSha256: "ab97cd5a036851a9748a5cfd8e6f9834e23090c8e95db4531aabfc37d3abb353",
1756
- vkSha256: "fac0e65b768a28750323cca851990598af936611125b6cfa3f5c16b04c7d084f"
2395
+ artifactSha256: "713b78469b6e97711122210f8497942120c1c9d66d3604bc184566c4eba59cc3",
2396
+ vkSha256: "d6a46e297949c28b9a62fd9aef1f202870fdca97b8bfb15beefd27b9e9f3d86e"
1757
2397
  },
1758
2398
  samples: [
1759
2399
  {
1760
- gasUsed: "1627325",
1761
- transactionHash: "0x7763d93a5b1e8797b5f4af2e1e5b1bb029a8b0f9f7b90bcc04f581947d826803",
2400
+ gasUsed: "5389227",
2401
+ transactionHash: "0xb820d3c358724c1d64422017f232d074e4ff1ffaf1b1ce5ee719409427cf2208",
1762
2402
  blockNumber: "49",
1763
- blockHash: "0x93e51ae5e99c68dc642693d478e444330d8e26255ff5bb9aafc4a3f4e70d3a45",
1764
- calldataBytes: 11940
2403
+ blockHash: "0x474bd1e52457801d1a596a9f23aeb6d365a17be028ee0c8cf8fd4758eaa1106b",
2404
+ calldataBytes: 36356
1765
2405
  },
1766
2406
  {
1767
- gasUsed: "1627385",
1768
- transactionHash: "0xe246d59cafa2a26dddf21c8385dd843be4d4596388ebe23e936df84e7f906635",
2407
+ gasUsed: "5389095",
2408
+ transactionHash: "0x16514d8cf1136d7a7f40591859e2ea2d256af66520498e1fc81eb28837db600d",
1769
2409
  blockNumber: "49",
1770
- blockHash: "0x3c24b2d6ed2a998562d34b49e0517515742a9b39d59aec38a9ac6b22be1b694b",
1771
- calldataBytes: 11940
2410
+ blockHash: "0x42314a0d6eb9e765869e1b66b279444c78f919d2c28aed544d9fa7ac3bd2acb4",
2411
+ calldataBytes: 36356
1772
2412
  },
1773
2413
  {
1774
- gasUsed: "1627157",
1775
- transactionHash: "0x2f7ed0b75435cc6a820d0cd90fd82d362f74787057413722b6eb3c6e37db87d3",
2414
+ gasUsed: "5389203",
2415
+ transactionHash: "0xee69d565a7eafb60ad7a47afe80a49d4fa40b50660669d9141e7dc6f4c3dbe0d",
1776
2416
  blockNumber: "49",
1777
- blockHash: "0x0a0301670b46017da772800c68bb941245ac1941c79fde9c85717632154e15ee",
1778
- calldataBytes: 11940
2417
+ blockHash: "0x0dcdada663ee04dd63e06fcdb79dacc5623201d29b687f63deede2b4762a994e",
2418
+ calldataBytes: 36356
1779
2419
  }
1780
2420
  ]
1781
2421
  },
1782
2422
  {
1783
- id: "draw-credit-1-partial",
2423
+ id: "transfer-1x112",
1784
2424
  shape: {
1785
- kind: "draw-credit",
2425
+ kind: "transfer",
1786
2426
  target: "evm",
1787
- capacity: 1,
1788
- noteInputs: 0,
1789
- noteOutputs: 0,
2427
+ capacity: 168,
2428
+ noteInputs: 1,
2429
+ noteOutputs: 112,
1790
2430
  sourceTrees: 1,
1791
- creditInputs: 1,
1792
- creditOutputs: 1,
1793
- creditRemainders: 1,
2431
+ creditInputs: 0,
2432
+ creditOutputs: 0,
2433
+ creditRemainders: 0,
1794
2434
  funding: "none",
1795
2435
  permit: false,
1796
- deliveryBytes: 936
2436
+ deliveryBytes: 25312
1797
2437
  },
1798
2438
  circuit: {
1799
- circuitName: "credit_draw_slots1",
2439
+ circuitName: "transact_user_slots168",
1800
2440
  target: "evm",
1801
- artifactSha256: "f5e458790948f37a61a833fad52cf2cc3b26a59515d271de32e0caaa4e229eb5",
1802
- vkSha256: "613699a440f50a0937e4c57e5152b5fdea42c31b10157d6b93226fef313df553"
2441
+ artifactSha256: "f7b3b1384e961367702f544299ca3521d8205fac31b7691c45ff84325d5a31c3",
2442
+ vkSha256: "e00181533d7e35d2307570528f9e7f8f88e2909b6ae338d93373b608dea96881"
1803
2443
  },
1804
2444
  samples: [
1805
2445
  {
1806
- gasUsed: "1581294",
1807
- transactionHash: "0xd438e22b0fa07a657279f182537e4996f1936f0881d5b7d637845f8ca2808aab",
2446
+ gasUsed: "9139842",
2447
+ transactionHash: "0x09951c4e00b868b6660429d187a482004646e4c84ef341d3b98352c249db6a06",
1808
2448
  blockNumber: "49",
1809
- blockHash: "0x9e384a3054530b1ff237a639bca1a559afb2b73b30e21c262aac85ebf480fc9b",
1810
- calldataBytes: 11396
2449
+ blockHash: "0xba9da3c08189335acff1eb33554f5f12475e4a6510324cf6ec9eadf340ce15d2",
2450
+ calldataBytes: 61444
1811
2451
  },
1812
2452
  {
1813
- gasUsed: "1581402",
1814
- transactionHash: "0xa70ac3e7284b6e98f8591a6ba88e4ddfb23ecbd05343641d0532f34920e10b56",
2453
+ gasUsed: "9139650",
2454
+ transactionHash: "0xb06f69d1c6e5406758918d5d296ab889bab4c3814f616cc581ad312cc7ebb2f3",
1815
2455
  blockNumber: "49",
1816
- blockHash: "0x37c5eb34ce96a841e96c36103a7ab65c1a3e08603dc9843efb0c0752c069f1d4",
1817
- calldataBytes: 11396
2456
+ blockHash: "0x5516a76b4b366f2e539a67bb848b7d232c3e6f328d34ca5bd3dba43a14c316bf",
2457
+ calldataBytes: 61444
1818
2458
  },
1819
2459
  {
1820
- gasUsed: "1581174",
1821
- transactionHash: "0xd062494979d0bc0e284ccb070f87b48f3e8e5befb6001f15a006dd2a4a72ca24",
2460
+ gasUsed: "9139530",
2461
+ transactionHash: "0x116c4875b7712b7cb51cdb0fcb6e66a95733dca272aa272bc0b1fd265edbe26c",
1822
2462
  blockNumber: "49",
1823
- blockHash: "0x12840d920f14163b2d29491f28cee616e1bb9fd9514a4debe10ae35256345fc1",
1824
- calldataBytes: 11396
2463
+ blockHash: "0xd36340fddd1eace21b73f785c6589bf73b07bef782f2e78a5e3d3d828b0b607c",
2464
+ calldataBytes: 61444
1825
2465
  }
1826
2466
  ]
1827
2467
  },
1828
2468
  {
1829
- id: "top-up-credit-1x1",
2469
+ id: "withdraw-1x1",
1830
2470
  shape: {
1831
- kind: "top-up-credit",
2471
+ kind: "withdraw",
1832
2472
  target: "evm",
1833
- capacity: 10,
2473
+ capacity: 14,
1834
2474
  noteInputs: 1,
1835
2475
  noteOutputs: 1,
1836
- sourceTrees: 2,
1837
- creditInputs: 1,
1838
- creditOutputs: 1,
2476
+ sourceTrees: 1,
2477
+ creditInputs: 0,
2478
+ creditOutputs: 0,
1839
2479
  creditRemainders: 0,
1840
2480
  funding: "none",
1841
2481
  permit: false,
1842
- deliveryBytes: 1162
2482
+ deliveryBytes: 226
1843
2483
  },
1844
2484
  circuit: {
1845
- circuitName: "credit_top_up",
2485
+ circuitName: "transact_user_slots14",
1846
2486
  target: "evm",
1847
- artifactSha256: "ee9dbcf8be6f6c09478190996e90b1d39d4a10a00245950f69fc1d2c329c6e9b",
1848
- vkSha256: "0c369fec0469b60baebb3be650bad42f3ccae6f0ff139cce6ad9a3f451ed7513"
2487
+ artifactSha256: "2a6a20839e90b88b1ecd629f59a01821bad3ee11dbe04db1fd9cdce7a3de0e84",
2488
+ vkSha256: "ffe0e1a4e690792ecb4eb1fc1acc9ff60f13d3b5af03cfc6ae6d6bf26e99bdea"
1849
2489
  },
1850
2490
  samples: [
1851
2491
  {
1852
- gasUsed: "1666948",
1853
- transactionHash: "0x1403da01167962a4349d2655ea217bfcfc1a2390138bea0279792c44b4381dd2",
2492
+ gasUsed: "1597571",
2493
+ transactionHash: "0x326892d32146e0bc36b396fd3973151a629312df68ed25a4ffbb6a3da23ba274",
1854
2494
  blockNumber: "49",
1855
- blockHash: "0xcb554ffcdb4afe5f6458e5d23ffbdd1fdbef9c23f982343065772c0b3e3dd633",
1856
- calldataBytes: 12100
2495
+ blockHash: "0x3e0f326cba3dd019b86431b4c22145758a7f10c121a696a81a094746b04495b5",
2496
+ calldataBytes: 10564
1857
2497
  },
1858
2498
  {
1859
- gasUsed: "1666900",
1860
- transactionHash: "0x3b5e54f29e3f888a443526cf23ab9255b3f0c7adf1d0d127c16b85f4c6a324d9",
2499
+ gasUsed: "1597715",
2500
+ transactionHash: "0x2e3a15157ac9c07e4717bbd4641481ce3bc0068d26157752815b6ec6b30acdd0",
1861
2501
  blockNumber: "49",
1862
- blockHash: "0xeb304df6bdd24b249cac3197b543b0eaa6381ed75ad812dff248f914864105ed",
1863
- calldataBytes: 12100
2502
+ blockHash: "0xab7fceac97d55e8702d1202b98d3a05c4b1e0f71e51b6d88d7e80e91cc338596",
2503
+ calldataBytes: 10564
1864
2504
  },
1865
2505
  {
1866
- gasUsed: "1666780",
1867
- transactionHash: "0x81c5ef25268a719275cb3b80618c2af291e1f7b3f91d7e82cc26bc894a8c332a",
2506
+ gasUsed: "1597595",
2507
+ transactionHash: "0x5052e94a67520c43416cdcb60a1365a126560861173d0eef46bcbf0a566fe947",
1868
2508
  blockNumber: "49",
1869
- blockHash: "0xfa42070d6349fc8d559b8bd4ad0ee6b79089107540c4472b9e492b8f5a6bd3e4",
1870
- calldataBytes: 12100
2509
+ blockHash: "0x9a64cf76b646b5a07b72fcc61266e87f17365fec891701c331982a93e5ba9b89",
2510
+ calldataBytes: 10564
1871
2511
  }
1872
2512
  ]
1873
2513
  },
1874
2514
  {
1875
- id: "cancel-credit-1",
2515
+ id: "sweep-1x0",
1876
2516
  shape: {
1877
- kind: "cancel-credit",
2517
+ kind: "sweep",
1878
2518
  target: "evm",
1879
- capacity: 1,
1880
- noteInputs: 0,
2519
+ capacity: 14,
2520
+ noteInputs: 1,
1881
2521
  noteOutputs: 0,
1882
2522
  sourceTrees: 1,
1883
- creditInputs: 1,
2523
+ creditInputs: 0,
1884
2524
  creditOutputs: 0,
1885
2525
  creditRemainders: 0,
1886
2526
  funding: "none",
@@ -1888,32 +2528,32 @@ var gas_benchmarks_default = [
1888
2528
  deliveryBytes: 0
1889
2529
  },
1890
2530
  circuit: {
1891
- circuitName: "credit_cancel",
2531
+ circuitName: "transact_user_slots14",
1892
2532
  target: "evm",
1893
- artifactSha256: "d332453a2b8c2c544747ac8d5f01912c9757f48d986226fd6a9b0e24d8321474",
1894
- vkSha256: "1f8a3c20cb081d6a90962556da3124919cc4e5675e59ad31562af39299da02fb"
2533
+ artifactSha256: "2a6a20839e90b88b1ecd629f59a01821bad3ee11dbe04db1fd9cdce7a3de0e84",
2534
+ vkSha256: "ffe0e1a4e690792ecb4eb1fc1acc9ff60f13d3b5af03cfc6ae6d6bf26e99bdea"
1895
2535
  },
1896
2536
  samples: [
1897
2537
  {
1898
- gasUsed: "998146",
1899
- transactionHash: "0x97bc72692d241e2c344b912804f9939061db5ef59cf4bb23922d93812e382160",
2538
+ gasUsed: "1069308",
2539
+ transactionHash: "0xb1ab469d05ca5f49659f54a332cc172892dcce37e475342fbf52fa9cfb4d3927",
1900
2540
  blockNumber: "49",
1901
- blockHash: "0x2e09df4df84a1c25961386febe8404531bb5da274836d50cc15a26c91b433a98",
1902
- calldataBytes: 9540
2541
+ blockHash: "0xe5b04579149987198801f1ca19ab771d5262de2aaf9861a6c962d50d1c6baef0",
2542
+ calldataBytes: 10116
1903
2543
  },
1904
2544
  {
1905
- gasUsed: "998134",
1906
- transactionHash: "0x26c5067b12c2bc4b694070784e6b19d4855efa6e77c2422f0c6b1567f061570a",
2545
+ gasUsed: "1069284",
2546
+ transactionHash: "0xd6adee997f7e1e19e3918f913f6ee48d94df69c09ed74e333325023089e7f6df",
1907
2547
  blockNumber: "49",
1908
- blockHash: "0xdd3f20520c09e001374cab58387e52c82446db053539e30dad28b0de679a333c",
1909
- calldataBytes: 9540
2548
+ blockHash: "0xcb225566f8f1ea6ae8da30158b8f1aef03d50fa4ea352a00aa42b7f41a05d63c",
2549
+ calldataBytes: 10116
1910
2550
  },
1911
2551
  {
1912
- gasUsed: "998230",
1913
- transactionHash: "0x5dc09445a405150da1445c22f50d6dd10d8d428a6a3f41ee90db7d3574657e31",
2552
+ gasUsed: "1069308",
2553
+ transactionHash: "0xe06dd7f3a2718bc9a9412c2d6f505960ce225b2e5fe6c1c66bb5b0e8f427006f",
1914
2554
  blockNumber: "49",
1915
- blockHash: "0x5c8f8223a50d2c8d48188a2db28ffa33c1b150a2fb465e99db4430949db3664b",
1916
- calldataBytes: 9540
2555
+ blockHash: "0x37a08c5918892e1c19df017c746ab0ede03c1bb195c3be593d70c1f9de91897e",
2556
+ calldataBytes: 10116
1917
2557
  }
1918
2558
  ]
1919
2559
  }
@@ -1944,6 +2584,29 @@ function copyGasBenchmarks(profiles) {
1944
2584
  for (const p of copy) {
1945
2585
  if (p.formatVersion !== 1 || !p.id || !decimal.test(p.deployment.chainId) || !address.test(p.deployment.protocolAddress) || !address.test(p.deployment.tokenAddress) || !p.deployment.runtimeCodeHash || !word2.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)
1946
2586
  throw new Error("invalid gas benchmark profile");
2587
+ if (p.source.fingerprints && ![
2588
+ "protocolSourceSha256",
2589
+ "dirtyDiffSha256",
2590
+ "compiledArtifactsSha256",
2591
+ "creditManifestSha256",
2592
+ "userManifestSha256",
2593
+ "sdkSourceSha256"
2594
+ ].every((key) => {
2595
+ const v = p.source.fingerprints[key];
2596
+ return typeof v === "string" && /^[a-f0-9]{64}$/i.test(v);
2597
+ }))
2598
+ throw new Error("invalid benchmark source fingerprint");
2599
+ if (p.source.blockGasLimit !== void 0 && (!decimal.test(p.source.blockGasLimit) || BigInt(p.source.blockGasLimit) <= 0n))
2600
+ throw new Error("invalid benchmark block gas limit");
2601
+ if (p.source.runtimeContracts && !Object.values(p.source.runtimeContracts).every(
2602
+ (v) => address.test(v.address) && word2.test(v.runtimeCodeHash)
2603
+ ))
2604
+ throw new Error("invalid benchmark runtime identity");
2605
+ if (p.source.toolchain && (!["solidity", "barretenberg", "noir", "evmVersion", "anvil"].every((key) => {
2606
+ const v = p.source.toolchain[key];
2607
+ return typeof v === "string" && v.length > 0;
2608
+ }) || !Number.isSafeInteger(p.source.toolchain.optimizerRuns) || p.source.toolchain.optimizerRuns < 0))
2609
+ throw new Error("invalid benchmark toolchain");
1947
2610
  for (const m of p.measurements) {
1948
2611
  if (!m.id || !m.samples.length || !["none", "caller", "signature"].includes(m.shape.funding) || typeof m.shape.permit !== "boolean")
1949
2612
  throw new Error("invalid gas benchmark measurement");
@@ -2023,11 +2686,20 @@ function estimateBenchmarkGas(plan, protocol, profiles) {
2023
2686
  );
2024
2687
  if (!request.deployment.runtimeCodeHash || !candidates.length)
2025
2688
  return { ...base, available: false, reason: "deployment-not-covered" };
2026
- for (const profile of candidates) {
2027
- const measurement = profile.measurements.find(
2689
+ const exact = candidates.flatMap(
2690
+ (profile) => profile.measurements.filter(
2028
2691
  (m) => shapeKeys.every((key) => m.shape[key] === request.shape[key]) && sameCircuit(m.circuit, request.circuit)
2029
- );
2030
- if (!measurement) continue;
2692
+ ).map((measurement) => ({ profile, measurement }))
2693
+ );
2694
+ const mean = (measurement) => {
2695
+ const count = BigInt(measurement.samples.length);
2696
+ return (measurement.samples.reduce((sum, s) => sum + BigInt(s.gasUsed), 0n) + count - 1n) / count;
2697
+ };
2698
+ exact.sort(
2699
+ (a, b) => mean(a.measurement) > mean(b.measurement) ? -1 : mean(a.measurement) < mean(b.measurement) ? 1 : a.measurement.id.localeCompare(b.measurement.id)
2700
+ );
2701
+ if (exact.length) {
2702
+ const { profile, measurement } = exact[0];
2031
2703
  const gas = measurement.samples.map((sample) => BigInt(sample.gasUsed));
2032
2704
  const count = BigInt(gas.length);
2033
2705
  return {
@@ -2057,14 +2729,20 @@ function estimateShapeGas(request, profiles = defaultProfiles) {
2057
2729
  const matching = measurements.filter(
2058
2730
  (measurement) => measurement.shape.kind === request.shape.kind && measurement.shape.target === request.shape.target && sameCircuit(measurement.circuit, request.circuit)
2059
2731
  );
2060
- const exact = matching.find(
2732
+ const exact = matching.filter(
2061
2733
  (measurement) => shapeKeys.every((key) => measurement.shape[key] === request.shape[key])
2062
2734
  );
2063
- if (exact) {
2064
- const gas = exact.samples.map((sample) => BigInt(sample.gasUsed));
2065
- const count = BigInt(gas.length);
2066
- return { gasUnits: (gas.reduce((sum, value) => sum + value, 0n) + count - 1n) / count };
2735
+ if (exact.length) {
2736
+ const means = exact.map((m) => {
2737
+ const count = BigInt(m.samples.length);
2738
+ return (m.samples.reduce((sum, s) => sum + BigInt(s.gasUsed), 0n) + count - 1n) / count;
2739
+ });
2740
+ return { gasUnits: means.reduce((max, v) => v > max ? v : max) };
2067
2741
  }
2742
+ if (["create-credit", "draw-credit", "top-up-credit", "cancel-credit"].includes(
2743
+ request.shape.kind
2744
+ ) && !matching.length)
2745
+ throw new Error("No current Credit gas reference for this artifact and verification key");
2068
2746
  const candidates = matching.length ? matching : measurements.filter(
2069
2747
  (measurement) => measurement.shape.kind === request.shape.kind && measurement.shape.target === request.shape.target
2070
2748
  );
@@ -2079,7 +2757,22 @@ function estimateShapeGas(request, profiles = defaultProfiles) {
2079
2757
  "deliveryBytes",
2080
2758
  ...!matching.length ? ["capacity"] : []
2081
2759
  ];
2082
- const estimates = candidates.map((measurement) => {
2760
+ const groups = /* @__PURE__ */ new Map();
2761
+ for (const candidate of candidates) {
2762
+ const key = JSON.stringify([
2763
+ shapeKeys.map((k) => candidate.shape[k]),
2764
+ candidate.circuit?.circuitName,
2765
+ candidate.circuit?.target,
2766
+ candidate.circuit?.artifactSha256.toLowerCase(),
2767
+ candidate.circuit?.vkSha256.toLowerCase()
2768
+ ]);
2769
+ const previous = groups.get(key);
2770
+ groups.set(
2771
+ key,
2772
+ previous ? { ...candidate, samples: [...previous.samples, ...candidate.samples] } : candidate
2773
+ );
2774
+ }
2775
+ const estimates = [...groups.values()].map((measurement) => {
2083
2776
  let numerator = 1n;
2084
2777
  let denominator = 1n;
2085
2778
  for (const key of dimensions) {
@@ -2110,7 +2803,8 @@ function estimateGasReference(plan, protocol, profiles) {
2110
2803
 
2111
2804
  // src/session/operation-execution.ts
2112
2805
  var import_ethers6 = require("ethers");
2113
- var import_core3 = require("@invisi-labs/core");
2806
+ var import_core5 = require("@invisi-labs/core");
2807
+ var import_protocol3 = require("@invisi-labs/protocol");
2114
2808
 
2115
2809
  // src/session/proof-integrity.ts
2116
2810
  var import_ethers5 = require("ethers");
@@ -2139,23 +2833,41 @@ async function authorizeOperation(plan, provider) {
2139
2833
  if (provider.walletIdentity !== plan.scope.walletIdentity)
2140
2834
  throw new Error("wallet authorization capability mismatch");
2141
2835
  const request = authorizationRequest(plan);
2142
- const digest = (0, import_core3.computeWalletAuthorizationDigest)(request);
2836
+ const digest = (0, import_core5.computeWalletAuthorizationDigest)(request);
2143
2837
  const signed = await provider.authorize(structuredClone(request));
2144
2838
  if (signed.walletIdentity !== plan.scope.walletIdentity || signed.digest !== digest)
2145
2839
  throw new Error("wallet authorization statement mismatch");
2146
2840
  return signed;
2147
2841
  }
2148
2842
  async function proveOperation(protocol, plan, authorization, prover, options) {
2843
+ if (Object.hasOwn(options, "target")) {
2844
+ throw new Error("prove accepts execution, not a backend target");
2845
+ }
2846
+ const { execution = "single", ...proverOptions } = options;
2847
+ if (execution !== "single" && execution !== "aggregate") {
2848
+ throw new Error("execution must be single or aggregate");
2849
+ }
2850
+ const frozen = statement(plan);
2851
+ if (execution === "aggregate" && (plan.kind !== "transfer" || plan.capacity !== 14)) {
2852
+ throw new Error("aggregate execution requires a 14-slot transfer");
2853
+ }
2854
+ if (plan.kind === "transfer") {
2855
+ plan.statement = import_protocol3.WitnessBuilder.statement(
2856
+ frozen.circuitName,
2857
+ frozen.expectedPublicInputs,
2858
+ execution === "aggregate" ? "noir-recursive" : "evm"
2859
+ );
2860
+ }
2149
2861
  const request = await witnessFor(protocol, plan, authorization);
2150
2862
  if (JSON.stringify({ ...request, witness: void 0 }) !== JSON.stringify(plan.statement))
2151
2863
  throw new Error("prepared proof statement changed");
2152
2864
  try {
2153
- const proof = publicProof(await prover.prove(request, options));
2865
+ const proof = publicProof(await prover.prove(request, proverOptions));
2154
2866
  sameStatement(proof, plan.statement);
2155
2867
  if (await prover.verify(
2156
2868
  structuredClone(proof),
2157
2869
  structuredClone(plan.statement),
2158
- options
2870
+ proverOptions
2159
2871
  ) !== true)
2160
2872
  throw new Error("proof verification failed");
2161
2873
  return proof;
@@ -2170,19 +2882,88 @@ async function signOperationFunding(saved, signer, verifier) {
2170
2882
  throw new Error("funding signer is not the payer");
2171
2883
  const typed = await fundingTypedData(saved);
2172
2884
  const signature = await signer.signTypedData(structuredClone(typed));
2885
+ return verifyFundingSignature(typed, payer, signature, verifier);
2886
+ }
2887
+ function walletSigningRequest(plan) {
2888
+ return (0, import_core5.createSigningRequest)((0, import_core5.walletAuthorizationTypedData)(authorizationRequest(plan)));
2889
+ }
2890
+ async function acceptWalletSignature(plan, signature) {
2891
+ const request = authorizationRequest(plan);
2892
+ const digest = (0, import_core5.computeWalletAuthorizationDigest)(request);
2893
+ try {
2894
+ const signed = import_ethers6.Signature.from(signature);
2895
+ const publicKey = (0, import_ethers6.getBytes)(import_ethers6.SigningKey.recoverPublicKey(digest, signed));
2896
+ const owner = await (0, import_core5.computeWalletIdentity)(publicKey);
2897
+ if (owner.toLowerCase() !== plan.scope.walletIdentity.toLowerCase()) {
2898
+ throw new Error("wallet signature identity mismatch");
2899
+ }
2900
+ return new import_core5.AuthorizedStatement(plan.scope.walletIdentity, digest, {
2901
+ public_key_x: Array.from(publicKey.slice(1, 33)),
2902
+ public_key_y: Array.from(publicKey.slice(33)),
2903
+ signature: Array.from((0, import_ethers6.getBytes)((0, import_ethers6.concat)([signed.r, signed.s])))
2904
+ });
2905
+ } catch {
2906
+ throw new Error("invalid wallet authorization signature");
2907
+ }
2908
+ }
2909
+ async function fundingSigningRequest(saved, runtime) {
2910
+ const plan = saved.plan;
2911
+ if (plan.fundingMode !== "signature") {
2912
+ throw new Error("operation does not require a funding signature");
2913
+ }
2914
+ if (plan.kind !== "shield" && !saved.proof) {
2915
+ throw new Error("proof must precede funding authorization");
2916
+ }
2917
+ await runtime.options.protocol.validateDeployment(runtime.reader);
2918
+ const block = await runtime.reader.getBlock(await runtime.reader.getLatestBlockNumber());
2919
+ if (block.timestamp > plan.deadline || block.timestamp > (plan.funding.deadline ?? 0n)) {
2920
+ throw new Error("funding authorization expired");
2921
+ }
2922
+ if (await runtime.reader.getFundingNonce(plan.context, plan.funding.payer, block) !== plan.funding.sigNonce) {
2923
+ throw new Error("funding nonce changed; prepare again");
2924
+ }
2925
+ const request = (0, import_core5.createSigningRequest)(await fundingTypedData(saved));
2926
+ if ((await runtime.reader.getBlock(block.number)).hash !== block.hash) {
2927
+ throw new Error("canonical funding block changed");
2928
+ }
2929
+ return request;
2930
+ }
2931
+ async function acceptFundingSignature(saved, signature, runtime) {
2932
+ if (!/^0x(?:[a-fA-F0-9]{2})+$/.test(signature)) {
2933
+ throw new Error("invalid EVM funding signature");
2934
+ }
2935
+ const request = await fundingSigningRequest(saved, runtime);
2936
+ return verifyFundingSignature(
2937
+ request,
2938
+ saved.plan.funding.payer,
2939
+ signature,
2940
+ runtime.options.fundingVerifier
2941
+ );
2942
+ }
2943
+ async function verifyFundingSignature(request, payer, signature, verifier) {
2944
+ if (!/^0x(?:[a-fA-F0-9]{2})+$/.test(signature)) {
2945
+ throw new Error("invalid EVM funding signature");
2946
+ }
2947
+ const types = Object.fromEntries(
2948
+ Object.entries(request.types).map(([name, fields]) => [name, [...fields]])
2949
+ );
2950
+ let validEOA = false;
2951
+ try {
2952
+ validEOA = (0, import_ethers6.verifyTypedData)(request.domain, types, request.message, signature).toLowerCase() === payer.toLowerCase();
2953
+ if (validEOA) {
2954
+ signature = import_ethers6.Signature.from(signature).serialized;
2955
+ }
2956
+ } catch {
2957
+ validEOA = false;
2958
+ }
2173
2959
  const valid = verifier ? await verifier.verifyTypedData({
2174
- ...structuredClone(typed),
2960
+ ...structuredClone(request),
2175
2961
  address: payer,
2176
2962
  signature
2177
- }) : (0, import_ethers6.verifyTypedData)(
2178
- typed.domain,
2179
- Object.fromEntries(
2180
- Object.entries(typed.types).map(([name, fields]) => [name, [...fields]])
2181
- ),
2182
- typed.message,
2183
- signature
2184
- ).toLowerCase() === payer.toLowerCase();
2185
- if (valid !== true) throw new Error("invalid EVM funding signature");
2963
+ }) : validEOA;
2964
+ if (valid !== true) {
2965
+ throw new Error("invalid EVM funding signature");
2966
+ }
2186
2967
  return signature;
2187
2968
  }
2188
2969
 
@@ -2223,16 +3004,16 @@ function operationPreview(plan, status) {
2223
3004
  }
2224
3005
 
2225
3006
  // src/session/Operation.ts
2226
- var import_core7 = require("@invisi-labs/core");
2227
- var import_protocol4 = require("@invisi-labs/protocol");
3007
+ var import_core9 = require("@invisi-labs/core");
3008
+ var import_protocol5 = require("@invisi-labs/protocol");
2228
3009
 
2229
3010
  // src/session/operation-confirmation.ts
2230
- var import_core6 = require("@invisi-labs/core");
3011
+ var import_core8 = require("@invisi-labs/core");
2231
3012
 
2232
3013
  // src/session/aggregate-receipt.ts
2233
3014
  var import_ethers7 = require("ethers");
2234
3015
  var import_contracts3 = require("@invisi-labs/protocol/contracts");
2235
- var import_protocol3 = require("@invisi-labs/protocol");
3016
+ var import_protocol4 = require("@invisi-labs/protocol");
2236
3017
  var aggregateAbi = import_contracts3.invisiProtocolAbi.filter(
2237
3018
  (item) => item.type === "function" && item.name === "transact" && item.inputs.length === 2 && item.inputs[1]?.type === "tuple[]"
2238
3019
  );
@@ -2260,7 +3041,7 @@ function matchesAggregateTransaction(saved, transaction) {
2260
3041
  });
2261
3042
  if (decoded.name !== "transact" || !Array.isArray(requests) || ![4, 8, 12].includes(requests.length))
2262
3043
  return false;
2263
- const canonical2 = (request) => (0, import_protocol3.buildTransactCalldata)({
3044
+ const canonical2 = (request) => (0, import_protocol4.buildTransactCalldata)({
2264
3045
  context: { ...plan.context, tokenAddress: request.params.token },
2265
3046
  proof: "0x00",
2266
3047
  params: request.params,
@@ -2268,7 +3049,7 @@ function matchesAggregateTransaction(saved, transaction) {
2268
3049
  funding: request.funding,
2269
3050
  caller: transaction.from
2270
3051
  }).data.toLowerCase();
2271
- const expected = (0, import_protocol3.buildTransactCalldata)({
3052
+ const expected = (0, import_protocol4.buildTransactCalldata)({
2272
3053
  context: plan.context,
2273
3054
  proof: "0x00",
2274
3055
  params: plan.params,
@@ -2283,10 +3064,10 @@ function matchesAggregateTransaction(saved, transaction) {
2283
3064
  }
2284
3065
 
2285
3066
  // src/session/credit-values.ts
2286
- var import_core4 = require("@invisi-labs/core");
3067
+ var import_core6 = require("@invisi-labs/core");
2287
3068
  async function creditLeaf(state) {
2288
3069
  const n = state.note;
2289
- return (0, import_core4.computeCreditCommitment)(
3070
+ return (0, import_core6.computeCreditCommitment)(
2290
3071
  n.chainId,
2291
3072
  n.spenderWalletIdentity,
2292
3073
  n.ownerWalletIdentity,
@@ -2296,22 +3077,23 @@ async function creditLeaf(state) {
2296
3077
  n.amount,
2297
3078
  n.nonce,
2298
3079
  n.expiry,
2299
- await (0, import_core4.computeCreditSharedKeyHash)(n.creditSharedKey)
3080
+ await (0, import_core6.computeCreditSharedKeyHash)(n.creditSharedKey),
3081
+ n
2300
3082
  );
2301
3083
  }
2302
3084
 
2303
3085
  // src/session/membership.ts
2304
- var import_core5 = require("@invisi-labs/core");
3086
+ var import_core7 = require("@invisi-labs/core");
2305
3087
  async function verifyMembership(reader, context, block, input, proof) {
2306
3088
  if (proof.block.hash !== block.hash || proof.block.number !== block.number || proof.leaf !== input.commitment || proof.treeId !== input.treeId || proof.leafIndex !== input.leafIndex || proof.path.length !== 16 || !Number.isInteger(input.leafIndex) || input.leafIndex < 0 || input.leafIndex >= 65536 || !await reader.isKnownRoot(context, input.treeId, proof.root, block))
2307
3089
  throw new Error("membership context/root mismatch");
2308
3090
  let root = BigInt(input.commitment);
2309
3091
  for (let i = 0; i < 16; i++) {
2310
3092
  const sibling = proof.path[i];
2311
- if (typeof sibling !== "bigint" || sibling < 0n || sibling >= import_core5.FIELD_MODULUS)
3093
+ if (typeof sibling !== "bigint" || sibling < 0n || sibling >= import_core7.FIELD_MODULUS)
2312
3094
  throw new Error("noncanonical membership path");
2313
3095
  root = BigInt(
2314
- await (0, import_core5.poseidonHash)(input.leafIndex >> i & 1 ? [sibling, root] : [root, sibling])
3096
+ await (0, import_core7.poseidonHash)(input.leafIndex >> i & 1 ? [sibling, root] : [root, sibling])
2315
3097
  );
2316
3098
  }
2317
3099
  if (root !== BigInt(proof.root))
@@ -2483,7 +3265,7 @@ async function confirmOperation(runtime, id, generation, hash2, signal) {
2483
3265
  if (credits.length) {
2484
3266
  const nullifiers = await Promise.all(
2485
3267
  credits.map(
2486
- async (record) => (0, import_core6.computeCreditNullifier)(
3268
+ async (record) => (0, import_core8.computeCreditNullifier)(
2487
3269
  plan.context.chainId,
2488
3270
  record.state.note.creditSharedKey,
2489
3271
  await creditLeaf(record.state)
@@ -2784,6 +3566,81 @@ var Operation = class _Operation {
2784
3566
  throw error;
2785
3567
  }
2786
3568
  }
3569
+ async signingCurrent() {
3570
+ await this.#runtime.store.transaction(this.#runtime.scope, (state) => {
3571
+ check6(!state.invalidated, "wallet state requires canonical resync");
3572
+ this.current(state.operations[this.id]);
3573
+ });
3574
+ }
3575
+ /** Public EIP-712 request; signing transport and key custody belong to the caller. */
3576
+ async exportWalletAuthorization(options = {}) {
3577
+ options.signal?.throwIfAborted();
3578
+ await this.signingCurrent();
3579
+ check6(
3580
+ requiresAuthorization(this.#saved.plan),
3581
+ "operation does not require wallet authorization"
3582
+ );
3583
+ check6(
3584
+ ["prepared", "authorized"].includes(this.status),
3585
+ "operation is not awaiting wallet authorization"
3586
+ );
3587
+ return walletSigningRequest(this.#saved.plan);
3588
+ }
3589
+ /** Attach an external EOA signature, retaining its witness only at the private proving boundary. */
3590
+ async withWalletSignature(signature, options = {}) {
3591
+ options.signal?.throwIfAborted();
3592
+ await this.signingCurrent();
3593
+ check6(
3594
+ requiresAuthorization(this.#saved.plan),
3595
+ "operation does not require wallet authorization"
3596
+ );
3597
+ check6(
3598
+ ["prepared", "authorized"].includes(this.status),
3599
+ "operation is not awaiting wallet authorization"
3600
+ );
3601
+ const authorization = await acceptWalletSignature(this.#saved.plan, signature);
3602
+ return this.stage(
3603
+ "wallet authorization",
3604
+ ["prepared", "authorized"],
3605
+ async () => ({ status: "authorized", authorization }),
3606
+ options.signal
3607
+ );
3608
+ }
3609
+ /** Export only after proving when the funding authorization binds an actual proof hash. */
3610
+ async exportFundingAuthorization(options = {}) {
3611
+ options.signal?.throwIfAborted();
3612
+ await this.signingCurrent();
3613
+ check6(
3614
+ this.status === (this.kind === "shield" ? "prepared" : "proved"),
3615
+ "operation is not awaiting funding authorization or proof"
3616
+ );
3617
+ const request = await fundingSigningRequest(this.#saved, this.#runtime);
3618
+ options.signal?.throwIfAborted();
3619
+ await this.signingCurrent();
3620
+ return request;
3621
+ }
3622
+ /** Verify an external signature against this handle's own frozen operation. */
3623
+ async withFundingSignature(signature, options = {}) {
3624
+ options.signal?.throwIfAborted();
3625
+ await this.signingCurrent();
3626
+ check6(
3627
+ this.status === (this.kind === "shield" ? "prepared" : "proved"),
3628
+ "operation is not awaiting funding authorization or proof"
3629
+ );
3630
+ const verified = await acceptFundingSignature(this.#saved, signature, this.#runtime);
3631
+ return this.stage(
3632
+ "funding authorization",
3633
+ this.kind === "shield" ? ["prepared"] : ["proved"],
3634
+ async (saved) => {
3635
+ saved.plan.funding.signature = verified;
3636
+ if (saved.plan.statement?.target !== "noir-recursive") {
3637
+ saved.call = await this.encode(saved);
3638
+ }
3639
+ return { status: "ready" };
3640
+ },
3641
+ options.signal
3642
+ );
3643
+ }
2787
3644
  async authorize(options = {}) {
2788
3645
  check6(
2789
3646
  requiresAuthorization(this.#saved.plan),
@@ -2804,7 +3661,8 @@ var Operation = class _Operation {
2804
3661
  options.signal
2805
3662
  );
2806
3663
  }
2807
- async prove(options = {}) {
3664
+ async prove(suppliedOptions = {}) {
3665
+ const options = { ...suppliedOptions };
2808
3666
  const plan = this.#saved.plan;
2809
3667
  check6(plan.kind !== "shield", "shield requires no proof");
2810
3668
  if (requiresAuthorization(plan)) {
@@ -2815,7 +3673,7 @@ var Operation = class _Operation {
2815
3673
  }
2816
3674
  const prover = this.#runtime.options.prover;
2817
3675
  if (!prover) {
2818
- throw new import_core7.MissingCapabilityError("prover");
3676
+ throw new import_core9.MissingCapabilityError("prover");
2819
3677
  }
2820
3678
  return this.stage(
2821
3679
  "proof",
@@ -2849,7 +3707,7 @@ var Operation = class _Operation {
2849
3707
  check6(p.kind === "shield" || this.#saved.proof, "proof must precede funding authorization");
2850
3708
  const signer = this.#runtime.options.fundingSigner;
2851
3709
  if (!signer) {
2852
- throw new import_core7.MissingCapabilityError("EVM funding signer");
3710
+ throw new import_core9.MissingCapabilityError("EVM funding signer");
2853
3711
  }
2854
3712
  check6(
2855
3713
  signer.address.toLowerCase() === p.funding.payer.toLowerCase(),
@@ -2951,7 +3809,7 @@ var Operation = class _Operation {
2951
3809
  request: {
2952
3810
  params: structuredClone(plan.params),
2953
3811
  deliveries: plan.outputs.map((output) => structuredClone(output.delivery)),
2954
- funding: (0, import_protocol4.normalizeFunding)(plan.funding)
3812
+ funding: (0, import_protocol5.normalizeFunding)(plan.funding)
2955
3813
  }
2956
3814
  };
2957
3815
  });
@@ -3038,18 +3896,181 @@ var Operation = class _Operation {
3038
3896
  }
3039
3897
  };
3040
3898
 
3899
+ // src/session/WalletSession.ts
3900
+ var import_core16 = require("@invisi-labs/core");
3901
+
3902
+ // src/session/history.ts
3903
+ function walletHistory(state, options = {}) {
3904
+ const token = options.tokenAddress?.toLowerCase();
3905
+ const outgoing = [];
3906
+ for (const record of Object.values(state.operations)) {
3907
+ const saved = record.payload;
3908
+ if (!saved?.plan || token && saved.plan.context.tokenAddress.toLowerCase() !== token) {
3909
+ continue;
3910
+ }
3911
+ const plan = saved.plan;
3912
+ outgoing.push({
3913
+ ...operationPreview(plan, record.status),
3914
+ preparedAt: { ...plan.preparedAt },
3915
+ ...record.transactionHash ? { transactionHash: record.transactionHash } : {},
3916
+ outputs: plan.outputs.map((output) => ({
3917
+ to: output.address,
3918
+ amount: output.note.amount,
3919
+ change: output.change,
3920
+ commitment: output.commitment,
3921
+ payload: Uint8Array.from(output.note.payload ?? [])
3922
+ }))
3923
+ });
3924
+ }
3925
+ outgoing.sort(
3926
+ (a, b) => a.preparedAt.number === b.preparedAt.number ? a.id.localeCompare(b.id) : a.preparedAt.number > b.preparedAt.number ? -1 : 1
3927
+ );
3928
+ const incoming = [];
3929
+ for (const record of Object.values(state.notes)) {
3930
+ const tokenAddress = `0x${record.note.tokenAddress.toString(16).padStart(40, "0")}`;
3931
+ if (token && tokenAddress !== token) continue;
3932
+ incoming.push({
3933
+ commitment: record.commitment,
3934
+ treeId: record.treeId,
3935
+ leafIndex: record.leafIndex,
3936
+ blockNumber: record.blockNumber,
3937
+ blockHash: record.blockHash,
3938
+ ...record.transactionHash ? { transactionHash: record.transactionHash } : {},
3939
+ tokenAddress,
3940
+ amount: record.note.amount,
3941
+ payload: Uint8Array.from(record.note.payload ?? []),
3942
+ spent: record.spent
3943
+ });
3944
+ }
3945
+ incoming.sort(
3946
+ (a, b) => a.blockNumber === b.blockNumber ? a.commitment.localeCompare(b.commitment) : a.blockNumber > b.blockNumber ? -1 : 1
3947
+ );
3948
+ return structuredClone({
3949
+ revision: state.revision,
3950
+ checkedThrough: state.discoveryThrough ?? null,
3951
+ invalidated: !!state.invalidated,
3952
+ outgoing,
3953
+ incoming
3954
+ });
3955
+ }
3956
+
3957
+ // src/errors.ts
3958
+ var import_core10 = require("@invisi-labs/core");
3959
+ var InvisiError = class extends Error {
3960
+ code;
3961
+ operation;
3962
+ address;
3963
+ outputIndex;
3964
+ field;
3965
+ capability;
3966
+ constructor(code, message, details = {}) {
3967
+ super(message, { cause: details.cause });
3968
+ this.name = "InvisiError";
3969
+ this.code = code;
3970
+ this.operation = details.operation;
3971
+ this.address = details.address;
3972
+ this.outputIndex = details.outputIndex;
3973
+ this.field = details.field;
3974
+ this.capability = details.capability;
3975
+ }
3976
+ };
3977
+ async function prepareWithErrors(operation, prepare) {
3978
+ try {
3979
+ return await prepare();
3980
+ } catch (cause) {
3981
+ if (cause instanceof InvisiError) {
3982
+ if (cause.operation) throw cause;
3983
+ throw new InvisiError(cause.code, cause.message, {
3984
+ operation,
3985
+ ...cause.address === void 0 ? {} : { address: cause.address },
3986
+ ...cause.outputIndex === void 0 ? {} : { outputIndex: cause.outputIndex },
3987
+ ...cause.field === void 0 ? {} : { field: cause.field },
3988
+ ...cause.capability === void 0 ? {} : { capability: cause.capability },
3989
+ cause: cause.cause
3990
+ });
3991
+ }
3992
+ throw new InvisiError(
3993
+ cause instanceof import_core10.MissingCapabilityError ? "MISSING_CAPABILITY" : "PREPARATION_FAILED",
3994
+ cause instanceof Error ? cause.message : "Transaction preparation failed",
3995
+ {
3996
+ operation,
3997
+ cause,
3998
+ ...cause instanceof import_core10.MissingCapabilityError ? { capability: cause.capability } : {}
3999
+ }
4000
+ );
4001
+ }
4002
+ }
4003
+
3041
4004
  // src/session/WalletSession.ts
3042
4005
  var import_ethers11 = require("ethers");
3043
- var import_core12 = require("@invisi-labs/core");
4006
+ var import_core17 = require("@invisi-labs/core");
3044
4007
 
3045
4008
  // src/session/transaction-preparation.ts
3046
4009
  var import_ethers10 = require("ethers");
3047
- var import_protocol7 = require("@invisi-labs/protocol");
4010
+ var import_protocol8 = require("@invisi-labs/protocol");
4011
+
4012
+ // src/resolve-recipient.ts
4013
+ var import_core11 = require("@invisi-labs/core");
4014
+ async function resolveRecipient(address2, lookup, details = {}) {
4015
+ const context = { ...details, address: address2 };
4016
+ let recipient;
4017
+ try {
4018
+ recipient = import_core11.ReceivingAddress.parse(address2);
4019
+ } catch (cause) {
4020
+ throw new InvisiError("INVALID_RECIPIENT", "Invalid recipient address", {
4021
+ ...context,
4022
+ cause
4023
+ });
4024
+ }
4025
+ if (recipient.kind === "long") return recipient;
4026
+ if (!lookup) {
4027
+ throw new InvisiError("MISSING_CAPABILITY", "Missing registry lookup capability", {
4028
+ ...context,
4029
+ capability: "registry lookup"
4030
+ });
4031
+ }
4032
+ let keys;
4033
+ try {
4034
+ keys = await lookup(recipient.walletIdentity);
4035
+ } catch (cause) {
4036
+ if (cause instanceof import_core11.MissingCapabilityError) {
4037
+ throw new InvisiError("MISSING_CAPABILITY", cause.message, {
4038
+ ...context,
4039
+ cause,
4040
+ capability: cause.capability
4041
+ });
4042
+ }
4043
+ throw new InvisiError("RECIPIENT_LOOKUP_FAILED", "Recipient registry lookup failed", {
4044
+ ...context,
4045
+ cause
4046
+ });
4047
+ }
4048
+ if (keys == null) {
4049
+ throw new InvisiError(
4050
+ "EVM_ADDRESS_NOT_REGISTERED",
4051
+ "EVM address has no registered receiving keys",
4052
+ context
4053
+ );
4054
+ }
4055
+ try {
4056
+ return import_core11.ReceivingAddress.from({
4057
+ walletIdentity: recipient.walletIdentity,
4058
+ viewingPublicKey: keys.viewingPublicKey,
4059
+ clueKey: keys.clueKey
4060
+ });
4061
+ } catch (cause) {
4062
+ throw new InvisiError(
4063
+ "RECIPIENT_LOOKUP_FAILED",
4064
+ "Registry returned invalid receiving keys",
4065
+ { ...context, cause }
4066
+ );
4067
+ }
4068
+ }
3048
4069
 
3049
4070
  // src/session/prepare-common.ts
3050
4071
  var import_ethers8 = require("ethers");
3051
- var import_core8 = require("@invisi-labs/core");
3052
- var import_protocol5 = require("@invisi-labs/protocol");
4072
+ var import_core12 = require("@invisi-labs/core");
4073
+ var import_protocol6 = require("@invisi-labs/protocol");
3053
4074
 
3054
4075
  // src/session/selection.ts
3055
4076
  function selectNotes(notes, target, reserved) {
@@ -3082,6 +4103,27 @@ function positiveAmount(value, bits = 128) {
3082
4103
  }
3083
4104
  return value;
3084
4105
  }
4106
+ function copyApplicationPayload(value) {
4107
+ if (value === void 0) return new Uint8Array();
4108
+ if (!(value instanceof Uint8Array)) throw new TypeError("payload must be Uint8Array");
4109
+ return Uint8Array.from(value);
4110
+ }
4111
+ function positiveOutputAmount(payment, outputIndex) {
4112
+ try {
4113
+ return positiveAmount(payment.amount);
4114
+ } catch (cause) {
4115
+ throw new InvisiError(
4116
+ "PREPARATION_FAILED",
4117
+ cause instanceof Error ? cause.message : "Invalid output amount",
4118
+ {
4119
+ address: payment.to,
4120
+ field: "amount",
4121
+ ...outputIndex === void 0 ? {} : { outputIndex },
4122
+ cause
4123
+ }
4124
+ );
4125
+ }
4126
+ }
3085
4127
  var Preparation = class {
3086
4128
  constructor(runtime) {
3087
4129
  this.runtime = runtime;
@@ -3104,7 +4146,15 @@ var Preparation = class {
3104
4146
  throw new Error("canonical wallet checkpoint changed; resync required");
3105
4147
  }
3106
4148
  }
3107
- return { context: { ...options.protocol.context, now: block.timestamp }, block, deadline };
4149
+ return {
4150
+ context: {
4151
+ ...options.protocol.context,
4152
+ now: block.timestamp,
4153
+ timestamp: block.timestamp
4154
+ },
4155
+ block,
4156
+ deadline
4157
+ };
3108
4158
  }
3109
4159
  async assertBlock(frame) {
3110
4160
  if ((await this.runtime.reader.getBlock(frame.block.number)).hash !== frame.block.hash) {
@@ -3127,7 +4177,7 @@ var Preparation = class {
3127
4177
  if (mode === "caller" && (source.sigNonce || source.deadline)) {
3128
4178
  throw new Error("caller funding uses zero nonce/deadline");
3129
4179
  }
3130
- const funding = (0, import_protocol5.normalizeFunding)({
4180
+ const funding = (0, import_protocol6.normalizeFunding)({
3131
4181
  payer,
3132
4182
  amount: source.amount,
3133
4183
  sigNonce: mode === "caller" ? 0n : source.sigNonce ?? await this.runtime.reader.getFundingNonce(
@@ -3143,52 +4193,70 @@ var Preparation = class {
3143
4193
  }
3144
4194
  return { funding, fundingMode: mode };
3145
4195
  }
3146
- async output(payment, context, change = false) {
3147
- positiveAmount(payment.amount);
3148
- const recipient = await import_core8.ReceivingAddress.parse(payment.to).resolve(
3149
- this.runtime.options.addressResolver
3150
- );
3151
- const memo = (0, import_core8.encodeMemo)(payment.memo);
3152
- const nonce = (0, import_core8.generateNonce)();
3153
- const identity = await (0, import_core8.computeNoteIdentity)(BigInt(recipient.walletIdentity), nonce);
3154
- const keys = recipient.getReceivingKeys();
3155
- const note = {
3156
- chainId: context.chainId,
3157
- protocolAddress: BigInt(context.protocolAddress),
3158
- tokenAddress: BigInt(context.tokenAddress),
3159
- walletIdentity: recipient.walletIdentity,
3160
- amount: payment.amount,
3161
- ...memo.length === 0 ? {} : { memo },
3162
- nonce
3163
- };
3164
- const commitment = await (0, import_core8.computeNoteCommitment)(
3165
- context.chainId,
3166
- identity,
3167
- note.tokenAddress,
3168
- note.amount
3169
- );
3170
- return {
3171
- note,
3172
- commitment,
3173
- identity,
3174
- address: payment.to,
3175
- change,
3176
- delivery: {
3177
- ciphertext: (0, import_ethers8.hexlify)(
3178
- await (0, import_core8.encryptPrivateTransferNote)(keys.viewingPublicKey, note, {
3179
- chainId: context.chainId,
3180
- protocolAddress: note.protocolAddress,
3181
- outputCommitment: commitment
3182
- })
3183
- ),
3184
- clue: (0, import_ethers8.hexlify)((0, import_core8.createClue)(keys.clueKey))
3185
- }
3186
- };
4196
+ async output(payment, context, change = false, outputIndex) {
4197
+ try {
4198
+ positiveOutputAmount(payment, outputIndex);
4199
+ const recipient = await resolveRecipient(
4200
+ payment.to,
4201
+ this.runtime.options.addressResolver,
4202
+ {
4203
+ field: change ? "changeAddress" : "to",
4204
+ ...outputIndex === void 0 ? {} : { outputIndex }
4205
+ }
4206
+ );
4207
+ const nonce = (0, import_core12.generateNonce)();
4208
+ const identity = await (0, import_core12.computeNoteIdentity)(BigInt(recipient.walletIdentity), nonce);
4209
+ const keys = recipient.getReceivingKeys();
4210
+ const note = {
4211
+ chainId: context.chainId,
4212
+ protocolAddress: BigInt(context.protocolAddress),
4213
+ tokenAddress: BigInt(context.tokenAddress),
4214
+ walletIdentity: recipient.walletIdentity,
4215
+ amount: payment.amount,
4216
+ payload: copyApplicationPayload(payment.payload),
4217
+ nonce
4218
+ };
4219
+ const commitment = await (0, import_core12.computeNoteCommitment)(
4220
+ context.chainId,
4221
+ identity,
4222
+ note.tokenAddress,
4223
+ note.amount
4224
+ );
4225
+ return {
4226
+ note,
4227
+ commitment,
4228
+ identity,
4229
+ address: payment.to,
4230
+ change,
4231
+ delivery: {
4232
+ ciphertext: (0, import_ethers8.hexlify)(
4233
+ await (0, import_core12.encryptPrivateTransferNote)(keys.viewingPublicKey, note, {
4234
+ chainId: context.chainId,
4235
+ protocolAddress: note.protocolAddress,
4236
+ outputCommitment: commitment
4237
+ })
4238
+ ),
4239
+ clue: (0, import_ethers8.hexlify)((0, import_core12.createClue)(keys.clueKey))
4240
+ }
4241
+ };
4242
+ } catch (cause) {
4243
+ if (cause instanceof InvisiError) throw cause;
4244
+ throw new InvisiError(
4245
+ "PREPARATION_FAILED",
4246
+ cause instanceof Error ? cause.message : "Output preparation failed",
4247
+ {
4248
+ address: payment.to,
4249
+ field: change ? "changeAddress" : "to",
4250
+ ...outputIndex === void 0 ? {} : { outputIndex },
4251
+ cause
4252
+ }
4253
+ );
4254
+ }
3187
4255
  }
3188
4256
  async membership(input, frame) {
3189
4257
  const { options, reader } = this.runtime;
3190
4258
  if (!options.protocolRpc)
3191
- throw new import_core8.MissingCapabilityError("Protocol RPC membership provider");
4259
+ throw new import_core12.MissingCapabilityError("Protocol RPC membership provider");
3192
4260
  const root = this.#roots.get(input.treeId);
3193
4261
  const proof = await options.protocolRpc.getMembership(
3194
4262
  frame.context,
@@ -3235,9 +4303,9 @@ var Preparation = class {
3235
4303
  for (const input of selected) {
3236
4304
  const note = input.note;
3237
4305
  const c = frame.context;
3238
- if (note.walletIdentity !== scope.walletIdentity || note.chainId !== c.chainId || note.protocolAddress !== BigInt(c.protocolAddress) || note.tokenAddress !== BigInt(c.tokenAddress) || await (0, import_core8.computeNoteCommitment)(
4306
+ if (note.walletIdentity !== scope.walletIdentity || note.chainId !== c.chainId || note.protocolAddress !== BigInt(c.protocolAddress) || note.tokenAddress !== BigInt(c.tokenAddress) || await (0, import_core12.computeNoteCommitment)(
3239
4307
  c.chainId,
3240
- await (0, import_core8.computeNoteIdentity)(BigInt(note.walletIdentity), note.nonce),
4308
+ await (0, import_core12.computeNoteIdentity)(BigInt(note.walletIdentity), note.nonce),
3241
4309
  note.tokenAddress,
3242
4310
  note.amount
3243
4311
  ) !== input.commitment) {
@@ -3289,8 +4357,8 @@ function storedCandidates(inputs) {
3289
4357
 
3290
4358
  // src/session/prepare-credit.ts
3291
4359
  var import_ethers9 = require("ethers");
3292
- var import_core9 = require("@invisi-labs/core");
3293
- var import_protocol6 = require("@invisi-labs/protocol");
4360
+ var import_core13 = require("@invisi-labs/core");
4361
+ var import_protocol7 = require("@invisi-labs/protocol");
3294
4362
  var EMPTY = { ciphertext: "0x", clue: "0x" };
3295
4363
  var CreditPreparation = class {
3296
4364
  constructor(runtime) {
@@ -3305,7 +4373,7 @@ var CreditPreparation = class {
3305
4373
  return value;
3306
4374
  }
3307
4375
  async seal(input, frame) {
3308
- const state = (0, import_core9.normalizeCreditDeliveryState)(input);
4376
+ const state = (0, import_core13.normalizeCreditDeliveryState)(input);
3309
4377
  const commitment = await creditLeaf(state);
3310
4378
  const context = {
3311
4379
  chainId: frame.context.chainId,
@@ -3317,9 +4385,9 @@ var CreditPreparation = class {
3317
4385
  const keys = role === "owner" ? state.ownerReceivingKeys : state.spenderReceivingKeys;
3318
4386
  return {
3319
4387
  ciphertext: (0, import_ethers9.hexlify)(
3320
- await (0, import_core9.encryptCreditNote)(keys.viewingPublicKey, state, { ...context, role })
4388
+ await (0, import_core13.encryptCreditNote)(keys.viewingPublicKey, state, { ...context, role })
3321
4389
  ),
3322
- clue: (0, import_ethers9.hexlify)((0, import_core9.createClue)(keys.clueKey))
4390
+ clue: (0, import_ethers9.hexlify)((0, import_core13.createClue)(keys.clueKey))
3323
4391
  };
3324
4392
  })
3325
4393
  );
@@ -3330,14 +4398,14 @@ var CreditPreparation = class {
3330
4398
  if (!stored || stored.spent !== "unspent" || stored.role !== role) {
3331
4399
  throw new Error(`confirmed unspent ${role} Credit is unavailable`);
3332
4400
  }
3333
- const state = (0, import_core9.normalizeCreditDeliveryState)(stored.state);
4401
+ const state = (0, import_core13.normalizeCreditDeliveryState)(stored.state);
3334
4402
  const n = state.note;
3335
4403
  if ((role === "owner" ? n.ownerWalletIdentity : n.spenderWalletIdentity) !== this.runtime.scope.walletIdentity || n.chainId !== frame.context.chainId || n.protocolAddress !== BigInt(frame.context.protocolAddress) || n.tokenAddress !== BigInt(frame.context.tokenAddress) || await creditLeaf(state) !== commitment) {
3336
4404
  throw new Error("Credit role, commitment or deployment mismatch");
3337
4405
  }
3338
4406
  const proof = await this.#prepare.membership(stored, frame);
3339
4407
  const path = [...proof.path];
3340
- const nullifier = await (0, import_core9.computeCreditNullifier)(n.chainId, n.creditSharedKey, commitment);
4408
+ const nullifier = await (0, import_core13.computeCreditNullifier)(n.chainId, n.creditSharedKey, commitment);
3341
4409
  await this.#prepare.assertUnspent([nullifier], frame);
3342
4410
  return {
3343
4411
  input: {
@@ -3374,10 +4442,16 @@ var CreditPreparation = class {
3374
4442
  positiveAmount(options.amount, 126);
3375
4443
  const frame = await this.#prepare.frame(options.deadline);
3376
4444
  const expiry = this.expiry(options.expiry, frame);
3377
- const spender = await import_core9.ReceivingAddress.parse(options.spender).resolve(
3378
- this.runtime.options.addressResolver
4445
+ const spender = await resolveRecipient(
4446
+ options.spender,
4447
+ this.runtime.options.addressResolver,
4448
+ { field: "spender" }
4449
+ );
4450
+ const owner = await resolveRecipient(
4451
+ this.runtime.options.wallet.getReceivingAddress().toString(),
4452
+ this.runtime.options.addressResolver,
4453
+ { field: "wallet" }
3379
4454
  );
3380
- const owner = await this.runtime.options.wallet.getReceivingAddress().resolve(this.runtime.options.addressResolver);
3381
4455
  const ownerPayout = (0, import_ethers9.getAddress)(owner.walletIdentity);
3382
4456
  const spenderPayout = (0, import_ethers9.getAddress)(spender.walletIdentity);
3383
4457
  if (BigInt(ownerPayout) === 0n || BigInt(spenderPayout) === 0n) {
@@ -3393,11 +4467,16 @@ var CreditPreparation = class {
3393
4467
  spenderWalletIdentity: spender.walletIdentity,
3394
4468
  ownerPayout: BigInt(ownerPayout),
3395
4469
  spenderPayout: BigInt(spenderPayout),
4470
+ ...(0, import_core13.normalizeCreditPolicy)({
4471
+ singleLimit: options.singleLimit ?? 0n,
4472
+ dailyLimit: options.dailyLimit ?? 0n,
4473
+ monthlyLimit: options.monthlyLimit ?? 0n
4474
+ }),
3396
4475
  amount: options.amount,
3397
- ...options.memo === void 0 ? {} : { memo: options.memo },
4476
+ payload: copyApplicationPayload(options.payload),
3398
4477
  expiry,
3399
- nonce: (0, import_core9.generateNonce)(),
3400
- creditSharedKey: (0, import_core9.generateCreditSharedKey)()
4478
+ nonce: (0, import_core13.generateNonce)(),
4479
+ creditSharedKey: (0, import_core13.generateCreditSharedKey)()
3401
4480
  },
3402
4481
  ownerReceivingKeys: owner.getReceivingKeys(),
3403
4482
  spenderReceivingKeys: spender.getReceivingKeys()
@@ -3439,7 +4518,7 @@ var CreditPreparation = class {
3439
4518
  sources: selected.sources,
3440
4519
  nullifiers: selected.nullifiers,
3441
4520
  creditCommitment: output.commitment,
3442
- changeCommitment: plan.outputs[0]?.commitment ?? (0, import_protocol6.word)(0n),
4521
+ changeCommitment: plan.outputs[0]?.commitment ?? (0, import_protocol7.word)(0n),
3443
4522
  owner: (0, import_ethers9.getAddress)((0, import_ethers9.toBeHex)(output.state.note.ownerPayout, 20)),
3444
4523
  expiry: output.state.note.expiry,
3445
4524
  deadline: frame.deadline
@@ -3459,14 +4538,14 @@ var CreditPreparation = class {
3459
4538
  creditNullifier: previous.nullifier,
3460
4539
  previousExpiry: previous.input.state.note.expiry
3461
4540
  };
3462
- plan.statement = import_protocol6.WitnessBuilder.statement(
4541
+ plan.statement = import_protocol7.WitnessBuilder.statement(
3463
4542
  "credit_top_up",
3464
- (0, import_protocol6.topUpCreditPublicInputs)(frame.context, plan.credit.topUp, deliveries, plan.funding)
4543
+ (0, import_protocol7.topUpCreditPublicInputs)(frame.context, plan.credit.topUp, deliveries, plan.funding)
3465
4544
  );
3466
4545
  } else {
3467
- plan.statement = import_protocol6.WitnessBuilder.statement(
4546
+ plan.statement = import_protocol7.WitnessBuilder.statement(
3468
4547
  "create_credit",
3469
- (0, import_protocol6.createCreditPublicInputs)(frame.context, creation, deliveries, plan.funding)
4548
+ (0, import_protocol7.createCreditPublicInputs)(frame.context, creation, deliveries, plan.funding)
3470
4549
  );
3471
4550
  }
3472
4551
  await this.#prepare.assertBlock(frame);
@@ -3490,10 +4569,15 @@ var CreditPreparation = class {
3490
4569
  ...old,
3491
4570
  note: {
3492
4571
  ...old.note,
4572
+ singleLimit: options.singleLimit ?? old.note.singleLimit ?? 0n,
4573
+ dailyLimit: options.dailyLimit ?? old.note.dailyLimit ?? 0n,
4574
+ monthlyLimit: options.monthlyLimit ?? old.note.monthlyLimit ?? 0n,
3493
4575
  amount,
3494
4576
  expiry,
3495
- nonce: (0, import_core9.generateNonce)(),
3496
- ...options.memo === void 0 ? {} : { memo: options.memo }
4577
+ nonce: (0, import_core13.generateNonce)(),
4578
+ payload: copyApplicationPayload(
4579
+ options.payload === void 0 ? old.note.payload : options.payload
4580
+ )
3497
4581
  }
3498
4582
  },
3499
4583
  frame
@@ -3509,7 +4593,7 @@ var CreditPreparation = class {
3509
4593
  }
3510
4594
  async draw(options) {
3511
4595
  const frame = await this.#prepare.frame(options.deadline);
3512
- const profile = (0, import_protocol6.selectCreditDrawCircuit)(options.credits.length);
4596
+ const profile = (0, import_protocol7.selectCreditDrawCircuit)(options.credits.length);
3513
4597
  if (new Set(options.credits.map((value) => value.credit)).size !== options.credits.length) {
3514
4598
  throw new Error("duplicate Credit input");
3515
4599
  }
@@ -3541,10 +4625,11 @@ var CreditPreparation = class {
3541
4625
  }
3542
4626
  sources.set(member.source.treeId, member.source.merkleRoot);
3543
4627
  amounts.push(amount);
4628
+ const usage = (0, import_core13.applyCreditDrawUsage)(n, amount, frame.block.timestamp);
3544
4629
  const remaining = n.amount - amount;
3545
4630
  if (remaining === 0n) {
3546
- remainders.push((0, import_protocol6.word)(0n));
3547
- recoveryAmounts.push((0, import_protocol6.word)(0n));
4631
+ remainders.push((0, import_protocol7.word)(0n));
4632
+ recoveryAmounts.push((0, import_protocol7.word)(0n));
3548
4633
  deliveries.push({ ...EMPTY }, { ...EMPTY });
3549
4634
  continue;
3550
4635
  }
@@ -3560,9 +4645,12 @@ var CreditPreparation = class {
3560
4645
  ...state,
3561
4646
  note: {
3562
4647
  ...n,
4648
+ ...usage,
3563
4649
  amount: remaining,
3564
- ...options.credits[i].memo === void 0 ? {} : { memo: options.credits[i].memo },
3565
- nonce: await (0, import_core9.deriveRemainderNonce)(...args)
4650
+ payload: copyApplicationPayload(
4651
+ options.credits[i].payload === void 0 ? n.payload : options.credits[i].payload
4652
+ ),
4653
+ nonce: await (0, import_core13.deriveRemainderNonce)(...args)
3566
4654
  }
3567
4655
  },
3568
4656
  frame
@@ -3570,7 +4658,7 @@ var CreditPreparation = class {
3570
4658
  outputs.push(output);
3571
4659
  remainders.push(output.commitment);
3572
4660
  recoveryAmounts.push(
3573
- (0, import_protocol6.word)((remaining + await (0, import_core9.computeCreditRecoveryPad)(...args)) % import_core9.FIELD_MODULUS)
4661
+ (0, import_protocol7.word)((remaining + await (0, import_core13.computeCreditRecoveryPad)(...args)) % import_core13.FIELD_MODULUS)
3574
4662
  );
3575
4663
  deliveries.push(...output.deliveries);
3576
4664
  }
@@ -3594,9 +4682,9 @@ var CreditPreparation = class {
3594
4682
  draw: params,
3595
4683
  amounts
3596
4684
  };
3597
- plan.statement = import_protocol6.WitnessBuilder.statement(
4685
+ plan.statement = import_protocol7.WitnessBuilder.statement(
3598
4686
  profile.name,
3599
- (0, import_protocol6.creditDrawPublicInputs)(frame.context, params, deliveries)
4687
+ (0, import_protocol7.creditDrawPublicInputs)(frame.context, params, deliveries)
3600
4688
  );
3601
4689
  await this.#prepare.assertBlock(frame);
3602
4690
  return this.runtime.complete(plan);
@@ -3616,9 +4704,9 @@ var CreditPreparation = class {
3616
4704
  };
3617
4705
  plan.capacity = 1;
3618
4706
  plan.credit = { inputs: [previous.input], outputs: [], deliveries: [], cancel: params };
3619
- plan.statement = import_protocol6.WitnessBuilder.statement(
4707
+ plan.statement = import_protocol7.WitnessBuilder.statement(
3620
4708
  "credit_cancel",
3621
- (0, import_protocol6.cancelCreditPublicInputs)(frame.context, params)
4709
+ (0, import_protocol7.cancelCreditPublicInputs)(frame.context, params)
3622
4710
  );
3623
4711
  await this.#prepare.assertBlock(frame);
3624
4712
  return this.runtime.complete(plan);
@@ -3639,87 +4727,48 @@ var TransactionPreparation = class {
3639
4727
  return this.context.scope;
3640
4728
  }
3641
4729
  async prepareTransfer(options) {
4730
+ if (Object.hasOwn(options, "target") || Object.hasOwn(options, "execution")) {
4731
+ throw new Error(
4732
+ "prepareTransfer accepts no target or execution; choose execution in prove()"
4733
+ );
4734
+ }
3642
4735
  const copied = structuredClone(options);
3643
- const preparation = new Preparation(this.runtime(copied.tokenAddress));
4736
+ const runtime = this.runtime(copied.tokenAddress);
4737
+ if (copied.commitments !== void 0 && copied.commitments.length === 0)
4738
+ throw new Error("empty explicit input selection");
4739
+ const preparation = new Preparation({
4740
+ ...runtime,
4741
+ ...copied.commitments !== void 0 ? { inputSelection: copied.commitments } : {}
4742
+ });
3644
4743
  const frame = await preparation.frame(copied.deadline);
3645
- if (copied.outputs.length < 1 || copied.outputs.length > 168) {
3646
- throw new Error("transfer requires 1..168 outputs");
4744
+ if (copied.outputs.length > 168) throw new Error("transfer supports at most 168 outputs");
4745
+ let withdrawalAddress = import_protocol8.ZERO_ADDRESS;
4746
+ let withdrawalAmount = 0n;
4747
+ if (copied.withdrawal !== void 0) {
4748
+ withdrawalAddress = (0, import_ethers10.getAddress)(copied.withdrawal.to);
4749
+ positiveAmount(copied.withdrawal.amount);
4750
+ if (BigInt(withdrawalAddress) === 0n)
4751
+ throw new Error("withdrawal destination must be nonzero");
4752
+ withdrawalAmount = copied.withdrawal.amount;
3647
4753
  }
4754
+ if (copied.outputs.length === 0 && withdrawalAmount === 0n)
4755
+ throw new Error("transfer requires a private output or public withdrawal");
3648
4756
  const total = copied.outputs.reduce(
3649
- (sum, output) => sum + positiveAmount(output.amount),
3650
- 0n
4757
+ (sum, output, index2) => sum + positiveOutputAmount(output, index2),
4758
+ withdrawalAmount
3651
4759
  );
3652
4760
  const funding = await preparation.funding(copied.funding, frame);
3653
4761
  return this.funds(
3654
- "transfer",
3655
4762
  copied.outputs,
3656
4763
  total,
3657
- import_protocol7.ZERO_ADDRESS,
3658
- 0n,
4764
+ withdrawalAddress,
4765
+ withdrawalAmount,
3659
4766
  frame,
3660
4767
  funding,
3661
- copied.target,
3662
- preparation
3663
- );
3664
- }
3665
- async prepareWithdraw(options) {
3666
- const copied = structuredClone(options);
3667
- const preparation = new Preparation(this.runtime(copied.tokenAddress));
3668
- const frame = await preparation.frame(copied.deadline);
3669
- const to = (0, import_ethers10.getAddress)(copied.to);
3670
- positiveAmount(copied.amount);
3671
- if (BigInt(to) === 0n) {
3672
- throw new Error("withdrawal destination must be nonzero");
3673
- }
3674
- return this.funds(
3675
- "withdraw",
3676
- [],
3677
- copied.amount,
3678
- to,
3679
- copied.amount,
3680
- frame,
3681
- { funding: {}, fundingMode: "none" },
3682
- copied.target,
3683
- preparation
3684
- );
3685
- }
3686
- /** Full payout to the note owner; no arbitrary destination, change or spending signature. */
3687
- async prepareSweep(options) {
3688
- const copied = structuredClone(options);
3689
- const runtime = this.runtime(copied.tokenAddress);
3690
- const state = await runtime.readInventory();
3691
- const available = Object.values(state.notes).filter(
3692
- (record) => record.note.tokenAddress === BigInt(copied.tokenAddress) && record.spent === "unspent" && !state.reservations[record.commitment]
3693
- );
3694
- const selected = copied.commitments ?? available.map((record) => record.commitment);
3695
- if (selected.length === 0) throw new Error("empty sweep input selection");
3696
- if (new Set(selected).size !== selected.length) throw new Error("duplicate sweep inputs");
3697
- const byId = new Map(available.map((record) => [record.commitment, record]));
3698
- let amount = 0n;
3699
- for (const id of selected) {
3700
- const record = byId.get(id);
3701
- if (!record) throw new Error("sweep input unavailable");
3702
- amount += record.note.amount;
3703
- }
3704
- positiveAmount(amount);
3705
- const preparation = new Preparation({
3706
- ...runtime,
3707
- inputSelection: selected
3708
- });
3709
- const frame = await preparation.frame(copied.deadline);
3710
- return this.funds(
3711
- "sweep",
3712
- [],
3713
- amount,
3714
- this.scope.walletIdentity,
3715
- amount,
3716
- frame,
3717
- { funding: {}, fundingMode: "none" },
3718
- copied.target,
3719
4768
  preparation
3720
4769
  );
3721
4770
  }
3722
- async funds(kind, payments, total, withdrawalAddress, withdrawalAmount, frame, funding, target, preparation) {
4771
+ async funds(payments, total, withdrawalAddress, withdrawalAmount, frame, funding, preparation) {
3723
4772
  if (total >= 1n << 135n) {
3724
4773
  throw new Error("transaction sum exceeds uint135");
3725
4774
  }
@@ -3729,7 +4778,7 @@ var TransactionPreparation = class {
3729
4778
  frame
3730
4779
  );
3731
4780
  const outputs = await Promise.all(
3732
- payments.map((payment) => preparation.output(payment, context))
4781
+ payments.map((payment, index2) => preparation.output(payment, context, false, index2))
3733
4782
  );
3734
4783
  const change = selection.amount + (funding.funding.amount ?? 0n) - total;
3735
4784
  if (change > 0n) {
@@ -3754,17 +4803,17 @@ var TransactionPreparation = class {
3754
4803
  deadline
3755
4804
  };
3756
4805
  const deliveries = outputs.map((output) => output.delivery);
3757
- const normalized = (0, import_protocol7.normalizeTransactRequest)(context, params, deliveries, funding.funding);
3758
- const statement2 = import_protocol7.WitnessBuilder.statement(
4806
+ const normalized = (0, import_protocol8.normalizeTransactRequest)(context, params, deliveries, funding.funding);
4807
+ const statement2 = import_protocol8.WitnessBuilder.statement(
3759
4808
  `transact_user_slots${normalized.capacity}`,
3760
- (0, import_protocol7.transactUserPublicInputs)(context, params, deliveries, funding.funding),
3761
- target ?? "evm"
4809
+ (0, import_protocol8.transactUserPublicInputs)(context, params, deliveries, funding.funding),
4810
+ "evm"
3762
4811
  );
3763
4812
  await preparation.assertBlock(frame);
3764
4813
  return preparation.runtime.complete({
3765
4814
  version: 1,
3766
4815
  id: crypto.randomUUID(),
3767
- kind,
4816
+ kind: "transfer",
3768
4817
  context,
3769
4818
  scope: this.scope,
3770
4819
  preparedAt: block,
@@ -3786,7 +4835,9 @@ var TransactionPreparation = class {
3786
4835
  throw new Error("shield requires 1..10 outputs");
3787
4836
  }
3788
4837
  const outputs = await Promise.all(
3789
- copied.outputs.map((output) => preparation.output(output, frame.context))
4838
+ copied.outputs.map(
4839
+ (output, index2) => preparation.output(output, frame.context, false, index2)
4840
+ )
3790
4841
  );
3791
4842
  if (outputs.reduce((sum, output) => sum + output.note.amount, 0n) !== (funding.funding.amount ?? 0n)) {
3792
4843
  throw new Error("shield funding must equal output total");
@@ -3891,10 +4942,10 @@ async function refreshWallet(runtime, options) {
3891
4942
  }
3892
4943
 
3893
4944
  // src/session/WalletUpdater.ts
3894
- var import_core11 = require("@invisi-labs/core");
4945
+ var import_core15 = require("@invisi-labs/core");
3895
4946
 
3896
4947
  // src/session/inventory.ts
3897
- var import_core10 = require("@invisi-labs/core");
4948
+ var import_core14 = require("@invisi-labs/core");
3898
4949
  var CanonicalConflict = class extends Error {
3899
4950
  };
3900
4951
  var CreditMetadataMismatch = class extends Error {
@@ -3946,10 +4997,10 @@ var InventoryProcessor = class {
3946
4997
  }
3947
4998
  async creditNullifier(state) {
3948
4999
  const n = state.note;
3949
- return (0, import_core10.computeCreditNullifier)(
5000
+ return (0, import_core14.computeCreditNullifier)(
3950
5001
  n.chainId,
3951
5002
  n.creditSharedKey,
3952
- await (0, import_core10.computeCreditCommitment)(
5003
+ await (0, import_core14.computeCreditCommitment)(
3953
5004
  n.chainId,
3954
5005
  n.spenderWalletIdentity,
3955
5006
  n.ownerWalletIdentity,
@@ -3959,7 +5010,8 @@ var InventoryProcessor = class {
3959
5010
  n.amount,
3960
5011
  n.nonce,
3961
5012
  n.expiry,
3962
- await (0, import_core10.computeCreditSharedKeyHash)(n.creditSharedKey)
5013
+ await (0, import_core14.computeCreditSharedKeyHash)(n.creditSharedKey),
5014
+ n
3963
5015
  )
3964
5016
  );
3965
5017
  }
@@ -4006,6 +5058,9 @@ var InventoryProcessor = class {
4006
5058
  };
4007
5059
  for (const event of logs) {
4008
5060
  if (event.eventName === "CreditDraw") {
5061
+ const block = await this.#options.reader.getBlock(event.blockNumber);
5062
+ if (block.hash !== event.blockHash)
5063
+ throw new CanonicalConflict("draw block changed during Credit recovery");
4009
5064
  const args = event.args;
4010
5065
  const params = args.params;
4011
5066
  const indices = args.remainderLeafIndices;
@@ -4019,10 +5074,11 @@ var InventoryProcessor = class {
4019
5074
  previous.state.note.expiry === params.expiries[index2],
4020
5075
  "draw recovery expiry mismatch"
4021
5076
  );
4022
- const remainder = await (0, import_core10.recoverCreditRemainder)(
5077
+ const remainder = await (0, import_core14.recoverCreditRemainder)(
4023
5078
  context,
4024
5079
  previous.state.note,
4025
5080
  {
5081
+ timestamp: block.timestamp,
4026
5082
  creditNullifier: nullifier,
4027
5083
  remainderCommitment: params.remainderCommitments[index2],
4028
5084
  recoveryAmount: BigInt(params.recoveryAmounts[index2])
@@ -4034,7 +5090,7 @@ var InventoryProcessor = class {
4034
5090
  const child = foundByKey.get(
4035
5091
  params.remainderCommitments[index2] + ":" + previous.role
4036
5092
  );
4037
- const memo = child?.state.note.memo;
5093
+ const payload = child?.state.note.payload;
4038
5094
  const record = {
4039
5095
  commitment: params.remainderCommitments[index2],
4040
5096
  treeId: BigInt(args.outputTreeId),
@@ -4047,7 +5103,7 @@ var InventoryProcessor = class {
4047
5103
  ...clone(previous.state),
4048
5104
  note: {
4049
5105
  ...remainder,
4050
- ...memo === void 0 ? {} : { memo: (0, import_core10.encodeMemo)(memo) }
5106
+ ...payload === void 0 ? {} : { payload: clone(payload) }
4051
5107
  }
4052
5108
  },
4053
5109
  receivingKeySource: { kind: "draw", commitment: previous.commitment },
@@ -4126,7 +5182,7 @@ var WalletUpdater = class extends InventoryProcessor {
4126
5182
  }
4127
5183
  async run(batch, options) {
4128
5184
  const { reader, protocol, scope, store, viewing } = this.#options;
4129
- const nullifier = import_core11.NullifierCapability.fromIdentity(scope.walletIdentity);
5185
+ const nullifier = import_core15.NullifierCapability.fromIdentity(scope.walletIdentity);
4130
5186
  const { signal, reset } = options;
4131
5187
  signal?.throwIfAborted();
4132
5188
  const context = protocol.context;
@@ -4295,6 +5351,7 @@ var WalletUpdater = class extends InventoryProcessor {
4295
5351
  draft.notes = {};
4296
5352
  draft.credits = {};
4297
5353
  delete draft.observedThrough;
5354
+ delete draft.discoveryThrough;
4298
5355
  delete draft.invalidated;
4299
5356
  }
4300
5357
  mergeReceiptRecords(draft, { notes, credits, checkpoint: block });
@@ -4326,13 +5383,38 @@ var WalletUpdater = class extends InventoryProcessor {
4326
5383
  var WalletSession = class {
4327
5384
  #options;
4328
5385
  #updater;
5386
+ #listeners = /* @__PURE__ */ new Set();
4329
5387
  #sending = /* @__PURE__ */ new Set();
4330
5388
  #refreshQueue = Promise.resolve();
4331
5389
  scope;
4332
5390
  protocol;
4333
5391
  constructor(options) {
5392
+ if ("ciphertextCodecs" in options || "envelopeVersion" in options) {
5393
+ throw new Error(
5394
+ "SDK envelope versions are fixed; encode application payload bytes externally"
5395
+ );
5396
+ }
5397
+ const store = options.store;
4334
5398
  this.#options = {
4335
5399
  ...options,
5400
+ ...store ? {
5401
+ store: {
5402
+ persistent: store.persistent,
5403
+ readSnapshot: (scope) => store.readSnapshot(scope),
5404
+ transaction: async (scope, action) => {
5405
+ const result = await store.transaction(scope, action);
5406
+ if (scopeKey(scope) === scopeKey(this.scope)) {
5407
+ for (const listener of [...this.#listeners]) {
5408
+ try {
5409
+ listener();
5410
+ } catch {
5411
+ }
5412
+ }
5413
+ }
5414
+ return result;
5415
+ }
5416
+ }
5417
+ } : {},
4336
5418
  ...options.gasBenchmarks ? { gasBenchmarks: copyGasBenchmarks(options.gasBenchmarks) } : {}
4337
5419
  };
4338
5420
  this.protocol = options.protocol;
@@ -4347,7 +5429,7 @@ var WalletSession = class {
4347
5429
  /** Delegate sending to ethers; managed operations additionally retain the resulting hash. */
4348
5430
  async sendTransaction(input, options = {}) {
4349
5431
  const signer = this.#options.signer;
4350
- if (!signer) throw new import_core12.MissingCapabilityError("ethers signer");
5432
+ if (!signer) throw new import_core17.MissingCapabilityError("ethers signer");
4351
5433
  const operation = input instanceof Operation ? input : void 0;
4352
5434
  if (operation && this.#sending.has(operation.id))
4353
5435
  throw new Error("operation is already being sent by this session");
@@ -4355,12 +5437,12 @@ var WalletSession = class {
4355
5437
  const overrides = { ...options };
4356
5438
  const plain = operation ? void 0 : { ...input };
4357
5439
  try {
4358
- if (!signer.provider) throw new import_core12.MissingCapabilityError("connected ethers signer");
5440
+ if (!signer.provider) throw new import_core17.MissingCapabilityError("connected ethers signer");
4359
5441
  if ((await signer.provider.getNetwork()).chainId !== this.protocol.context.chainId) {
4360
5442
  throw new Error("signer-provider session chain mismatch");
4361
5443
  }
4362
5444
  if (operation) {
4363
- if (!this.#options.store) throw new import_core12.MissingCapabilityError("wallet store");
5445
+ if (!this.#options.store) throw new import_core17.MissingCapabilityError("wallet store");
4364
5446
  const state = await this.#options.store.readSnapshot(this.scope);
4365
5447
  if (!state.operations[operation.id])
4366
5448
  throw new Error("operation does not belong to this wallet session");
@@ -4391,25 +5473,30 @@ var WalletSession = class {
4391
5473
  runtime(tokenAddress) {
4392
5474
  const options = this.#options;
4393
5475
  if (!options.store) {
4394
- throw new import_core12.MissingCapabilityError("wallet store");
5476
+ throw new import_core17.MissingCapabilityError("wallet store");
4395
5477
  }
4396
5478
  if (!options.chainReader) {
4397
- throw new import_core12.MissingCapabilityError("chain reader");
5479
+ throw new import_core17.MissingCapabilityError("chain reader");
4398
5480
  }
4399
5481
  return {
4400
5482
  options: { ...options, protocol: options.protocol.forToken(tokenAddress) },
4401
5483
  scope: this.scope,
4402
5484
  store: options.store,
4403
5485
  reader: options.chainReader,
4404
- authorization: () => options.authorization ?? options.wallet.exportAuthorization()
5486
+ authorization: () => {
5487
+ if (options.authorization) return options.authorization;
5488
+ if (options.wallet instanceof import_core16.Wallet) return options.wallet.exportAuthorization();
5489
+ throw new import_core17.MissingCapabilityError("wallet authorization");
5490
+ }
4405
5491
  };
4406
5492
  }
4407
5493
  updater() {
4408
5494
  if (this.#updater) return this.#updater;
4409
5495
  const options = this.#options;
4410
5496
  if (!options.store || !options.chainReader || !options.protocolRpc)
4411
- throw new import_core12.MissingCapabilityError("wallet store, chain reader and Protocol RPC");
4412
- const viewing = options.viewing ?? options.wallet.getViewer();
5497
+ throw new import_core17.MissingCapabilityError("wallet store, chain reader and Protocol RPC");
5498
+ const viewing = options.viewing ?? (options.wallet instanceof import_core16.Wallet ? options.wallet.getViewer() : void 0);
5499
+ if (!viewing) throw new import_core17.MissingCapabilityError("viewing");
4413
5500
  const receivingAddress = options.wallet.getReceivingAddress();
4414
5501
  const receivingKeys = receivingAddress.kind === "long" ? receivingAddress.getReceivingKeys() : void 0;
4415
5502
  this.#updater = new WalletUpdater({
@@ -4423,10 +5510,27 @@ var WalletSession = class {
4423
5510
  });
4424
5511
  return this.#updater;
4425
5512
  }
5513
+ /** Local session commits only. Host applications own cross-tab/store subscriptions. */
5514
+ subscribe(listener) {
5515
+ this.#listeners.add(listener);
5516
+ return () => {
5517
+ this.#listeners.delete(listener);
5518
+ };
5519
+ }
5520
+ /** Detached history for wallet UI; construction records do not imply chain success. */
5521
+ async getHistory(options = {}) {
5522
+ const tokenAddress = options.tokenAddress ? (0, import_ethers11.getAddress)(options.tokenAddress) : void 0;
5523
+ const store = this.#options.store;
5524
+ if (!store) throw new import_core17.MissingCapabilityError("wallet store");
5525
+ return walletHistory(
5526
+ await store.readSnapshot(this.scope),
5527
+ tokenAddress ? { tokenAddress } : {}
5528
+ );
5529
+ }
4426
5530
  async balance(tokenAddress) {
4427
5531
  const store = this.#options.store;
4428
5532
  if (!store) {
4429
- throw new import_core12.MissingCapabilityError("wallet store");
5533
+ throw new import_core17.MissingCapabilityError("wallet store");
4430
5534
  }
4431
5535
  return walletBalance(await store.readSnapshot(this.scope), (0, import_ethers11.getAddress)(tokenAddress));
4432
5536
  }
@@ -4434,15 +5538,15 @@ var WalletSession = class {
4434
5538
  async refresh(options) {
4435
5539
  const provider = this.#options.protocolRpc;
4436
5540
  const reader = this.#options.chainReader;
4437
- if (!reader) throw new import_core12.MissingCapabilityError("chain reader");
4438
- if (!provider) throw new import_core12.MissingCapabilityError("Protocol RPC");
5541
+ if (!reader) throw new import_core17.MissingCapabilityError("chain reader");
5542
+ if (!provider) throw new import_core17.MissingCapabilityError("Protocol RPC");
4439
5543
  const updater = this.updater();
4440
5544
  const request = {
4441
5545
  ...options,
4442
5546
  ...options.detectionKey ? { detectionKey: options.detectionKey.slice() } : {}
4443
5547
  };
4444
- const task = this.#refreshQueue.then(
4445
- () => refreshWallet(
5548
+ const task = this.#refreshQueue.then(async () => {
5549
+ const result = await refreshWallet(
4446
5550
  {
4447
5551
  provider,
4448
5552
  reader,
@@ -4451,8 +5555,21 @@ var WalletSession = class {
4451
5555
  apply: (batch, settings) => updater.applyUpdates(batch, settings)
4452
5556
  },
4453
5557
  request
4454
- )
4455
- );
5558
+ );
5559
+ await this.#options.store.transaction(this.scope, (state) => {
5560
+ request.signal?.throwIfAborted();
5561
+ if (state.invalidated) throw new Error("wallet requires canonical resync");
5562
+ const previous = state.discoveryThrough;
5563
+ const start = previous ? previous.number + 1n : this.protocol.deployment.protocol.fromBlock;
5564
+ if (request.fromBlock <= start && (!previous || result.block.number >= previous.number)) {
5565
+ state.discoveryThrough = {
5566
+ number: result.block.number,
5567
+ hash: result.block.hash
5568
+ };
5569
+ }
5570
+ });
5571
+ return result;
5572
+ });
4456
5573
  this.#refreshQueue = task.catch(() => {
4457
5574
  });
4458
5575
  return task;
@@ -4463,38 +5580,43 @@ var WalletSession = class {
4463
5580
  options: runtime.options,
4464
5581
  scope: runtime.scope,
4465
5582
  reader: runtime.reader,
4466
- authorization: runtime.authorization,
4467
5583
  readInventory: () => runtime.store.readSnapshot(runtime.scope),
4468
5584
  complete: (plan) => Operation.prepare(runtime, plan)
4469
5585
  });
4470
5586
  }
4471
5587
  async prepareTransfer(options) {
4472
- return this.preparation(options.tokenAddress).prepareTransfer(options);
4473
- }
4474
- async prepareWithdraw(options) {
4475
- return this.preparation(options.tokenAddress).prepareWithdraw(options);
4476
- }
4477
- async prepareSweep(options) {
4478
- return this.preparation(options.tokenAddress).prepareSweep(options);
5588
+ return prepareWithErrors("prepareTransfer", async () => {
5589
+ return this.preparation(options.tokenAddress).prepareTransfer(options);
5590
+ });
4479
5591
  }
4480
5592
  async prepareShield(options) {
4481
- return this.preparation(options.tokenAddress).prepareShield(options);
5593
+ return prepareWithErrors("prepareShield", async () => {
5594
+ return this.preparation(options.tokenAddress).prepareShield(options);
5595
+ });
4482
5596
  }
4483
5597
  async prepareCreateCredit(options) {
4484
- return this.preparation(options.tokenAddress).prepareCreateCredit(options);
5598
+ return prepareWithErrors("prepareCreateCredit", async () => {
5599
+ return this.preparation(options.tokenAddress).prepareCreateCredit(options);
5600
+ });
4485
5601
  }
4486
5602
  async prepareDrawCredit(options) {
4487
- return this.preparation(options.tokenAddress).prepareDrawCredit(options);
5603
+ return prepareWithErrors("prepareDrawCredit", async () => {
5604
+ return this.preparation(options.tokenAddress).prepareDrawCredit(options);
5605
+ });
4488
5606
  }
4489
5607
  async prepareTopUpCredit(options) {
4490
- return this.preparation(options.tokenAddress).prepareTopUpCredit(options);
5608
+ return prepareWithErrors("prepareTopUpCredit", async () => {
5609
+ return this.preparation(options.tokenAddress).prepareTopUpCredit(options);
5610
+ });
4491
5611
  }
4492
5612
  async prepareCancelCredit(options) {
4493
- return this.preparation(options.tokenAddress).prepareCancelCredit(options);
5613
+ return prepareWithErrors("prepareCancelCredit", async () => {
5614
+ return this.preparation(options.tokenAddress).prepareCancelCredit(options);
5615
+ });
4494
5616
  }
4495
5617
  async resume(operationId) {
4496
5618
  const store = this.#options.store;
4497
- if (!store) throw new import_core12.MissingCapabilityError("wallet store");
5619
+ if (!store) throw new import_core17.MissingCapabilityError("wallet store");
4498
5620
  const state = await store.readSnapshot(this.scope);
4499
5621
  const saved = state.operations[operationId]?.payload;
4500
5622
  if (!saved?.plan) throw new Error("operation not found");