@b3dotfun/sdk 0.1.65 → 0.1.66-alpha.0

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.
Files changed (116) hide show
  1. package/dist/cjs/anyspend/react/components/AnySpend.d.ts +2 -0
  2. package/dist/cjs/anyspend/react/components/AnySpend.js +7 -16
  3. package/dist/cjs/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +6 -1
  4. package/dist/cjs/anyspend/react/components/AnySpendCollectorClubPurchase.js +151 -22
  5. package/dist/cjs/anyspend/react/components/AnySpendCustom.js +4 -50
  6. package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.d.ts +2 -0
  7. package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.js +4 -2
  8. package/dist/cjs/anyspend/react/components/AnySpendDeposit.d.ts +3 -1
  9. package/dist/cjs/anyspend/react/components/AnySpendDeposit.js +2 -2
  10. package/dist/cjs/anyspend/react/components/AnySpendWorkflowTrigger.d.ts +31 -0
  11. package/dist/cjs/anyspend/react/components/AnySpendWorkflowTrigger.js +14 -0
  12. package/dist/cjs/anyspend/react/components/QRDeposit.js +5 -13
  13. package/dist/cjs/anyspend/react/components/ccShopAbi.d.ts +113 -0
  14. package/dist/cjs/anyspend/react/components/ccShopAbi.js +63 -0
  15. package/dist/cjs/anyspend/react/components/common/CryptoPaySection.d.ts +1 -3
  16. package/dist/cjs/anyspend/react/components/common/CryptoPaySection.js +3 -3
  17. package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.d.ts +1 -4
  18. package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.js +3 -57
  19. package/dist/cjs/anyspend/react/components/common/PaySection.js +1 -1
  20. package/dist/cjs/anyspend/react/components/index.d.ts +2 -0
  21. package/dist/cjs/anyspend/react/components/index.js +3 -1
  22. package/dist/cjs/anyspend/react/hooks/index.d.ts +1 -0
  23. package/dist/cjs/anyspend/react/hooks/index.js +1 -0
  24. package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOnrampOrder.js +1 -0
  25. package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOrder.d.ts +1 -0
  26. package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOrder.js +1 -0
  27. package/dist/cjs/anyspend/react/hooks/useOnOrderSuccess.d.ts +10 -0
  28. package/dist/cjs/anyspend/react/hooks/useOnOrderSuccess.js +27 -0
  29. package/dist/cjs/anyspend/services/anyspend.d.ts +2 -1
  30. package/dist/cjs/anyspend/services/anyspend.js +2 -1
  31. package/dist/cjs/anyspend/utils/chain.d.ts +1 -1
  32. package/dist/cjs/anyspend/utils/chain.js +72 -62
  33. package/dist/cjs/global-account/react/components/B3DynamicModal.js +4 -0
  34. package/dist/cjs/global-account/react/hooks/useUserQuery.js +10 -0
  35. package/dist/cjs/global-account/react/stores/useModalStore.d.ts +37 -1
  36. package/dist/cjs/global-account/react/stores/userStore.js +1 -0
  37. package/dist/esm/anyspend/react/components/AnySpend.d.ts +2 -0
  38. package/dist/esm/anyspend/react/components/AnySpend.js +7 -16
  39. package/dist/esm/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +6 -1
  40. package/dist/esm/anyspend/react/components/AnySpendCollectorClubPurchase.js +152 -23
  41. package/dist/esm/anyspend/react/components/AnySpendCustom.js +4 -17
  42. package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.d.ts +2 -0
  43. package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.js +4 -2
  44. package/dist/esm/anyspend/react/components/AnySpendDeposit.d.ts +3 -1
  45. package/dist/esm/anyspend/react/components/AnySpendDeposit.js +2 -2
  46. package/dist/esm/anyspend/react/components/AnySpendWorkflowTrigger.d.ts +31 -0
  47. package/dist/esm/anyspend/react/components/AnySpendWorkflowTrigger.js +11 -0
  48. package/dist/esm/anyspend/react/components/QRDeposit.js +6 -14
  49. package/dist/esm/anyspend/react/components/ccShopAbi.d.ts +113 -0
  50. package/dist/esm/anyspend/react/components/ccShopAbi.js +60 -0
  51. package/dist/esm/anyspend/react/components/common/CryptoPaySection.d.ts +1 -3
  52. package/dist/esm/anyspend/react/components/common/CryptoPaySection.js +3 -3
  53. package/dist/esm/anyspend/react/components/common/OrderTokenAmount.d.ts +1 -4
  54. package/dist/esm/anyspend/react/components/common/OrderTokenAmount.js +2 -56
  55. package/dist/esm/anyspend/react/components/common/PaySection.js +1 -1
  56. package/dist/esm/anyspend/react/components/index.d.ts +2 -0
  57. package/dist/esm/anyspend/react/components/index.js +1 -0
  58. package/dist/esm/anyspend/react/hooks/index.d.ts +1 -0
  59. package/dist/esm/anyspend/react/hooks/index.js +1 -0
  60. package/dist/esm/anyspend/react/hooks/useAnyspendCreateOnrampOrder.js +1 -0
  61. package/dist/esm/anyspend/react/hooks/useAnyspendCreateOrder.d.ts +1 -0
  62. package/dist/esm/anyspend/react/hooks/useAnyspendCreateOrder.js +1 -0
  63. package/dist/esm/anyspend/react/hooks/useOnOrderSuccess.d.ts +10 -0
  64. package/dist/esm/anyspend/react/hooks/useOnOrderSuccess.js +24 -0
  65. package/dist/esm/anyspend/services/anyspend.d.ts +2 -1
  66. package/dist/esm/anyspend/services/anyspend.js +2 -1
  67. package/dist/esm/anyspend/utils/chain.d.ts +1 -1
  68. package/dist/esm/anyspend/utils/chain.js +72 -62
  69. package/dist/esm/global-account/react/components/B3DynamicModal.js +4 -0
  70. package/dist/esm/global-account/react/hooks/useUserQuery.js +11 -1
  71. package/dist/esm/global-account/react/stores/useModalStore.d.ts +37 -1
  72. package/dist/esm/global-account/react/stores/userStore.js +1 -0
  73. package/dist/types/anyspend/react/components/AnySpend.d.ts +2 -0
  74. package/dist/types/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +6 -1
  75. package/dist/types/anyspend/react/components/AnySpendCustomExactIn.d.ts +2 -0
  76. package/dist/types/anyspend/react/components/AnySpendDeposit.d.ts +3 -1
  77. package/dist/types/anyspend/react/components/AnySpendWorkflowTrigger.d.ts +31 -0
  78. package/dist/types/anyspend/react/components/ccShopAbi.d.ts +113 -0
  79. package/dist/types/anyspend/react/components/common/CryptoPaySection.d.ts +1 -3
  80. package/dist/types/anyspend/react/components/common/OrderTokenAmount.d.ts +1 -4
  81. package/dist/types/anyspend/react/components/index.d.ts +2 -0
  82. package/dist/types/anyspend/react/hooks/index.d.ts +1 -0
  83. package/dist/types/anyspend/react/hooks/useAnyspendCreateOrder.d.ts +1 -0
  84. package/dist/types/anyspend/react/hooks/useOnOrderSuccess.d.ts +10 -0
  85. package/dist/types/anyspend/services/anyspend.d.ts +2 -1
  86. package/dist/types/anyspend/utils/chain.d.ts +1 -1
  87. package/dist/types/global-account/react/stores/useModalStore.d.ts +37 -1
  88. package/package.json +1 -1
  89. package/src/anyspend/README.md +14 -0
  90. package/src/anyspend/docs/checkout-sessions.md +228 -0
  91. package/src/anyspend/docs/components.md +26 -0
  92. package/src/anyspend/docs/examples.md +58 -0
  93. package/src/anyspend/docs/hooks.md +32 -0
  94. package/src/anyspend/llms.txt +185 -0
  95. package/src/anyspend/react/components/AnySpend.tsx +9 -17
  96. package/src/anyspend/react/components/AnySpendCollectorClubPurchase.tsx +206 -22
  97. package/src/anyspend/react/components/AnySpendCustom.tsx +3 -18
  98. package/src/anyspend/react/components/AnySpendCustomExactIn.tsx +5 -1
  99. package/src/anyspend/react/components/AnySpendDeposit.tsx +5 -0
  100. package/src/anyspend/react/components/AnySpendWorkflowTrigger.tsx +73 -0
  101. package/src/anyspend/react/components/QRDeposit.tsx +19 -15
  102. package/src/anyspend/react/components/ccShopAbi.ts +64 -0
  103. package/src/anyspend/react/components/common/CryptoPaySection.tsx +0 -5
  104. package/src/anyspend/react/components/common/OrderTokenAmount.tsx +1 -70
  105. package/src/anyspend/react/components/common/PaySection.tsx +0 -1
  106. package/src/anyspend/react/components/index.ts +2 -0
  107. package/src/anyspend/react/hooks/index.ts +1 -0
  108. package/src/anyspend/react/hooks/useAnyspendCreateOnrampOrder.ts +1 -0
  109. package/src/anyspend/react/hooks/useAnyspendCreateOrder.ts +2 -0
  110. package/src/anyspend/react/hooks/useOnOrderSuccess.ts +36 -0
  111. package/src/anyspend/services/anyspend.ts +3 -0
  112. package/src/anyspend/utils/chain.ts +81 -65
  113. package/src/global-account/react/components/B3DynamicModal.tsx +4 -0
  114. package/src/global-account/react/hooks/useUserQuery.ts +12 -1
  115. package/src/global-account/react/stores/useModalStore.ts +39 -2
  116. package/src/global-account/react/stores/userStore.ts +1 -0
@@ -392,8 +392,8 @@ function getPaymentUrl(address, amount, currency, chainId, decimals) {
392
392
  // For EVM chains, follow EIP-681 format
393
393
  // Format: ethereum:[address]@[chainId]?value=[amount]&symbol=[symbol]
394
394
  const params = new URLSearchParams();
395
- // Add value for native token transfers
396
- if (currency === chain.nativeToken.symbol) {
395
+ // Add value for native token transfers (skip if amount not provided, e.g. deposit_first)
396
+ if (currency === chain.nativeToken.symbol && amount !== undefined) {
397
397
  params.append("value", amount.toString());
398
398
  }
399
399
  // Handle token transfers differently from native transfers
@@ -408,28 +408,31 @@ function getPaymentUrl(address, amount, currency, chainId, decimals) {
408
408
  }
409
409
  // For ERC20 tokens, convert from smallest unit to display units using decimals
410
410
  // For example: 2400623 (raw) with 6 decimals becomes "2.400623"
411
- let displayAmount;
412
- if (decimals !== undefined && currency !== chain.nativeToken.symbol) {
413
- // Convert from smallest unit to display unit for ERC20 tokens
414
- const divisor = BigInt(10 ** decimals);
415
- const wholePart = amount / divisor;
416
- const fractionalPart = amount % divisor;
417
- if (fractionalPart === BigInt(0)) {
418
- displayAmount = wholePart.toString();
411
+ // Skip amount if not provided (e.g. deposit_first orders)
412
+ if (amount !== undefined) {
413
+ let displayAmount;
414
+ if (decimals !== undefined && currency !== chain.nativeToken.symbol) {
415
+ // Convert from smallest unit to display unit for ERC20 tokens
416
+ const divisor = BigInt(10 ** decimals);
417
+ const wholePart = amount / divisor;
418
+ const fractionalPart = amount % divisor;
419
+ if (fractionalPart === BigInt(0)) {
420
+ displayAmount = wholePart.toString();
421
+ }
422
+ else {
423
+ // Format fractional part with leading zeros if needed
424
+ const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
425
+ // Remove trailing zeros
426
+ const trimmedFractional = fractionalStr.replace(/0+$/, "");
427
+ displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
428
+ }
419
429
  }
420
430
  else {
421
- // Format fractional part with leading zeros if needed
422
- const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
423
- // Remove trailing zeros
424
- const trimmedFractional = fractionalStr.replace(/0+$/, "");
425
- displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
431
+ // For native tokens or when decimals not provided, use raw amount
432
+ displayAmount = amount.toString();
426
433
  }
434
+ tokenParams.append("amount", displayAmount);
427
435
  }
428
- else {
429
- // For native tokens or when decimals not provided, use raw amount
430
- displayAmount = amount.toString();
431
- }
432
- tokenParams.append("amount", displayAmount);
433
436
  tokenParams.append("address", address); // recipient address
434
437
  // For Arbitrum and other L2s, try a more explicit format
435
438
  if (chainId !== chains_1.mainnet.id) {
@@ -449,7 +452,9 @@ function getPaymentUrl(address, amount, currency, chainId, decimals) {
449
452
  // to make sure wallets recognize the correct chain
450
453
  const nativeParams = new URLSearchParams();
451
454
  nativeParams.append("chainId", chainId.toString());
452
- nativeParams.append("value", amount.toString());
455
+ if (amount !== undefined) {
456
+ nativeParams.append("value", amount.toString());
457
+ }
453
458
  const url = `ethereum:${address}@${chainId}?${nativeParams.toString()}`;
454
459
  return url;
455
460
  }
@@ -468,60 +473,65 @@ function getPaymentUrl(address, amount, currency, chainId, decimals) {
468
473
  const isNativeSOL = currency === chain.nativeToken.symbol || currency === "SOL" || currency === "11111111111111111111111111111111";
469
474
  if (isNativeSOL) {
470
475
  // Native SOL transfers - convert from lamports to SOL
471
- let displayAmount;
472
- if (decimals !== undefined) {
473
- const divisor = BigInt(10 ** decimals);
474
- const wholePart = amount / divisor;
475
- const fractionalPart = amount % divisor;
476
- if (fractionalPart === BigInt(0)) {
477
- displayAmount = wholePart.toString();
478
- }
479
- else {
480
- const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
481
- const trimmedFractional = fractionalStr.replace(/0+$/, "");
482
- displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
483
- }
484
- }
485
- else {
486
- // Fallback: assume SOL has 9 decimals
487
- const divisor = BigInt(1000000000); // 1e9
488
- const wholePart = amount / divisor;
489
- const fractionalPart = amount % divisor;
490
- if (fractionalPart === BigInt(0)) {
491
- displayAmount = wholePart.toString();
476
+ if (amount !== undefined) {
477
+ let displayAmount;
478
+ if (decimals !== undefined) {
479
+ const divisor = BigInt(10 ** decimals);
480
+ const wholePart = amount / divisor;
481
+ const fractionalPart = amount % divisor;
482
+ if (fractionalPart === BigInt(0)) {
483
+ displayAmount = wholePart.toString();
484
+ }
485
+ else {
486
+ const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
487
+ const trimmedFractional = fractionalStr.replace(/0+$/, "");
488
+ displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
489
+ }
492
490
  }
493
491
  else {
494
- const fractionalStr = fractionalPart.toString().padStart(9, "0");
495
- const trimmedFractional = fractionalStr.replace(/0+$/, "");
496
- displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
492
+ // Fallback: assume SOL has 9 decimals
493
+ const divisor = BigInt(1000000000); // 1e9
494
+ const wholePart = amount / divisor;
495
+ const fractionalPart = amount % divisor;
496
+ if (fractionalPart === BigInt(0)) {
497
+ displayAmount = wholePart.toString();
498
+ }
499
+ else {
500
+ const fractionalStr = fractionalPart.toString().padStart(9, "0");
501
+ const trimmedFractional = fractionalStr.replace(/0+$/, "");
502
+ displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
503
+ }
497
504
  }
505
+ // For native SOL, use simple format without spl-token parameter
506
+ params.append("amount", displayAmount);
498
507
  }
499
- // For native SOL, use simple format without spl-token parameter
500
- params.append("amount", displayAmount);
501
508
  }
502
509
  else {
503
510
  // SPL token transfers
504
- let displayAmount;
505
- if (decimals !== undefined) {
506
- const divisor = BigInt(10 ** decimals);
507
- const wholePart = amount / divisor;
508
- const fractionalPart = amount % divisor;
509
- if (fractionalPart === BigInt(0)) {
510
- displayAmount = wholePart.toString();
511
+ if (amount !== undefined) {
512
+ let displayAmount;
513
+ if (decimals !== undefined) {
514
+ const divisor = BigInt(10 ** decimals);
515
+ const wholePart = amount / divisor;
516
+ const fractionalPart = amount % divisor;
517
+ if (fractionalPart === BigInt(0)) {
518
+ displayAmount = wholePart.toString();
519
+ }
520
+ else {
521
+ const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
522
+ const trimmedFractional = fractionalStr.replace(/0+$/, "");
523
+ displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
524
+ }
511
525
  }
512
526
  else {
513
- const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
514
- const trimmedFractional = fractionalStr.replace(/0+$/, "");
515
- displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
527
+ displayAmount = amount.toString();
516
528
  }
529
+ params.append("amount", displayAmount);
517
530
  }
518
- else {
519
- displayAmount = amount.toString();
520
- }
521
- params.append("amount", displayAmount);
522
531
  params.append("spl-token", currency); // token mint address
523
532
  }
524
- const url = `solana:${address}?${params.toString()}`;
533
+ const queryString = params.toString();
534
+ const url = queryString ? `solana:${address}?${queryString}` : `solana:${address}`;
525
535
  console.log("Solana URL (isNativeSOL:", isNativeSOL, "):", url);
526
536
  return url;
527
537
  }
@@ -8,6 +8,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
8
8
  const react_1 = require("../../../anyspend/react");
9
9
  const AnySpendDeposit_1 = require("../../../anyspend/react/components/AnySpendDeposit");
10
10
  const AnyspendDepositHype_1 = require("../../../anyspend/react/components/AnyspendDepositHype");
11
+ const AnySpendWorkflowTrigger_1 = require("../../../anyspend/react/components/AnySpendWorkflowTrigger");
11
12
  const AnySpendDepositUpside_1 = require("../../../anyspend/react/components/AnySpendDepositUpside");
12
13
  const AnySpendStakeUpside_1 = require("../../../anyspend/react/components/AnySpendStakeUpside");
13
14
  const AnySpendStakeUpsideExactIn_1 = require("../../../anyspend/react/components/AnySpendStakeUpsideExactIn");
@@ -58,6 +59,7 @@ function B3DynamicModal() {
58
59
  "send",
59
60
  "notifications",
60
61
  "anySpendDeposit",
62
+ "anySpendWorkflowTrigger",
61
63
  ];
62
64
  const freestyleTypes = [
63
65
  "anySpendNft",
@@ -128,6 +130,8 @@ function B3DynamicModal() {
128
130
  return (0, jsx_runtime_1.jsx)(react_1.AnySpendCollectorClubPurchase, { ...contentType, mode: "modal" });
129
131
  case "anySpendDeposit":
130
132
  return (0, jsx_runtime_1.jsx)(AnySpendDeposit_1.AnySpendDeposit, { ...contentType, mode: "modal" });
133
+ case "anySpendWorkflowTrigger":
134
+ return (0, jsx_runtime_1.jsx)(AnySpendWorkflowTrigger_1.AnySpendWorkflowTrigger, { ...contentType, mode: "modal" });
131
135
  case "avatarEditor":
132
136
  return (0, jsx_runtime_1.jsx)(AvatarEditor_1.AvatarEditor, { onSetAvatar: contentType.onSuccess });
133
137
  case "deposit":
@@ -14,6 +14,16 @@ function useUserQuery() {
14
14
  const user = (0, userStore_1.useUserStore)(state => state.user);
15
15
  const setUserStore = (0, userStore_1.useUserStore)(state => state.setUser);
16
16
  const clearUserStore = (0, userStore_1.useUserStore)(state => state.clearUser);
17
+ // Manually rehydrate persisted store inside useLayoutEffect to avoid
18
+ // updating AuthenticationProvider state during Hydrate render.
19
+ // useLayoutEffect (not useEffect) ensures rehydration triggers a
20
+ // synchronous re-render before any useEffect callbacks fire, so
21
+ // downstream effects always see the persisted user value.
22
+ (0, react_1.useLayoutEffect)(() => {
23
+ if (!userStore_1.useUserStore.persist.hasHydrated()) {
24
+ userStore_1.useUserStore.persist.rehydrate();
25
+ }
26
+ }, []);
17
27
  // Listen for storage events from other tabs/windows
18
28
  (0, react_1.useEffect)(() => {
19
29
  const handleStorageChange = (e) => {
@@ -470,11 +470,45 @@ export interface AnySpendCollectorClubPurchaseProps extends BaseModalProps {
470
470
  forceFiatPayment?: boolean;
471
471
  /** Staging environment support */
472
472
  isStaging?: boolean;
473
+ /** Optional discount code to apply to the purchase */
474
+ discountCode?: string;
473
475
  }
474
476
  /**
475
477
  * Props for the AnySpend Deposit modal
476
478
  * Flexible deposit component with optional chain selection
477
479
  */
480
+ /**
481
+ * Props for the AnySpend Workflow Trigger modal
482
+ * Handles payments that trigger b3os-workflow runs
483
+ */
484
+ export interface AnySpendWorkflowTriggerModalProps extends BaseModalProps {
485
+ /** Modal type identifier */
486
+ type: "anySpendWorkflowTrigger";
487
+ /** Payment recipient address (hex) */
488
+ recipientAddress: string;
489
+ /** Destination chain ID */
490
+ chainId: number;
491
+ /** Destination token address */
492
+ tokenAddress: string;
493
+ /** Required payment amount in token base units (wei) */
494
+ amount: string;
495
+ /** Workflow ID to trigger */
496
+ workflowId: string;
497
+ /** Organization ID that owns the workflow */
498
+ orgId: string;
499
+ /** Optional callback metadata */
500
+ callbackMetadata?: {
501
+ inputs?: Record<string, unknown>;
502
+ } & Record<string, unknown>;
503
+ /** Callback when payment succeeds */
504
+ onSuccess?: (amount: string) => void;
505
+ /** Callback when modal is closed */
506
+ onClose?: () => void;
507
+ /** Custom action label */
508
+ actionLabel?: string;
509
+ /** Custom class names */
510
+ classes?: AnySpendAllClasses;
511
+ }
478
512
  export interface AnySpendDepositModalProps extends BaseModalProps {
479
513
  /** Modal type identifier */
480
514
  type: "anySpendDeposit";
@@ -534,11 +568,13 @@ export interface AnySpendDepositModalProps extends BaseModalProps {
534
568
  classes?: AnySpendAllClasses;
535
569
  /** Whether to allow direct transfer without swap */
536
570
  allowDirectTransfer?: boolean;
571
+ /** Opaque metadata passed to the order for callbacks (e.g., workflow form data) */
572
+ callbackMetadata?: Record<string, unknown>;
537
573
  }
538
574
  /**
539
575
  * Union type of all possible modal content types
540
576
  */
541
- export type ModalContentType = SignInWithB3ModalProps | RequestPermissionsModalProps | ManageAccountModalProps | AnySpendModalProps | AnyspendOrderDetailsProps | AnySpendNftProps | AnySpendJoinTournamentProps | AnySpendFundTournamentProps | AnySpendOrderHistoryProps | AnySpendStakeB3Props | AnySpendStakeB3ExactInProps | AnySpendStakeUpsideProps | AnySpendStakeUpsideExactInProps | AnySpendDepositUpsideProps | AnySpendBuySpinProps | AnySpendSignatureMintProps | AnySpendBondKitProps | LinkAccountModalProps | LinkNewAccountModalProps | AnySpendDepositHypeProps | AvatarEditorModalProps | DepositModalProps | SendModalProps | NotificationsModalProps | AnySpendCollectorClubPurchaseProps | AnySpendDepositModalProps;
577
+ export type ModalContentType = SignInWithB3ModalProps | RequestPermissionsModalProps | ManageAccountModalProps | AnySpendModalProps | AnyspendOrderDetailsProps | AnySpendNftProps | AnySpendJoinTournamentProps | AnySpendFundTournamentProps | AnySpendOrderHistoryProps | AnySpendStakeB3Props | AnySpendStakeB3ExactInProps | AnySpendStakeUpsideProps | AnySpendStakeUpsideExactInProps | AnySpendDepositUpsideProps | AnySpendBuySpinProps | AnySpendSignatureMintProps | AnySpendBondKitProps | LinkAccountModalProps | LinkNewAccountModalProps | AnySpendDepositHypeProps | AvatarEditorModalProps | DepositModalProps | SendModalProps | NotificationsModalProps | AnySpendCollectorClubPurchaseProps | AnySpendDepositModalProps | AnySpendWorkflowTriggerModalProps;
542
578
  /**
543
579
  * State interface for the modal store
544
580
  */
@@ -22,6 +22,7 @@ exports.useUserStore = (0, zustand_1.create)()((0, middleware_1.persist)(set =>
22
22
  },
23
23
  }), {
24
24
  name: "b3-user",
25
+ skipHydration: true,
25
26
  onRehydrateStorage: () => (_, error) => {
26
27
  if (error) {
27
28
  console.warn("Failed to rehydrate user store:", error);
@@ -53,4 +53,6 @@ export declare function AnySpend(props: {
53
53
  allowDirectTransfer?: boolean;
54
54
  /** Fixed destination token amount (in wei/smallest unit). When provided, user cannot change the amount. */
55
55
  destinationTokenAmount?: string;
56
+ /** Opaque metadata passed to the order for callbacks (e.g., workflow form data) */
57
+ callbackMetadata?: Record<string, unknown>;
56
58
  }): import("react/jsx-runtime").JSX.Element;
@@ -18,6 +18,7 @@ import { useAutoSelectCryptoPaymentMethod } from "../hooks/useAutoSelectCryptoPa
18
18
  import { useConnectedWalletDisplay } from "../hooks/useConnectedWalletDisplay.js";
19
19
  import { useCryptoPaymentMethodState } from "../hooks/useCryptoPaymentMethodState.js";
20
20
  import { useDirectTransfer } from "../hooks/useDirectTransfer.js";
21
+ import { useOnOrderSuccess } from "../hooks/useOnOrderSuccess.js";
21
22
  import { useRecipientAddressState } from "../hooks/useRecipientAddressState.js";
22
23
  import { AnySpendFingerprintWrapper, getFingerprintConfig } from "./AnySpendFingerprintWrapper.js";
23
24
  import { CryptoPaymentMethod, CryptoPaymentMethodType } from "./common/CryptoPaymentMethod.js";
@@ -54,7 +55,7 @@ export function AnySpend(props) {
54
55
  console.log("[mitch] AnySpend rendered with fingerprintConfig:", props, fingerprintConfig);
55
56
  return (_jsx(AnySpendFingerprintWrapper, { fingerprint: fingerprintConfig, children: _jsx(AnySpendInner, { ...props }) }));
56
57
  }
57
- function AnySpendInner({ sourceChainId, destinationTokenAddress, destinationTokenChainId, mode = "modal", defaultActiveTab = "crypto", loadOrder, hideTransactionHistoryButton, recipientAddress: recipientAddressFromProps, onTokenSelect, onSuccess, customUsdInputValues, hideHeader, hideBottomNavigation = false, disableUrlParamManagement = false, returnToHomeUrl, customRecipientLabel, returnHomeLabel, classes, allowDirectTransfer = false, destinationTokenAmount, }) {
58
+ function AnySpendInner({ sourceChainId, destinationTokenAddress, destinationTokenChainId, mode = "modal", defaultActiveTab = "crypto", loadOrder, hideTransactionHistoryButton, recipientAddress: recipientAddressFromProps, onTokenSelect, onSuccess, customUsdInputValues, hideHeader, hideBottomNavigation = false, disableUrlParamManagement = false, returnToHomeUrl, customRecipientLabel, returnHomeLabel, classes, allowDirectTransfer = false, destinationTokenAmount, callbackMetadata, }) {
58
59
  const searchParams = useSearchParamsSSR();
59
60
  const router = useRouter();
60
61
  const { partnerId } = useB3Config();
@@ -65,8 +66,6 @@ function AnySpendInner({ sourceChainId, destinationTokenAddress, destinationToke
65
66
  // Add refs to track URL state
66
67
  const initialUrlProcessed = useRef(false);
67
68
  const lastUrlUpdate = useRef(null);
68
- // Track if onSuccess has been called for the current order
69
- const onSuccessCalled = useRef(false);
70
69
  // Track animation direction for TransitionPanel
71
70
  const animationDirection = useRef(null);
72
71
  // Track previous panel for proper back navigation
@@ -486,18 +485,8 @@ function AnySpendInner({ sourceChainId, destinationTokenAddress, destinationToke
486
485
  }
487
486
  }
488
487
  }, [anyspendQuote, isSrcInputDirty, destinationTokenAmount]);
489
- useEffect(() => {
490
- if (oat?.data?.order.status === "executed" && !onSuccessCalled.current) {
491
- console.log("Calling onSuccess");
492
- const txHash = oat?.data?.executeTx?.txHash;
493
- onSuccess?.(txHash);
494
- onSuccessCalled.current = true;
495
- }
496
- }, [oat?.data?.order.status, oat?.data?.executeTx?.txHash, onSuccess]);
497
- // Reset flag when orderId changes
498
- useEffect(() => {
499
- onSuccessCalled.current = false;
500
- }, [orderId]);
488
+ // Call onSuccess when order is executed
489
+ useOnOrderSuccess({ orderData: oat, orderId, onSuccess });
501
490
  const { createOrder, isCreatingOrder } = useAnyspendCreateOrder({
502
491
  onSuccess: data => {
503
492
  const orderId = data.data.id;
@@ -724,6 +713,7 @@ function AnySpendInner({ sourceChainId, destinationTokenAddress, destinationToke
724
713
  srcAmount: srcAmountBigInt.toString(),
725
714
  expectedDstAmount: anyspendQuote?.data?.currencyOut?.amount || "0",
726
715
  creatorAddress: globalAddress,
716
+ callbackMetadata,
727
717
  });
728
718
  }
729
719
  catch (err) {
@@ -798,6 +788,7 @@ function AnySpendInner({ sourceChainId, destinationTokenAddress, destinationToke
798
788
  },
799
789
  expectedDstAmount: anyspendQuote?.data?.currencyOut?.amount?.toString() || "0",
800
790
  creatorAddress: globalAddress,
791
+ callbackMetadata,
801
792
  });
802
793
  }
803
794
  catch (err) {
@@ -884,7 +875,7 @@ function AnySpendInner({ sourceChainId, destinationTokenAddress, destinationToke
884
875
  // Reset payment methods when switching tabs
885
876
  resetPaymentMethods();
886
877
  setSelectedFiatPaymentMethod(FiatPaymentMethod.NONE);
887
- }, setSelectedCryptoPaymentMethod: setSelectedCryptoPaymentMethod, setSelectedFiatPaymentMethod: setSelectedFiatPaymentMethod }), _jsxs("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: [activeTab === "crypto" ? (_jsx(CryptoPaySection, { selectedSrcChainId: selectedSrcChainId, setSelectedSrcChainId: setSelectedSrcChainId, selectedSrcToken: selectedSrcToken, setSelectedSrcToken: setSelectedSrcToken, srcAmount: srcAmount, setSrcAmount: setSrcAmount, isSrcInputDirty: isSrcInputDirty, setIsSrcInputDirty: setIsSrcInputDirty, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod, onSelectCryptoPaymentMethod: () => navigateToPanel(PanelView.CRYPTO_PAYMENT_METHOD, "forward"), anyspendQuote: anyspendQuote, onTokenSelect: onTokenSelect, onShowFeeDetail: () => navigateToPanel(PanelView.FEE_DETAIL, "forward"), skipAutoMaxOnTokenChange: !!destinationTokenAmount })) : (_jsx(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, children: _jsx(PanelOnramp, { srcAmountOnRamp: srcAmountOnRamp, setSrcAmountOnRamp: setSrcAmountOnRamp, selectedPaymentMethod: selectedFiatPaymentMethod, setActivePanel: (panelIndex) => {
878
+ }, setSelectedCryptoPaymentMethod: setSelectedCryptoPaymentMethod, setSelectedFiatPaymentMethod: setSelectedFiatPaymentMethod }), _jsxs("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: [activeTab === "crypto" ? (_jsx(CryptoPaySection, { selectedSrcChainId: selectedSrcChainId, setSelectedSrcChainId: setSelectedSrcChainId, selectedSrcToken: selectedSrcToken, setSelectedSrcToken: setSelectedSrcToken, srcAmount: srcAmount, setSrcAmount: setSrcAmount, isSrcInputDirty: isSrcInputDirty, setIsSrcInputDirty: setIsSrcInputDirty, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod, onSelectCryptoPaymentMethod: () => navigateToPanel(PanelView.CRYPTO_PAYMENT_METHOD, "forward"), anyspendQuote: anyspendQuote, onTokenSelect: onTokenSelect, onShowFeeDetail: () => navigateToPanel(PanelView.FEE_DETAIL, "forward") })) : (_jsx(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, children: _jsx(PanelOnramp, { srcAmountOnRamp: srcAmountOnRamp, setSrcAmountOnRamp: setSrcAmountOnRamp, selectedPaymentMethod: selectedFiatPaymentMethod, setActivePanel: (panelIndex) => {
888
879
  // Map panel index to navigation with direction
889
880
  const panelsWithForwardNav = [PanelView.FIAT_PAYMENT_METHOD, PanelView.RECIPIENT_SELECTION];
890
881
  if (panelsWithForwardNav.includes(panelIndex)) {
@@ -69,5 +69,10 @@ export interface AnySpendCollectorClubPurchaseProps {
69
69
  * Force fiat payment
70
70
  */
71
71
  forceFiatPayment?: boolean;
72
+ /**
73
+ * Optional discount code to apply to the purchase.
74
+ * When provided, validates on-chain and adjusts the price accordingly.
75
+ */
76
+ discountCode?: string;
72
77
  }
73
- export declare function AnySpendCollectorClubPurchase({ loadOrder, mode, activeTab, packId, packAmount, pricePerPack, paymentToken, recipientAddress, spenderAddress, isStaging, onSuccess, header, showRecipient, vendingMachineId, packType, forceFiatPayment, }: AnySpendCollectorClubPurchaseProps): import("react/jsx-runtime").JSX.Element;
78
+ export declare function AnySpendCollectorClubPurchase({ loadOrder, mode, activeTab, packId, packAmount, pricePerPack, paymentToken, recipientAddress, spenderAddress, isStaging, onSuccess, header, showRecipient, vendingMachineId, packType, forceFiatPayment, discountCode, }: AnySpendCollectorClubPurchaseProps): import("react/jsx-runtime").JSX.Element;
@@ -26,27 +26,22 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
26
26
  * ```
27
27
  */
28
28
  import { USDC_BASE } from "../../../anyspend/constants/index.js";
29
+ import { PUBLIC_BASE_RPC_URL } from "../../../shared/constants/index.js";
29
30
  import { formatUnits } from "../../../shared/utils/number.js";
30
- import { useMemo } from "react";
31
- import { encodeFunctionData } from "viem";
31
+ import { useEffect, useMemo, useState } from "react";
32
+ import { createPublicClient, encodeFunctionData, http } from "viem";
33
+ import { base } from "viem/chains";
32
34
  import { AnySpendCustom } from "./AnySpendCustom.js";
35
+ import { BUY_PACKS_FOR_ABI, BUY_PACKS_FOR_WITH_DISCOUNT_ABI, GET_DISCOUNT_CODE_ABI, IS_DISCOUNT_CODE_VALID_FOR_PACK_ABI, } from "./ccShopAbi.js";
33
36
  // Collector Club Shop contract addresses on Base
34
37
  const CC_SHOP_ADDRESS = "0x47366E64E4917dd4DdC04Fb9DC507c1dD2b87294";
35
38
  const CC_SHOP_ADDRESS_STAGING = "0x8b751143342ac41eB965E55430e3F7Adf6BE01fA";
36
39
  const BASE_CHAIN_ID = 8453;
37
- // ABI for buyPacksFor function only
38
- const BUY_PACKS_FOR_ABI = {
39
- inputs: [
40
- { internalType: "address", name: "user", type: "address" },
41
- { internalType: "uint256", name: "packId", type: "uint256" },
42
- { internalType: "uint256", name: "amount", type: "uint256" },
43
- ],
44
- name: "buyPacksFor",
45
- outputs: [],
46
- stateMutability: "nonpayable",
47
- type: "function",
48
- };
49
- export function AnySpendCollectorClubPurchase({ loadOrder, mode = "modal", activeTab = "crypto", packId, packAmount, pricePerPack, paymentToken = USDC_BASE, recipientAddress, spenderAddress, isStaging = false, onSuccess, header, showRecipient = true, vendingMachineId, packType, forceFiatPayment, }) {
40
+ const basePublicClient = createPublicClient({
41
+ chain: base,
42
+ transport: http(PUBLIC_BASE_RPC_URL),
43
+ });
44
+ export function AnySpendCollectorClubPurchase({ loadOrder, mode = "modal", activeTab = "crypto", packId, packAmount, pricePerPack, paymentToken = USDC_BASE, recipientAddress, spenderAddress, isStaging = false, onSuccess, header, showRecipient = true, vendingMachineId, packType, forceFiatPayment, discountCode, }) {
50
45
  const ccShopAddress = isStaging ? CC_SHOP_ADDRESS_STAGING : CC_SHOP_ADDRESS;
51
46
  // Calculate total amount needed (pricePerPack * packAmount)
52
47
  const totalAmount = useMemo(() => {
@@ -58,15 +53,130 @@ export function AnySpendCollectorClubPurchase({ loadOrder, mode = "modal", activ
58
53
  return "0";
59
54
  }
60
55
  }, [pricePerPack, packAmount]);
61
- // Calculate fiat amount (totalAmount in USD, assuming USDC with 6 decimals)
56
+ // Discount code validation state
57
+ const [discountInfo, setDiscountInfo] = useState({
58
+ isValid: false,
59
+ discountAmount: BigInt(0),
60
+ minPurchaseAmount: BigInt(0),
61
+ isLoading: false,
62
+ error: null,
63
+ });
64
+ // Validate discount code on-chain when provided
65
+ useEffect(() => {
66
+ if (!discountCode) {
67
+ setDiscountInfo({
68
+ isValid: false,
69
+ discountAmount: BigInt(0),
70
+ minPurchaseAmount: BigInt(0),
71
+ isLoading: false,
72
+ error: null,
73
+ });
74
+ return;
75
+ }
76
+ let cancelled = false;
77
+ const validateDiscount = async () => {
78
+ setDiscountInfo(prev => ({ ...prev, isLoading: true, error: null }));
79
+ try {
80
+ // Validate against specific pack and fetch full details in parallel
81
+ const [validForPack, codeDetails] = await Promise.all([
82
+ basePublicClient.readContract({
83
+ address: ccShopAddress,
84
+ abi: [IS_DISCOUNT_CODE_VALID_FOR_PACK_ABI],
85
+ functionName: "isDiscountCodeValidForPack",
86
+ args: [discountCode, BigInt(packId)],
87
+ }),
88
+ basePublicClient.readContract({
89
+ address: ccShopAddress,
90
+ abi: [GET_DISCOUNT_CODE_ABI],
91
+ functionName: "getDiscountCode",
92
+ args: [discountCode],
93
+ }),
94
+ ]);
95
+ if (cancelled)
96
+ return;
97
+ const [isValid, discountAmount] = validForPack;
98
+ const { minPurchaseAmount, packId: restrictedPackId, exists } = codeDetails;
99
+ if (!exists) {
100
+ setDiscountInfo({
101
+ isValid: false,
102
+ discountAmount: BigInt(0),
103
+ minPurchaseAmount: BigInt(0),
104
+ isLoading: false,
105
+ error: "Discount code does not exist",
106
+ });
107
+ return;
108
+ }
109
+ if (!isValid) {
110
+ // Provide specific error based on code details
111
+ if (restrictedPackId !== BigInt(0) && restrictedPackId !== BigInt(packId)) {
112
+ setDiscountInfo({
113
+ isValid: false,
114
+ discountAmount: BigInt(0),
115
+ minPurchaseAmount: BigInt(0),
116
+ isLoading: false,
117
+ error: "Discount code is not valid for this pack",
118
+ });
119
+ }
120
+ else {
121
+ setDiscountInfo({
122
+ isValid: false,
123
+ discountAmount: BigInt(0),
124
+ minPurchaseAmount: BigInt(0),
125
+ isLoading: false,
126
+ error: "Invalid or expired discount code",
127
+ });
128
+ }
129
+ return;
130
+ }
131
+ setDiscountInfo({ isValid: true, discountAmount, minPurchaseAmount, isLoading: false, error: null });
132
+ }
133
+ catch (error) {
134
+ if (cancelled)
135
+ return;
136
+ console.error("Failed to validate discount code", { discountCode, error });
137
+ setDiscountInfo({
138
+ isValid: false,
139
+ discountAmount: BigInt(0),
140
+ minPurchaseAmount: BigInt(0),
141
+ isLoading: false,
142
+ error: "Failed to validate discount code",
143
+ });
144
+ }
145
+ };
146
+ validateDiscount();
147
+ return () => {
148
+ cancelled = true;
149
+ };
150
+ }, [discountCode, ccShopAddress, packId]);
151
+ // Calculate effective dstAmount after discount
152
+ const effectiveDstAmount = useMemo(() => {
153
+ if (!discountCode || !discountInfo.isValid || discountInfo.discountAmount === BigInt(0)) {
154
+ return totalAmount;
155
+ }
156
+ const total = BigInt(totalAmount);
157
+ const discount = discountInfo.discountAmount;
158
+ if (discount >= total) {
159
+ console.error("Discount exceeds total price", { totalAmount, discountAmount: discount.toString() });
160
+ return "0";
161
+ }
162
+ return (total - discount).toString();
163
+ }, [totalAmount, discountCode, discountInfo.isValid, discountInfo.discountAmount]);
164
+ // Calculate fiat amount (effectiveDstAmount in USD, assuming USDC with 6 decimals)
62
165
  const srcFiatAmount = useMemo(() => {
63
- if (!totalAmount || totalAmount === "0")
166
+ if (!effectiveDstAmount || effectiveDstAmount === "0")
64
167
  return "0";
65
- return formatUnits(totalAmount, USDC_BASE.decimals);
66
- }, [totalAmount]);
67
- // Encode the buyPacksFor function call
168
+ return formatUnits(effectiveDstAmount, USDC_BASE.decimals);
169
+ }, [effectiveDstAmount]);
170
+ // Encode the contract function call (with or without discount)
68
171
  const encodedData = useMemo(() => {
69
172
  try {
173
+ if (discountCode && discountInfo.isValid) {
174
+ return encodeFunctionData({
175
+ abi: [BUY_PACKS_FOR_WITH_DISCOUNT_ABI],
176
+ functionName: "buyPacksForWithDiscount",
177
+ args: [recipientAddress, BigInt(packId), BigInt(packAmount), discountCode],
178
+ });
179
+ }
70
180
  return encodeFunctionData({
71
181
  abi: [BUY_PACKS_FOR_ABI],
72
182
  functionName: "buyPacksFor",
@@ -74,17 +184,36 @@ export function AnySpendCollectorClubPurchase({ loadOrder, mode = "modal", activ
74
184
  });
75
185
  }
76
186
  catch (error) {
77
- console.error("Failed to encode function data", { recipientAddress, packId, packAmount, error });
187
+ console.error("Failed to encode function data", { recipientAddress, packId, packAmount, discountCode, error });
78
188
  return "0x";
79
189
  }
80
- }, [recipientAddress, packId, packAmount]);
190
+ }, [recipientAddress, packId, packAmount, discountCode, discountInfo.isValid]);
81
191
  // Default header if not provided
82
192
  const defaultHeader = () => (_jsx("div", { className: "mb-4 flex flex-col items-center gap-3 text-center", children: _jsxs("div", { children: [_jsx("h1", { className: "text-as-primary text-xl font-bold", children: "Buy Collector Club Packs" }), _jsxs("p", { className: "text-as-secondary text-sm", children: ["Purchase ", packAmount, " pack", packAmount !== 1 ? "s" : "", " using any token"] })] }) }));
83
- return (_jsx(AnySpendCustom, { loadOrder: loadOrder, mode: mode, activeTab: activeTab, recipientAddress: recipientAddress, spenderAddress: spenderAddress ?? ccShopAddress, orderType: "custom", dstChainId: BASE_CHAIN_ID, dstToken: paymentToken, dstAmount: totalAmount, contractAddress: ccShopAddress, encodedData: encodedData, metadata: {
193
+ // Don't render AnySpendCustom while discount is being validated (avoids showing wrong price)
194
+ if (discountCode && discountInfo.isLoading) {
195
+ return (_jsx("div", { className: "mb-4 flex flex-col items-center gap-3 text-center", children: _jsx("p", { className: "text-as-secondary text-sm", children: "Validating discount code..." }) }));
196
+ }
197
+ if (discountCode && discountInfo.error) {
198
+ return (_jsx("div", { className: "mb-4 flex flex-col items-center gap-3 text-center", children: _jsx("p", { className: "text-sm text-red-500", children: discountInfo.error }) }));
199
+ }
200
+ if (discountCode &&
201
+ discountInfo.isValid &&
202
+ discountInfo.minPurchaseAmount > BigInt(0) &&
203
+ BigInt(packAmount) < discountInfo.minPurchaseAmount) {
204
+ return (_jsx("div", { className: "mb-4 flex flex-col items-center gap-3 text-center", children: _jsxs("p", { className: "text-sm text-red-500", children: ["Minimum purchase of ", discountInfo.minPurchaseAmount.toString(), " pack", discountInfo.minPurchaseAmount > BigInt(1) ? "s" : "", " required for this discount code"] }) }));
205
+ }
206
+ if (discountCode && discountInfo.isValid && effectiveDstAmount === "0") {
207
+ return (_jsx("div", { className: "mb-4 flex flex-col items-center gap-3 text-center", children: _jsx("p", { className: "text-sm text-red-500", children: "Discount exceeds total price" }) }));
208
+ }
209
+ return (_jsx(AnySpendCustom, { loadOrder: loadOrder, mode: mode, activeTab: activeTab, recipientAddress: recipientAddress, spenderAddress: spenderAddress ?? ccShopAddress, orderType: "custom", dstChainId: BASE_CHAIN_ID, dstToken: paymentToken, dstAmount: effectiveDstAmount, contractAddress: ccShopAddress, encodedData: encodedData, metadata: {
84
210
  packId,
85
211
  packAmount,
86
212
  pricePerPack,
87
213
  vendingMachineId,
88
214
  packType,
215
+ ...(discountCode && discountInfo.isValid
216
+ ? { discountCode, discountAmount: discountInfo.discountAmount.toString() }
217
+ : {}),
89
218
  }, header: header || defaultHeader, onSuccess: onSuccess, showRecipient: showRecipient, srcFiatAmount: srcFiatAmount, forceFiatPayment: forceFiatPayment }));
90
219
  }