@invisi-labs/protocol 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/index.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
 
14
14
  // src/RegistrationOperation.ts
15
15
  import { hexlify as hexlify2, Interface as Interface2, getBytes as getBytes2, verifyTypedData } from "ethers";
16
- import { ReceivingAddress as ReceivingAddress2 } from "@invisi-labs/core";
16
+ import { ReceivingAddress as ReceivingAddress2, createSigningRequest } from "@invisi-labs/core";
17
17
 
18
18
  // src/registry.ts
19
19
  import {
@@ -228,27 +228,20 @@ var RegistrationOperation = class _RegistrationOperation {
228
228
  update: this.#plan.update
229
229
  };
230
230
  }
231
- /** Sign with ethers, or attach externally obtained ERC-1271 signature bytes. */
232
- async authorize(options = {}) {
231
+ /** Export portable EIP-712 data for external signing. */
232
+ async exportRegistrationAuthorization(options = {}) {
233
+ check(this.status === "prepared", "registry operation is not awaiting authorization");
234
+ options.signal?.throwIfAborted();
235
+ await this.validateFreshness();
236
+ options.signal?.throwIfAborted();
237
+ return createSigningRequest(this.typedData());
238
+ }
239
+ /** Validate and attach an independently obtained EOA or ERC-1271 signature. */
240
+ async withSignature(signature, options = {}) {
233
241
  check(this.status === "prepared", "registry operation is not awaiting authorization");
234
242
  options.signal?.throwIfAborted();
235
243
  await this.validateFreshness();
236
244
  options.signal?.throwIfAborted();
237
- let signature = options.signature;
238
- if (signature === void 0) {
239
- const signer = this.#runtime.signer;
240
- check(signer, "registry signer capability is missing");
241
- check(
242
- BigInt(await signer.getAddress()) === BigInt(this.#plan.registration.walletIdentity),
243
- "registry signer does not match wallet owner"
244
- );
245
- const typed = this.typedData();
246
- signature = await signer.signTypedData(
247
- typed.domain,
248
- typed.types,
249
- typed.message
250
- );
251
- }
252
245
  check(
253
246
  /^0x(?:[a-fA-F0-9]{2})+$/.test(signature),
254
247
  "registry signature must be nonempty hexadecimal bytes"
@@ -516,6 +509,7 @@ import {
516
509
  import { computeWalletAuthorizationDigest, walletAuthorizationTypedData } from "@invisi-labs/core";
517
510
 
518
511
  // src/validation.ts
512
+ import { MAX_CIPHERTEXT_BYTES } from "@invisi-labs/core";
519
513
  import {
520
514
  AbiCoder,
521
515
  dataLength,
@@ -610,19 +604,14 @@ var pad = (v, n) => [
610
604
  ...v,
611
605
  ...Array(n - v.length).fill(0n)
612
606
  ];
613
- function normalizeDelivery(value, options = {}) {
607
+ function normalizeOpaqueDelivery(value, options = {}) {
614
608
  known(value, ["ciphertext", "clue"], "delivery");
615
609
  if (options.empty) {
616
610
  if (value.ciphertext !== "0x" || value.clue !== "0x")
617
611
  throw new Error("absent output requires an empty delivery");
618
612
  return { ciphertext: "0x", clue: "0x" };
619
613
  }
620
- const ciphertext = envelope(
621
- value.ciphertext,
622
- options.credit ? 402 : 160,
623
- options.credit ? 4 : 2,
624
- options.credit ? 658 : 416
625
- );
614
+ const ciphertext = envelope(value.ciphertext, 1, void 0, MAX_CIPHERTEXT_BYTES);
626
615
  const clue = envelope(value.clue, 68);
627
616
  if (clue.slice(130, 132).toLowerCase() !== "18") throw new Error("clue precision must be 24");
628
617
  return { ciphertext, clue };
@@ -705,7 +694,7 @@ function validateCreateCreditRequest(c, p, cs, funding = {}) {
705
694
  throw new Error("owner must be nonzero and expiry future");
706
695
  if (dense(cs, "deliveries").length !== 3) throw new Error("deliveries count mismatch");
707
696
  const deliveries = cs.map(
708
- (v, i) => normalizeDelivery(v, { credit: i < 2, empty: i === 2 && BigInt(changeCommitment) === 0n })
697
+ (v, i) => normalizeOpaqueDelivery(v, { empty: i === 2 && BigInt(changeCommitment) === 0n })
709
698
  );
710
699
  if (ns.length === 0 && f.amount === 0n)
711
700
  throw new Error("empty inputs require positive funding");
@@ -839,6 +828,7 @@ function encodeCreditProof(proof) {
839
828
  // src/credit-lifecycle.ts
840
829
  import { AbiCoder as AbiCoder3, getAddress as getAddress5, Interface as Interface4, keccak256 as keccak2564, ParamType as ParamType3 } from "ethers";
841
830
  import {
831
+ creditPeriods,
842
832
  computeWalletAuthorizationDigest as computeWalletAuthorizationDigest2,
843
833
  walletAuthorizationTypedData as walletAuthorizationTypedData2
844
834
  } from "@invisi-labs/core";
@@ -850,7 +840,7 @@ function selectCreditDrawCircuit(count) {
850
840
  return {
851
841
  name: `credit_draw_slots${maxSize}`,
852
842
  maxSize,
853
- publicInputCount: 6 * maxSize + 12,
843
+ publicInputCount: 6 * maxSize + 14,
854
844
  totalBits: 126 + Math.ceil(Math.log2(maxSize))
855
845
  };
856
846
  }
@@ -890,7 +880,7 @@ function validateCreditDrawRequest(c, p, cs) {
890
880
  if (dense(cs, "deliveries").length !== 2 * ns.length)
891
881
  throw new Error("deliveries count mismatch");
892
882
  const deliveries = cs.map(
893
- (v, i) => BigInt(remainderCommitments[Math.floor(i / 2)]) === 0n ? normalizeDelivery(v, { empty: true }) : normalizeDelivery(v, { credit: true })
883
+ (v, i) => BigInt(remainderCommitments[Math.floor(i / 2)]) === 0n ? normalizeOpaqueDelivery(v, { empty: true }) : normalizeOpaqueDelivery(v, {})
894
884
  );
895
885
  return {
896
886
  ...ctx,
@@ -903,7 +893,8 @@ function validateCreditDrawRequest(c, p, cs) {
903
893
  totalAmount,
904
894
  deadline: checkDeadline(c, p.deadline),
905
895
  deliveries,
906
- profile
896
+ profile,
897
+ periods: creditPeriods(c.timestamp)
907
898
  };
908
899
  }
909
900
  function creditDrawBaseInputs(c, p, cs) {
@@ -930,7 +921,9 @@ function creditDrawBaseInputs(c, p, cs) {
930
921
  r.deadline,
931
922
  h >> 128n,
932
923
  h & (1n << 128n) - 1n,
933
- ...pad(r.recoveryAmounts.map(BigInt), n)
924
+ ...pad(r.recoveryAmounts.map(BigInt), n),
925
+ r.periods.currentDay,
926
+ r.periods.currentMonth
934
927
  ].map(word);
935
928
  }
936
929
  function validateCancelCreditRequest(c, p) {
@@ -1149,7 +1142,7 @@ function normalizeTransactRequest(c, p, cs, funding = {}) {
1149
1142
  "deadline"
1150
1143
  ]);
1151
1144
  const ns = notes(p.nullifiers, "nullifiers"), os = notes(p.outputCommitments, "outputCommitments"), capacity = selectTransactCapacity(ns.length, os.length);
1152
- const sources = normalizeSources(p.sources, ns.length, capacity), deliveries = dense(cs, "deliveries").map((v) => normalizeDelivery(v));
1145
+ const sources = normalizeSources(p.sources, ns.length, capacity), deliveries = dense(cs, "deliveries").map((v) => normalizeOpaqueDelivery(v));
1153
1146
  if (deliveries.length !== os.length) throw new Error("deliveries count mismatch");
1154
1147
  const withdrawalAmount = uint(p.withdrawalAmount, 128, "withdrawalAmount"), withdrawalAddress = getAddress6(p.withdrawalAddress), f = normalizeFunding(funding);
1155
1148
  if (withdrawalAmount === 0n !== (BigInt(withdrawalAddress) === 0n) || os.length === 0 && withdrawalAmount === 0n)
@@ -1328,7 +1321,7 @@ async function validateShieldRequest(p) {
1328
1321
  uint(o.amount, 128, "amount");
1329
1322
  if (o.amount === 0n) throw new Error("amount must be positive");
1330
1323
  field(o.identity);
1331
- normalizeDelivery(cs[i]);
1324
+ normalizeOpaqueDelivery(cs[i]);
1332
1325
  if (await computeNoteCommitment(
1333
1326
  p.context.chainId,
1334
1327
  o.identity,
@@ -1654,53 +1647,22 @@ async function verifyCreditCommitment(params) {
1654
1647
  params.amount,
1655
1648
  params.nonce,
1656
1649
  params.expiry,
1657
- await computeCreditSharedKeyHash(params.creditSharedKey)
1650
+ await computeCreditSharedKeyHash(params.creditSharedKey),
1651
+ params
1658
1652
  );
1659
1653
  return BigInt(expected) === BigInt(params.creditCommitment);
1660
1654
  }
1661
1655
 
1662
- // src/withdrawal.ts
1663
- import {
1664
- computeNoteCommitment as computeNoteCommitment3,
1665
- computeNoteIdentity as computeNoteIdentity2,
1666
- computeNoteNullifier
1667
- } from "@invisi-labs/core";
1668
- async function buildWithdrawalCalldata(p) {
1669
- const r = normalizeTransactRequest(p.context, p.params, [], p.funding);
1670
- if (r.outputCount !== 0 || r.depositAmount !== 0n || p.sourceNotes.length === 0 || p.sourceNotes.length !== r.inputCount) {
1671
- throw new Error("full withdrawal requires inputs, no private outputs and no funding");
1672
- }
1673
- const walletIdentity = BigInt(p.sourceNotes[0].walletIdentity);
1674
- let total = 0n;
1675
- for (const [index, note] of p.sourceNotes.entries()) {
1676
- if (note.chainId !== p.context.chainId || note.protocolAddress !== BigInt(p.context.protocolAddress))
1677
- throw new Error("source note context mismatch");
1678
- if (BigInt(note.walletIdentity) !== walletIdentity || note.tokenAddress !== BigInt(p.context.tokenAddress) || note.amount <= 0n)
1679
- throw new Error("source note wallet/token/amount mismatch");
1680
- const commitment = await computeNoteCommitment3(
1681
- note.chainId,
1682
- await computeNoteIdentity2(walletIdentity, note.nonce),
1683
- note.tokenAddress,
1684
- note.amount
1685
- );
1686
- const nullifier = await computeNoteNullifier(note.chainId, note.nonce, commitment);
1687
- if (nullifier.toLowerCase() !== r.nullifiers[index].toLowerCase())
1688
- throw new Error("source note nullifier mismatch");
1689
- total += note.amount;
1690
- }
1691
- if (r.withdrawalAmount !== total)
1692
- throw new Error("withdrawal must equal the full input balance");
1693
- return buildTransactCalldata({ ...p, deliveries: [] });
1694
- }
1695
-
1696
1656
  // src/witness.ts
1697
1657
  import {
1698
1658
  computeCreditCommitment as computeCreditCommitment2,
1659
+ normalizeCreditPolicy,
1660
+ applyCreditDrawUsage,
1699
1661
  computeCreditNullifier,
1700
1662
  computeCreditSharedKeyHash as computeCreditSharedKeyHash2,
1701
- computeNoteCommitment as computeNoteCommitment4,
1702
- computeNoteIdentity as computeNoteIdentity3,
1703
- computeNoteNullifier as computeNoteNullifier2,
1663
+ computeNoteCommitment as computeNoteCommitment3,
1664
+ computeNoteIdentity as computeNoteIdentity2,
1665
+ computeNoteNullifier,
1704
1666
  computeWalletAuthorizationDigest as computeWalletAuthorizationDigest3,
1705
1667
  normalizeCreditDeliveryState,
1706
1668
  poseidonHash,
@@ -2230,9 +2192,9 @@ var witness_layouts_default = {
2230
2192
  ]
2231
2193
  },
2232
2194
  create_credit: {
2233
- artifactSha256: "078c6d2da1ed2d6bd27fab28af9970261fe626a0b22ae56ad170e5d15b1b05ba",
2195
+ artifactSha256: "3ed6cfdee4f5fd840f023580f76c208768777fea79737f2511377e5c55be0230",
2234
2196
  keys: {
2235
- evm: "8285456447e92833a4fa9c330b9c667a3a1b9e48649578082041b9738f037c8f"
2197
+ evm: "56f663c6053be0d158a271022d200c732597efd3a2e0be48fe94549d0b1795e0"
2236
2198
  },
2237
2199
  publicInputCount: 46,
2238
2200
  public: [
@@ -2347,16 +2309,19 @@ var witness_layouts_default = {
2347
2309
  "credit_amount",
2348
2310
  "credit_nonce",
2349
2311
  "credit_shared_key",
2312
+ "single_limit",
2313
+ "daily_limit",
2314
+ "monthly_limit",
2350
2315
  "change_amount",
2351
2316
  "change_nonce"
2352
2317
  ]
2353
2318
  },
2354
2319
  credit_draw_slots1: {
2355
- artifactSha256: "2b9da9d3d1dbd411d9be1bbe2b34305ac5dce7c7d18e3857d8e2be7dd9bf7c21",
2320
+ artifactSha256: "4542b227e0552b45c302f1dace21cadeba4962c96244e021472f1f7531cff8d1",
2356
2321
  keys: {
2357
- evm: "613699a440f50a0937e4c57e5152b5fdea42c31b10157d6b93226fef313df553"
2322
+ evm: "43c051a2bedf9454c12e70b10156361e414944823ba23e80662c16c7ced0a2ce"
2358
2323
  },
2359
- publicInputCount: 18,
2324
+ publicInputCount: 20,
2360
2325
  public: [
2361
2326
  {
2362
2327
  name: "chain_id",
@@ -2438,6 +2403,16 @@ var witness_layouts_default = {
2438
2403
  count: 1,
2439
2404
  array: true
2440
2405
  },
2406
+ {
2407
+ name: "current_day",
2408
+ count: 1,
2409
+ array: false
2410
+ },
2411
+ {
2412
+ name: "current_month",
2413
+ count: 1,
2414
+ array: false
2415
+ },
2441
2416
  {
2442
2417
  name: "auth_digest_high",
2443
2418
  count: 1,
@@ -2462,15 +2437,22 @@ var witness_layouts_default = {
2462
2437
  "leaf_indices",
2463
2438
  "merkle_paths",
2464
2439
  "input_source_indices",
2465
- "draw_amounts"
2440
+ "draw_amounts",
2441
+ "single_limits",
2442
+ "daily_limits",
2443
+ "monthly_limits",
2444
+ "last_days",
2445
+ "daily_spents",
2446
+ "last_months",
2447
+ "monthly_spents"
2466
2448
  ]
2467
2449
  },
2468
2450
  credit_draw_slots12: {
2469
- artifactSha256: "92b741e161a99c05b8810bc24cee6bafc1cebc85347ea47fe511ee6c8f7065be",
2451
+ artifactSha256: "dd72b0867fc3be7cd90de263bd2d0892075cb18eb4f6dd671b13111710f10369",
2470
2452
  keys: {
2471
- evm: "a5ae214784fe6e523977ef4e283a6d217fc3f4ec0c5a40effb275693a74ee5ce"
2453
+ evm: "5e31d771e6294993736078596d9c69f21fe7595eda50e3cce6d7406b65cf1443"
2472
2454
  },
2473
- publicInputCount: 84,
2455
+ publicInputCount: 86,
2474
2456
  public: [
2475
2457
  {
2476
2458
  name: "chain_id",
@@ -2552,6 +2534,16 @@ var witness_layouts_default = {
2552
2534
  count: 12,
2553
2535
  array: true
2554
2536
  },
2537
+ {
2538
+ name: "current_day",
2539
+ count: 1,
2540
+ array: false
2541
+ },
2542
+ {
2543
+ name: "current_month",
2544
+ count: 1,
2545
+ array: false
2546
+ },
2555
2547
  {
2556
2548
  name: "auth_digest_high",
2557
2549
  count: 1,
@@ -2576,15 +2568,22 @@ var witness_layouts_default = {
2576
2568
  "leaf_indices",
2577
2569
  "merkle_paths",
2578
2570
  "input_source_indices",
2579
- "draw_amounts"
2571
+ "draw_amounts",
2572
+ "single_limits",
2573
+ "daily_limits",
2574
+ "monthly_limits",
2575
+ "last_days",
2576
+ "daily_spents",
2577
+ "last_months",
2578
+ "monthly_spents"
2580
2579
  ]
2581
2580
  },
2582
2581
  credit_draw_slots50: {
2583
- artifactSha256: "9c6a23d5dbca3a1aeed461c908f228e89642550775cbc519d633bb1c984a3d04",
2582
+ artifactSha256: "09c7469866748b4c0c4bbf2b040844771948a170999f6dc7a38fe5c0ecda4054",
2584
2583
  keys: {
2585
- evm: "f0b192e2cb312148c7a16fae3acaed9efb01b0c6a1b381ce03468f00b4ef0f2a"
2584
+ evm: "7b613225b6f32a077011d4196c356e836d22dcd116efe687fde53144fbd8db9f"
2586
2585
  },
2587
- publicInputCount: 312,
2586
+ publicInputCount: 314,
2588
2587
  public: [
2589
2588
  {
2590
2589
  name: "chain_id",
@@ -2666,6 +2665,16 @@ var witness_layouts_default = {
2666
2665
  count: 50,
2667
2666
  array: true
2668
2667
  },
2668
+ {
2669
+ name: "current_day",
2670
+ count: 1,
2671
+ array: false
2672
+ },
2673
+ {
2674
+ name: "current_month",
2675
+ count: 1,
2676
+ array: false
2677
+ },
2669
2678
  {
2670
2679
  name: "auth_digest_high",
2671
2680
  count: 1,
@@ -2690,15 +2699,22 @@ var witness_layouts_default = {
2690
2699
  "leaf_indices",
2691
2700
  "merkle_paths",
2692
2701
  "input_source_indices",
2693
- "draw_amounts"
2702
+ "draw_amounts",
2703
+ "single_limits",
2704
+ "daily_limits",
2705
+ "monthly_limits",
2706
+ "last_days",
2707
+ "daily_spents",
2708
+ "last_months",
2709
+ "monthly_spents"
2694
2710
  ]
2695
2711
  },
2696
2712
  credit_draw_slots120: {
2697
- artifactSha256: "69686a4f0a8a98d8cef06485b0de1804ca2e8f47ce0244287a03ceef4d67625a",
2713
+ artifactSha256: "6ccd0366a669c50fd5da875c3eae194fe8aa4c36d35a5f9ebfd64636ea599b48",
2698
2714
  keys: {
2699
- evm: "6f32ca89775f332a9193af9b1e25641ef14fda9fbdd2685c33ee775d3c170b92"
2715
+ evm: "d715848afc5c1ecdfcef5ed5026865abef5040a3bc232fd65330a5ffee8475fb"
2700
2716
  },
2701
- publicInputCount: 732,
2717
+ publicInputCount: 734,
2702
2718
  public: [
2703
2719
  {
2704
2720
  name: "chain_id",
@@ -2780,6 +2796,16 @@ var witness_layouts_default = {
2780
2796
  count: 120,
2781
2797
  array: true
2782
2798
  },
2799
+ {
2800
+ name: "current_day",
2801
+ count: 1,
2802
+ array: false
2803
+ },
2804
+ {
2805
+ name: "current_month",
2806
+ count: 1,
2807
+ array: false
2808
+ },
2783
2809
  {
2784
2810
  name: "auth_digest_high",
2785
2811
  count: 1,
@@ -2804,13 +2830,20 @@ var witness_layouts_default = {
2804
2830
  "leaf_indices",
2805
2831
  "merkle_paths",
2806
2832
  "input_source_indices",
2807
- "draw_amounts"
2833
+ "draw_amounts",
2834
+ "single_limits",
2835
+ "daily_limits",
2836
+ "monthly_limits",
2837
+ "last_days",
2838
+ "daily_spents",
2839
+ "last_months",
2840
+ "monthly_spents"
2808
2841
  ]
2809
2842
  },
2810
2843
  credit_cancel: {
2811
- artifactSha256: "ff278a04f22d2886c9f27f7785a0b8fc317dd242fd4aa9d0d9398d18b7513daf",
2844
+ artifactSha256: "b4459c2cf756d096e37291cf4d7cd129866b6d420b6d03c928f383b057112ccb",
2812
2845
  keys: {
2813
- evm: "1f8a3c20cb081d6a90962556da3124919cc4e5675e59ad31562af39299da02fb"
2846
+ evm: "fc8ad196ef15f3328afcc8f01d867a3ebefd15451c2813948442fab1923b73b2"
2814
2847
  },
2815
2848
  publicInputCount: 11,
2816
2849
  public: [
@@ -2880,14 +2913,21 @@ var witness_layouts_default = {
2880
2913
  "input_nonce",
2881
2914
  "expiry",
2882
2915
  "credit_shared_key",
2916
+ "single_limit",
2917
+ "daily_limit",
2918
+ "monthly_limit",
2919
+ "last_day",
2920
+ "daily_spent",
2921
+ "last_month",
2922
+ "monthly_spent",
2883
2923
  "leaf_index",
2884
2924
  "merkle_path"
2885
2925
  ]
2886
2926
  },
2887
2927
  credit_top_up: {
2888
- artifactSha256: "fbe662363d9814983f7940f74369117cd6c84783945fbf527b0ed48d011b58a4",
2928
+ artifactSha256: "2ffebd5753ec1b0c050204d4f97498765fe61ea01a793a9b2466c2f97536345c",
2889
2929
  keys: {
2890
- evm: "44436f31414497a708355426da051ee48ba63fdebcb6cfd72347c37c34c98c50"
2930
+ evm: "40b02a9d2e7eb7b49daaac4b7760328537b7982fd5a225cc065bb74cd5ef44b3"
2891
2931
  },
2892
2932
  publicInputCount: 50,
2893
2933
  public: [
@@ -3022,6 +3062,16 @@ var witness_layouts_default = {
3022
3062
  "credit_amount",
3023
3063
  "credit_nonce",
3024
3064
  "credit_shared_key",
3065
+ "single_limit",
3066
+ "daily_limit",
3067
+ "monthly_limit",
3068
+ "previous_single_limit",
3069
+ "previous_daily_limit",
3070
+ "previous_monthly_limit",
3071
+ "last_day",
3072
+ "daily_spent",
3073
+ "last_month",
3074
+ "monthly_spent",
3025
3075
  "change_amount",
3026
3076
  "change_nonce",
3027
3077
  "previous_credit_amount",
@@ -3037,6 +3087,20 @@ var pad2 = (values, count, zero) => {
3037
3087
  if (values.length > count) throw new Error("witness capacity exceeded");
3038
3088
  return [...values, ...Array.from({ length: count - values.length }, zero)];
3039
3089
  };
3090
+ var policyWitness = (note, usage = true) => {
3091
+ const p = normalizeCreditPolicy(note);
3092
+ return {
3093
+ single_limit: p.singleLimit,
3094
+ daily_limit: p.dailyLimit,
3095
+ monthly_limit: p.monthlyLimit,
3096
+ ...usage ? {
3097
+ last_day: p.lastDay,
3098
+ daily_spent: p.dailySpent,
3099
+ last_month: p.lastMonth,
3100
+ monthly_spent: p.monthlySpent
3101
+ } : {}
3102
+ };
3103
+ };
3040
3104
  var zeros = () => Array(16).fill(0n);
3041
3105
  var zeroAuthority = () => ({
3042
3106
  public_key_x: Array(32).fill(0),
@@ -3146,9 +3210,9 @@ var WitnessBuilder = class {
3146
3210
  }
3147
3211
  async noteLeaf(note) {
3148
3212
  this.context(note);
3149
- return computeNoteCommitment4(
3213
+ return computeNoteCommitment3(
3150
3214
  note.chainId,
3151
- await computeNoteIdentity3(BigInt(note.walletIdentity), note.nonce),
3215
+ await computeNoteIdentity2(BigInt(note.walletIdentity), note.nonce),
3152
3216
  note.tokenAddress,
3153
3217
  note.amount
3154
3218
  );
@@ -3165,7 +3229,8 @@ var WitnessBuilder = class {
3165
3229
  note.amount,
3166
3230
  note.nonce,
3167
3231
  note.expiry,
3168
- await computeCreditSharedKeyHash2(note.creditSharedKey)
3232
+ await computeCreditSharedKeyHash2(note.creditSharedKey),
3233
+ note
3169
3234
  );
3170
3235
  }
3171
3236
  async noteInputs(inputs, sources, nullifiers, identity, authority) {
@@ -3175,7 +3240,7 @@ var WitnessBuilder = class {
3175
3240
  check2(input.note.walletIdentity === identity, "input wallet mismatch");
3176
3241
  const leaf = await this.noteLeaf(input.note);
3177
3242
  check2(
3178
- await computeNoteNullifier2(input.note.chainId, input.note.nonce, leaf) === nullifiers[i],
3243
+ await computeNoteNullifier(input.note.chainId, input.note.nonce, leaf) === nullifiers[i],
3179
3244
  "input nullifier mismatch"
3180
3245
  );
3181
3246
  return BigInt(await this.membership(leaf, input, sources));
@@ -3249,6 +3314,8 @@ var WitnessBuilder = class {
3249
3314
  await this.creditLeaf(note) === p.params.creditCommitment && note.ownerPayout === BigInt(p.params.owner) && note.expiry === p.params.expiry,
3250
3315
  "Credit creation mismatch"
3251
3316
  );
3317
+ if (operation === "create-credit" && [note.lastDay, note.dailySpent, note.lastMonth, note.monthlySpent].some((v) => v !== 0n))
3318
+ throw new Error("new Credit usage must be zero");
3252
3319
  const authority = await this.authority(
3253
3320
  operation,
3254
3321
  10,
@@ -3295,6 +3362,7 @@ var WitnessBuilder = class {
3295
3362
  spender_payout: note.spenderPayout,
3296
3363
  spender_wallet_identity: BigInt(note.spenderWalletIdentity),
3297
3364
  owner_wallet_identity: BigInt(note.ownerWalletIdentity),
3365
+ ...policyWitness(note, operation === "top-up-credit"),
3298
3366
  credit_amount: note.amount,
3299
3367
  credit_nonce: note.nonce,
3300
3368
  credit_shared_key: note.creditSharedKey,
@@ -3336,6 +3404,7 @@ var WitnessBuilder = class {
3336
3404
  spender_payout: note.spenderPayout,
3337
3405
  spender_wallet_identity: BigInt(note.spenderWalletIdentity),
3338
3406
  owner_wallet_identity: BigInt(note.ownerWalletIdentity),
3407
+ ...policyWitness(note),
3339
3408
  input_nonce: note.nonce,
3340
3409
  expiry: note.expiry,
3341
3410
  credit_shared_key: note.creditSharedKey,
@@ -3346,7 +3415,7 @@ var WitnessBuilder = class {
3346
3415
  );
3347
3416
  }
3348
3417
  async drawCredit(p) {
3349
- const c = this.#protocol.context, profile = selectCreditDrawCircuit(p.inputs.length), capacity = profile.maxSize;
3418
+ const c = { ...this.#protocol.context, timestamp: p.timestamp }, profile = selectCreditDrawCircuit(p.inputs.length), capacity = profile.maxSize;
3350
3419
  check2(
3351
3420
  p.inputs.length === p.amounts.length && p.inputs.length === p.params.nullifiers.length,
3352
3421
  "draw input count mismatch"
@@ -3361,6 +3430,7 @@ var WitnessBuilder = class {
3361
3430
  );
3362
3431
  const sourceIndices = await Promise.all(
3363
3432
  notes2.map(async (note, i) => {
3433
+ applyCreditDrawUsage(note, p.amounts[i], p.timestamp);
3364
3434
  const leaf = await this.creditLeaf(note);
3365
3435
  check2(
3366
3436
  note.spenderWalletIdentity === identity && note.spenderPayout === BigInt(p.params.spender) && note.expiry === p.params.expiries[i] && p.amounts[i] > 0n && p.amounts[i] <= note.amount && await computeCreditNullifier(c.chainId, note.creditSharedKey, leaf) === p.params.nullifiers[i],
@@ -3373,6 +3443,26 @@ var WitnessBuilder = class {
3373
3443
  profile.name,
3374
3444
  {
3375
3445
  ...authority,
3446
+ ...Object.fromEntries(
3447
+ Object.entries({
3448
+ singleLimit: "single_limits",
3449
+ dailyLimit: "daily_limits",
3450
+ monthlyLimit: "monthly_limits",
3451
+ lastDay: "last_days",
3452
+ dailySpent: "daily_spents",
3453
+ lastMonth: "last_months",
3454
+ monthlySpent: "monthly_spents"
3455
+ }).map(([key, name]) => [
3456
+ name,
3457
+ pad2(
3458
+ notes2.map(
3459
+ (note) => normalizeCreditPolicy(note)[key]
3460
+ ),
3461
+ capacity,
3462
+ () => 0n
3463
+ )
3464
+ ])
3465
+ ),
3376
3466
  spender_wallet_identity: BigInt(identity),
3377
3467
  owner_payouts: pad2(
3378
3468
  notes2.map((note) => note.ownerPayout),
@@ -3422,7 +3512,11 @@ var WitnessBuilder = class {
3422
3512
  "ownerWalletIdentity",
3423
3513
  "spenderPayout",
3424
3514
  "ownerPayout",
3425
- "creditSharedKey"
3515
+ "creditSharedKey",
3516
+ "lastDay",
3517
+ "dailySpent",
3518
+ "lastMonth",
3519
+ "monthlySpent"
3426
3520
  ])
3427
3521
  check2(old[field2] === note[field2], "Credit role or payout changed");
3428
3522
  check2(
@@ -3443,6 +3537,9 @@ var WitnessBuilder = class {
3443
3537
  "credit_top_up",
3444
3538
  {
3445
3539
  ...base,
3540
+ previous_single_limit: old.singleLimit,
3541
+ previous_daily_limit: old.dailyLimit,
3542
+ previous_monthly_limit: old.monthlyLimit,
3446
3543
  previous_credit_amount: old.amount,
3447
3544
  previous_credit_nonce: old.nonce,
3448
3545
  previous_credit_leaf_index: BigInt(p.previous.leafIndex),
@@ -3487,7 +3584,6 @@ export {
3487
3584
  buildTopUpCreditCalldata,
3488
3585
  buildTransactAggregateCalldata,
3489
3586
  buildTransactCalldata,
3490
- buildWithdrawalCalldata,
3491
3587
  cancelCreditBaseInputs,
3492
3588
  cancelCreditPublicInputs,
3493
3589
  cancelCreditRequestHash,
@@ -3517,8 +3613,8 @@ export {
3517
3613
  getEIP712Domain,
3518
3614
  known,
3519
3615
  normalizeContext,
3520
- normalizeDelivery,
3521
3616
  normalizeFunding,
3617
+ normalizeOpaqueDelivery,
3522
3618
  normalizeSources,
3523
3619
  normalizeTransactRequest,
3524
3620
  notes,