@provex/react 1.9.2 → 1.10.0-rc.20260912192040.fdbb8fc

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.cjs CHANGED
@@ -13,6 +13,7 @@ var reputation = require('@provex/utils/reputation');
13
13
  var contracts = require('@provex/utils/contracts');
14
14
  var proving = require('@provex/proving');
15
15
  var utils = require('@provex/utils');
16
+ var deposit = require('@provex/utils/deposit');
16
17
  var fees = require('@provex/utils/fees');
17
18
  var abis = require('@provex/abis');
18
19
  var chain = require('@provex/utils/chain');
@@ -115,22 +116,9 @@ function getRate({
115
116
  currency
116
117
  }) {
117
118
  if (!deposit) return 0n;
118
- const paymentConfig = payment.providerConfigs(deposit.chainId)[paymentMethod];
119
- const candidateKeys = [
120
- paymentMethod,
121
- ...Array.from(paymentConfig?.subProviders ?? []).map((sp) => sp.key)
122
- ];
123
- let minRate = null;
124
- for (const key of candidateKeys) {
125
- const contractId = payment.providerKeyToContractId(key).toLowerCase();
126
- const value = deposit.conversionRates.get(contractId)?.get(currency.contractId.toLowerCase());
127
- if (value) {
128
- if (minRate === null || value < minRate) {
129
- minRate = value;
130
- }
131
- }
132
- }
133
- return minRate ?? 0n;
119
+ const contractId = payment.providerKeyToContractId(paymentMethod).toLowerCase();
120
+ const value = deposit.conversionRates.get(contractId)?.get(currency.contractId.toLowerCase());
121
+ return value ?? 0n;
134
122
  }
135
123
  function toDepositInfo(deposit) {
136
124
  return {
@@ -163,11 +151,7 @@ function useDeposits(options) {
163
151
  const paymentConfig = payment.providerConfigs(token.chainId)[paymentMethod];
164
152
  return /* @__PURE__ */ new Set([
165
153
  payment.providerKeyToContractId(paymentMethod).toLowerCase(),
166
- ...paymentConfig.v2Verifiers.map((v) => v.toLowerCase()),
167
- ...Array.from(paymentConfig.subProviders).flatMap((subProvider) => [
168
- payment.providerKeyToContractId(subProvider.key).toLowerCase(),
169
- ...subProvider.v2Verifiers(token.chainId).map((v) => v.toLowerCase())
170
- ])
154
+ ...paymentConfig.v2Verifiers.map((v) => v.toLowerCase())
171
155
  ]);
172
156
  }, [token.chainId, paymentMethod]);
173
157
  const depositsQuery = reactQuery.useQuery({
@@ -401,82 +385,85 @@ var ProveXClient = class {
401
385
  this.onSlowSync = config.onSlowSync;
402
386
  this.apiUrl = config.apiUrl ?? defaults?.apiUrl ?? "https://app.provex.com";
403
387
  this.createDepositRaw = this.buildWritableMethod({
404
- abi: abis.V3EscrowAbi,
388
+ abi: () => this.getEscrowAbi(),
405
389
  contractResolver: () => this.getEscrowAddress(),
406
390
  functionName: "createDeposit",
407
- argsMapper: (params) => [params]
391
+ argsMapper: (params) => [{
392
+ ...params,
393
+ currencies: params.currencies.map((perMethod) => deposit.toEscrowCurrencies(perMethod, this.getEscrowGeneration()))
394
+ }]
408
395
  });
409
396
  this.addFunds = this.buildWritableMethod({
410
- abi: abis.V3EscrowAbi,
397
+ abi: () => this.getEscrowAbi(),
411
398
  contractResolver: () => this.getEscrowAddress(),
412
399
  functionName: "addFunds",
413
400
  argsMapper: (params) => [params.depositId, params.amount]
414
401
  });
415
402
  this.removeFunds = this.buildWritableMethod({
416
- abi: abis.V3EscrowAbi,
403
+ abi: () => this.getEscrowAbi(),
417
404
  contractResolver: () => this.getEscrowAddress(),
418
405
  functionName: "removeFunds",
419
406
  argsMapper: (params) => [params.depositId, params.amount]
420
407
  });
421
408
  this.withdrawDeposit = this.buildWritableMethod({
422
- abi: abis.V3EscrowAbi,
409
+ abi: () => this.getEscrowAbi(),
423
410
  contractResolver: () => this.getEscrowAddress(),
424
411
  functionName: "withdrawDeposit",
425
412
  argsMapper: (params) => [params.depositId]
426
413
  });
427
414
  this.pruneExpiredIntents = this.buildWritableMethod({
428
- abi: abis.V3EscrowAbi,
415
+ abi: () => this.getEscrowAbi(),
429
416
  contractResolver: () => this.getEscrowAddress(),
430
417
  functionName: "pruneExpiredIntents",
431
418
  argsMapper: (params) => [params.depositId]
432
419
  });
433
420
  this.setAcceptingIntents = this.buildWritableMethod({
434
- abi: abis.V3EscrowAbi,
421
+ abi: () => this.getEscrowAbi(),
435
422
  contractResolver: () => this.getEscrowAddress(),
436
423
  functionName: "setAcceptingIntents",
437
424
  argsMapper: (params) => [params.depositId, params.accepting]
438
425
  });
439
426
  this.setRetainOnEmpty = this.buildWritableMethod({
440
- abi: abis.V3EscrowAbi,
427
+ abi: () => this.getEscrowAbi(),
441
428
  contractResolver: () => this.getEscrowAddress(),
442
429
  functionName: "setRetainOnEmpty",
443
430
  argsMapper: (params) => [params.depositId, params.retain]
444
431
  });
445
432
  this.setIntentRange = this.buildWritableMethod({
446
- abi: abis.V3EscrowAbi,
433
+ abi: () => this.getEscrowAbi(),
447
434
  contractResolver: () => this.getEscrowAddress(),
448
435
  functionName: "setIntentRange",
449
436
  argsMapper: (params) => [params.depositId, { min: params.min, max: params.max }]
450
437
  });
451
438
  this.setPaymentMethodActive = this.buildWritableMethod({
452
- abi: abis.V3EscrowAbi,
439
+ abi: () => this.getEscrowAbi(),
453
440
  contractResolver: () => this.getEscrowAddress(),
454
441
  functionName: "setPaymentMethodActive",
455
442
  argsMapper: (params) => [params.depositId, params.paymentMethod, params.active]
456
443
  });
457
444
  this.setCurrencyMinRate = this.buildWritableMethod({
458
- abi: abis.V3EscrowAbi,
445
+ abi: () => this.getEscrowAbi(),
459
446
  contractResolver: () => this.getEscrowAddress(),
460
447
  functionName: "setCurrencyMinRate",
461
448
  argsMapper: (params) => [params.depositId, params.paymentMethod, params.currency, params.rate]
462
449
  });
463
450
  this.addCurrencies = this.buildWritableMethod({
464
- abi: abis.V3EscrowAbi,
451
+ abi: () => this.getEscrowAbi(),
465
452
  contractResolver: () => this.getEscrowAddress(),
466
453
  functionName: "addCurrencies",
467
- argsMapper: (params) => [params.depositId, params.paymentMethod, params.currencies]
454
+ argsMapper: (params) => [params.depositId, params.paymentMethod, deposit.toEscrowCurrencies(params.currencies, this.getEscrowGeneration())]
468
455
  });
469
456
  this.deactivateCurrency = this.buildWritableMethod({
470
- abi: abis.V3EscrowAbi,
457
+ abi: () => this.getEscrowAbi(),
471
458
  contractResolver: () => this.getEscrowAddress(),
472
459
  functionName: "deactivateCurrency",
473
460
  argsMapper: (params) => [params.depositId, params.paymentMethod, params.currencyCode]
474
461
  });
475
462
  this.addPaymentMethods = this.buildWritableMethod({
476
- abi: abis.V3EscrowAbi,
463
+ abi: () => this.getEscrowAbi(),
477
464
  contractResolver: () => this.getEscrowAddress(),
478
465
  functionName: "addPaymentMethods",
479
- argsMapper: (params) => [params.depositId, params.paymentMethods, params.paymentMethodData, params.currencies]
466
+ argsMapper: (params) => [params.depositId, params.paymentMethods, params.paymentMethodData, params.currencies.map((perMethod) => deposit.toEscrowCurrencies(perMethod, this.getEscrowGeneration()))]
480
467
  });
481
468
  this.cancelIntent = this.buildWritableMethod({
482
469
  abi: abis.OrchestratorAbi,
@@ -511,17 +498,66 @@ var ProveXClient = class {
511
498
  });
512
499
  }
513
500
  // ─── Address Resolution ──────────────────────────────────────────────────
514
- /** Get the V3 escrow address for this client's chain. */
501
+ /**
502
+ * The escrow this client acts on.
503
+ *
504
+ * Callers that touch a specific deposit MUST construct the client with
505
+ * `escrowAddress: deposit.escrow` — the fallback below is only correct for a
506
+ * client that has no deposit in hand, and silently sends every write to the
507
+ * wrong escrow otherwise.
508
+ *
509
+ * That fallback follows the chain's current generation rather than a pinned
510
+ * v3. The only writes that reach it are ones with no existing deposit to
511
+ * name — `createDeposit` above all — and those belong on the generation the
512
+ * protocol is actually running, not the one it has moved off.
513
+ */
515
514
  getEscrowAddress() {
516
515
  if (this.escrowOverride) return this.escrowOverride;
517
- const addr = contracts.getLatestContract(this.chainId, "escrow", "v3");
518
- if (!addr) throw new ProveXError("VALIDATION_ERROR", `No V3 escrow found for chain ${this.chainId}`);
516
+ const addr = contracts.getLatestContract(this.chainId, "escrow", contracts.getLatestConfiguredVersion(this.chainId));
517
+ if (!addr) throw new ProveXError("VALIDATION_ERROR", `No escrow configured for chain ${this.chainId}`);
519
518
  return addr;
520
519
  }
521
- /** Get the orchestrator address (cached after first read). */
520
+ /**
521
+ * The escrow's generation, used to pick the matching interface.
522
+ *
523
+ * An unrecognised address is not an error: callers may point the client at a
524
+ * fork or a local deployment through `escrowAddress`. Those fall back to v3,
525
+ * which is what this client assumed for every escrow before generations were
526
+ * resolved at all — so an override that worked before still works.
527
+ */
528
+ getEscrowGeneration() {
529
+ return contracts.getEscrowVersion(this.getEscrowAddress(), this.chainId) ?? "v3";
530
+ }
531
+ /**
532
+ * The escrow interface matching this client's escrow generation.
533
+ *
534
+ * EscrowV2 is not signature-compatible with the v3 escrow for every maker
535
+ * write — `createDeposit`, `addPaymentMethods` and `addCurrencies` each gain
536
+ * an oracle rate config in their currency tuple, which changes the selector.
537
+ * Binding one generation's interface to whatever address we resolved
538
+ * produces a call the contract cannot decode, and since these writes are not
539
+ * simulated the maker signs and pays gas for a certain revert.
540
+ */
541
+ getEscrowAbi() {
542
+ return abis.escrowAbiByVersion[this.getEscrowGeneration()];
543
+ }
544
+ /**
545
+ * Get the orchestrator address (cached after first read).
546
+ *
547
+ * Generation decides where this comes from. v2 and v3 escrows expose
548
+ * `orchestrator()`; EscrowV2 authorizes through an `OrchestratorRegistry`
549
+ * and exposes no such function, so reading it reverts and the address has to
550
+ * come from configuration. Probing on-chain first would therefore break
551
+ * every v4 flow before the wallet ever opens.
552
+ */
522
553
  async getOrchestratorAddress() {
523
554
  if (this.cachedOrchestratorAddress) return this.cachedOrchestratorAddress;
524
555
  const escrow = this.getEscrowAddress();
556
+ const configured = contracts.getConfiguredOrchestratorForEscrow(escrow);
557
+ if (configured) {
558
+ this.cachedOrchestratorAddress = configured;
559
+ return configured;
560
+ }
525
561
  const result = await this.readContract({
526
562
  address: escrow,
527
563
  abi: abis.V3EscrowAbi,
@@ -671,34 +707,16 @@ var ProveXClient = class {
671
707
  }
672
708
  /**
673
709
  * Convert human-readable deposit params to raw contract params.
674
- * Handles provider expansion, hashing, gating service encoding, and defaults.
710
+ * Handles rail collapsing, hashing, gating service encoding, and defaults.
675
711
  */
676
712
  buildCreateDepositRawParams(params) {
677
- const expanded = [];
678
- const configs = payment.providerConfigs(this.chainId);
679
- for (const pm of params.paymentMethods) {
680
- const hash = payment.computePayeeDetailsHash(pm.payeeId);
681
- const config = configs[pm.provider];
682
- if (config?.subProviders && config.subProviders.size > 0) {
683
- for (const sub of config.subProviders) {
684
- expanded.push({
685
- providerKey: sub.key,
686
- payeeDetailsHash: hash,
687
- currencies: pm.currencies,
688
- intentGatingService: pm.intentGatingService,
689
- data: pm.data
690
- });
691
- }
692
- } else {
693
- expanded.push({
694
- providerKey: pm.provider,
695
- payeeDetailsHash: hash,
696
- currencies: pm.currencies,
697
- intentGatingService: pm.intentGatingService,
698
- data: pm.data
699
- });
700
- }
701
- }
713
+ const collapsed = params.paymentMethods.map((pm) => ({
714
+ providerKey: payment.resolveRailProviderKey(pm.provider),
715
+ payeeDetailsHash: payment.computePayeeDetailsHash(pm.payeeId),
716
+ currencies: pm.currencies,
717
+ intentGatingService: pm.intentGatingService,
718
+ data: pm.data
719
+ }));
702
720
  const defaultGatingData = viem.encodeAbiParameters(
703
721
  viem.parseAbiParameters(["address[]"]),
704
722
  [[contracts.reclaimSigners.peerWitnessSigner, contracts.reclaimSigners.reclaimWitnessSigner]]
@@ -711,13 +729,13 @@ var ProveXClient = class {
711
729
  min: params.intentRange?.min ?? 1000000n,
712
730
  max: params.intentRange?.max ?? params.amount
713
731
  },
714
- paymentMethods: expanded.map((p) => payment.providerKeyToContractId(p.providerKey)),
715
- paymentMethodData: expanded.map((p) => ({
732
+ paymentMethods: collapsed.map((p) => payment.providerKeyToContractId(p.providerKey)),
733
+ paymentMethodData: collapsed.map((p) => ({
716
734
  intentGatingService: p.intentGatingService ?? defaultGatingService,
717
735
  payeeDetails: p.payeeDetailsHash,
718
736
  data: p.data ?? defaultGatingData
719
737
  })),
720
- currencies: expanded.map(
738
+ currencies: collapsed.map(
721
739
  (p) => p.currencies.map((c) => ({
722
740
  code: currencies.tickerToContractId(c.code),
723
741
  minConversionRate: c.minRate
@@ -1028,7 +1046,7 @@ var ProveXClient = class {
1028
1046
  const to = await contractResolver(params);
1029
1047
  const args = argsMapper(params);
1030
1048
  const data = viem.encodeFunctionData({
1031
- abi,
1049
+ abi: typeof abi === "function" ? abi() : abi,
1032
1050
  functionName,
1033
1051
  args
1034
1052
  });
@@ -1519,16 +1537,34 @@ function useOrchestratorAddress({
1519
1537
  chainId,
1520
1538
  enabled = true
1521
1539
  }) {
1522
- return useContractRead({
1540
+ const configuredOrchestrator = react.useMemo(
1541
+ () => escrowAddress ? contracts.getConfiguredOrchestratorForEscrow(escrowAddress) : null,
1542
+ [escrowAddress]
1543
+ );
1544
+ const query = useContractRead({
1523
1545
  address: escrowAddress,
1524
1546
  abi: abis.V3EscrowAbi,
1525
1547
  functionName: "orchestrator",
1526
1548
  chainId,
1527
1549
  query: {
1528
- enabled: enabled && !!escrowAddress,
1550
+ enabled: enabled && !!escrowAddress && !configuredOrchestrator,
1529
1551
  staleTime: Infinity
1530
1552
  }
1531
1553
  });
1554
+ return react.useMemo(() => {
1555
+ if (!configuredOrchestrator) return query;
1556
+ return {
1557
+ ...query,
1558
+ data: configuredOrchestrator,
1559
+ isLoading: false,
1560
+ isPending: false,
1561
+ isFetching: false,
1562
+ isSuccess: true,
1563
+ isError: false,
1564
+ error: null,
1565
+ status: "success"
1566
+ };
1567
+ }, [query, configuredOrchestrator]);
1532
1568
  }
1533
1569
  var FEE_CACHE_STALE_TIME = 60 * 60 * 1e3;
1534
1570
  function useProtocolFees({
@@ -1847,7 +1883,7 @@ function useProvexBuy({
1847
1883
  );
1848
1884
  const attestationBaseUrl = config.apiUrl;
1849
1885
  const verifyingContract = react.useMemo(
1850
- () => contracts.getLatestContract(chainId, "unifiedPaymentVerifier", "v3"),
1886
+ () => contracts.getPaymentAttestationVerifier(chainId),
1851
1887
  [chainId]
1852
1888
  );
1853
1889
  const captureRequest = react.useMemo(() => {
@@ -2787,7 +2823,7 @@ var useV3Escrow = ({
2787
2823
  const escrow = react.useMemo(() => {
2788
2824
  if (escrowAddress) return escrowAddress;
2789
2825
  if (!chainId) return null;
2790
- return contracts.getLatestContract(chainId, "escrow", "v3");
2826
+ return contracts.getLatestContract(chainId, "escrow", contracts.getLatestConfiguredVersion(chainId));
2791
2827
  }, [chainId, escrowAddress]);
2792
2828
  const isLoading = react.useMemo(
2793
2829
  () => status === "prompt_wallet_confirm" || status === "writing_tx" || status === "confirming" || status === "syncing",