@b3dotfun/sdk 0.0.41 → 0.0.42-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 (112) hide show
  1. package/dist/cjs/anyspend/react/components/AnySpend.d.ts +1 -0
  2. package/dist/cjs/anyspend/react/components/AnySpend.js +11 -2
  3. package/dist/cjs/anyspend/react/components/AnySpendBondKit.js +0 -1
  4. package/dist/cjs/anyspend/react/components/AnySpendBuySpin.js +0 -1
  5. package/dist/cjs/anyspend/react/components/AnySpendCustom.d.ts +1 -0
  6. package/dist/cjs/anyspend/react/components/AnySpendCustom.js +33 -11
  7. package/dist/cjs/anyspend/react/components/AnySpendNFT.d.ts +2 -1
  8. package/dist/cjs/anyspend/react/components/AnySpendNFT.js +2 -2
  9. package/dist/cjs/anyspend/react/components/AnySpendStakeB3.js +0 -1
  10. package/dist/cjs/anyspend/react/components/AnyspendSignatureMint.js +1 -2
  11. package/dist/cjs/anyspend/react/components/common/CryptoPaySection.js +1 -1
  12. package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.js +2 -1
  13. package/dist/cjs/anyspend/react/components/common/PanelOnramp.js +4 -1
  14. package/dist/cjs/anyspend/react/components/common/PointsBadge.d.ts +7 -0
  15. package/dist/cjs/anyspend/react/components/common/PointsBadge.js +7 -0
  16. package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +5 -3
  17. package/dist/cjs/anyspend/services/anyspend.d.ts +1 -1
  18. package/dist/cjs/anyspend/services/anyspend.js +2 -0
  19. package/dist/cjs/anyspend/types/api.d.ts +41 -1
  20. package/dist/cjs/anyspend/utils/orderPayload.js +3 -0
  21. package/dist/cjs/bondkit/components/TradingView.js +3 -4
  22. package/dist/cjs/bondkit/swapService.js +3 -0
  23. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +19 -13
  24. package/dist/cjs/global-account/react/hooks/index.d.ts +1 -0
  25. package/dist/cjs/global-account/react/hooks/index.js +3 -1
  26. package/dist/cjs/global-account/react/hooks/useAccountAssets.js +5 -2
  27. package/dist/cjs/global-account/react/hooks/useAuthentication.js +1 -1
  28. package/dist/cjs/global-account/react/hooks/useGlobalAccount.d.ts +6 -0
  29. package/dist/cjs/global-account/react/hooks/useGlobalAccount.js +32 -0
  30. package/dist/cjs/global-account/react/hooks/useQueryB3.js +5 -2
  31. package/dist/cjs/global-account/react/hooks/useQueryBSMNT.js +5 -2
  32. package/dist/cjs/global-account/react/hooks/useTokenBalancesByChain.js +7 -1
  33. package/dist/cjs/global-account/react/hooks/useTokenFromUrl.js +2 -2
  34. package/dist/cjs/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +1 -2
  35. package/dist/cjs/shared/utils/fetchBalances.d.ts +1 -1
  36. package/dist/esm/anyspend/react/components/AnySpend.d.ts +1 -0
  37. package/dist/esm/anyspend/react/components/AnySpend.js +11 -2
  38. package/dist/esm/anyspend/react/components/AnySpendBondKit.js +0 -1
  39. package/dist/esm/anyspend/react/components/AnySpendBuySpin.js +0 -1
  40. package/dist/esm/anyspend/react/components/AnySpendCustom.d.ts +1 -0
  41. package/dist/esm/anyspend/react/components/AnySpendCustom.js +33 -11
  42. package/dist/esm/anyspend/react/components/AnySpendNFT.d.ts +2 -1
  43. package/dist/esm/anyspend/react/components/AnySpendNFT.js +2 -2
  44. package/dist/esm/anyspend/react/components/AnySpendStakeB3.js +0 -1
  45. package/dist/esm/anyspend/react/components/AnyspendSignatureMint.js +1 -2
  46. package/dist/esm/anyspend/react/components/common/CryptoPaySection.js +1 -1
  47. package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.js +2 -1
  48. package/dist/esm/anyspend/react/components/common/PanelOnramp.js +4 -1
  49. package/dist/esm/anyspend/react/components/common/PointsBadge.d.ts +7 -0
  50. package/dist/esm/anyspend/react/components/common/PointsBadge.js +4 -0
  51. package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +5 -3
  52. package/dist/esm/anyspend/services/anyspend.d.ts +1 -1
  53. package/dist/esm/anyspend/services/anyspend.js +2 -0
  54. package/dist/esm/anyspend/types/api.d.ts +41 -1
  55. package/dist/esm/anyspend/utils/orderPayload.js +3 -0
  56. package/dist/esm/bondkit/components/TradingView.js +3 -4
  57. package/dist/esm/bondkit/swapService.js +5 -2
  58. package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +19 -13
  59. package/dist/esm/global-account/react/hooks/index.d.ts +1 -0
  60. package/dist/esm/global-account/react/hooks/index.js +1 -0
  61. package/dist/esm/global-account/react/hooks/useAccountAssets.js +2 -2
  62. package/dist/esm/global-account/react/hooks/useAuthentication.js +1 -1
  63. package/dist/esm/global-account/react/hooks/useGlobalAccount.d.ts +6 -0
  64. package/dist/esm/global-account/react/hooks/useGlobalAccount.js +29 -0
  65. package/dist/esm/global-account/react/hooks/useQueryB3.js +5 -2
  66. package/dist/esm/global-account/react/hooks/useQueryBSMNT.js +5 -2
  67. package/dist/esm/global-account/react/hooks/useTokenBalancesByChain.js +4 -1
  68. package/dist/esm/global-account/react/hooks/useTokenFromUrl.js +2 -2
  69. package/dist/esm/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +2 -3
  70. package/dist/esm/shared/utils/fetchBalances.d.ts +1 -1
  71. package/dist/styles/index.css +1 -1
  72. package/dist/types/anyspend/react/components/AnySpend.d.ts +1 -0
  73. package/dist/types/anyspend/react/components/AnySpendCustom.d.ts +1 -0
  74. package/dist/types/anyspend/react/components/AnySpendNFT.d.ts +2 -1
  75. package/dist/types/anyspend/react/components/common/PointsBadge.d.ts +7 -0
  76. package/dist/types/anyspend/services/anyspend.d.ts +1 -1
  77. package/dist/types/anyspend/types/api.d.ts +41 -1
  78. package/dist/types/global-account/react/hooks/index.d.ts +1 -0
  79. package/dist/types/global-account/react/hooks/useGlobalAccount.d.ts +6 -0
  80. package/dist/types/shared/utils/fetchBalances.d.ts +1 -1
  81. package/package.json +22 -23
  82. package/src/anyspend/react/components/AnySpend.tsx +14 -1
  83. package/src/anyspend/react/components/AnySpendBondKit.tsx +0 -1
  84. package/src/anyspend/react/components/AnySpendBuySpin.tsx +0 -1
  85. package/src/anyspend/react/components/AnySpendCustom.tsx +63 -13
  86. package/src/anyspend/react/components/AnySpendNFT.tsx +3 -0
  87. package/src/anyspend/react/components/AnySpendStakeB3.tsx +0 -1
  88. package/src/anyspend/react/components/AnyspendSignatureMint.tsx +1 -2
  89. package/src/anyspend/react/components/common/CryptoPaySection.tsx +1 -1
  90. package/src/anyspend/react/components/common/CryptoReceiveSection.tsx +6 -8
  91. package/src/anyspend/react/components/common/PanelOnramp.tsx +10 -10
  92. package/src/anyspend/react/components/common/PointsBadge.tsx +20 -0
  93. package/src/anyspend/react/hooks/useAnyspendFlow.ts +5 -3
  94. package/src/anyspend/react/hooks/useAnyspendOrderAndTransactions.ts +1 -1
  95. package/src/anyspend/react/hooks/useCoinbaseOnrampOptions.ts +1 -1
  96. package/src/anyspend/services/anyspend.ts +3 -1
  97. package/src/anyspend/types/api.ts +41 -1
  98. package/src/anyspend/utils/orderPayload.ts +3 -0
  99. package/src/bondkit/components/TradingView.tsx +3 -5
  100. package/src/bondkit/swapService.ts +10 -7
  101. package/src/global-account/react/components/B3Provider/B3Provider.tsx +21 -17
  102. package/src/global-account/react/hooks/index.ts +1 -0
  103. package/src/global-account/react/hooks/useAccountAssets.ts +4 -3
  104. package/src/global-account/react/hooks/useAuthentication.ts +1 -1
  105. package/src/global-account/react/hooks/useGlobalAccount.tsx +36 -0
  106. package/src/global-account/react/hooks/useOneBalance.tsx +1 -1
  107. package/src/global-account/react/hooks/useQueryB3.ts +22 -15
  108. package/src/global-account/react/hooks/useQueryBSMNT.ts +22 -15
  109. package/src/global-account/react/hooks/useTokenBalancesByChain.tsx +4 -1
  110. package/src/global-account/react/hooks/useTokenFromUrl.tsx +2 -2
  111. package/src/global-account/react/hooks/useUnifiedChainSwitchAndExecute.ts +2 -3
  112. package/src/shared/utils/fetchBalances.ts +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@b3dotfun/sdk",
3
- "version": "0.0.41",
3
+ "version": "0.0.42-alpha.0",
4
4
  "source": "src/index.ts",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "react-native": "./dist/cjs/index.native.js",
@@ -236,27 +236,6 @@
236
236
  "utils",
237
237
  "constants"
238
238
  ],
239
- "scripts": {
240
- "clean": "rm -rf dist",
241
- "prebuild": "pnpm clean",
242
- "fix-dist": "[ -d ./dist/react/src ] && cp -r ./dist/react/src/* ./dist/ && rm -rf ./dist/react || echo \"No react directory found\"",
243
- "build": "pnpm clean && pnpm lint && pnpm build:types && pnpm build:cjs && pnpm build:esm && pnpm build:css",
244
- "build:types": "tsc -p tsconfig.cjs.json --emitDeclarationOnly --declarationDir dist/types",
245
- "build:cjs": "tsc -p tsconfig.cjs.json --outDir dist/cjs --module commonjs && tsc-alias -p tsconfig.cjs.json --outDir dist/cjs && mkdir -p dist/cjs/shared/generated && cp src/shared/generated/chain-networks.json src/shared/generated/coingecko-chains.json dist/cjs/shared/generated/ && ([ -d src/bondkit/json_abis ] && mkdir -p dist/cjs/bondkit/json_abis && cp -r src/bondkit/json_abis/* dist/cjs/bondkit/json_abis/ || echo \"No bondkit json_abis\")",
246
- "build:esm": "tsc -p tsconfig.esm.json --outDir dist/esm --module esnext && tsc-alias -p tsconfig.esm.json --outDir dist/esm && mkdir -p dist/esm/shared/generated && cp src/shared/generated/chain-networks.json src/shared/generated/coingecko-chains.json dist/esm/shared/generated/ && ([ -d src/bondkit/json_abis ] && mkdir -p dist/esm/bondkit/json_abis && cp -r src/bondkit/json_abis/* dist/esm/bondkit/json_abis/ || echo \"No bondkit json_abis\") && node scripts/fix-esm-imports.js",
247
- "build:css": "postcss src/styles/index.css -o dist/styles/index.css",
248
- "dev:cjs": "tsc-watch -p tsconfig.cjs.json --onSuccess \"tsc-alias -p tsconfig.cjs.json --outDir dist/cjs\"",
249
- "dev:esm": "tsc-watch -p tsconfig.esm.json --onSuccess \"tsc-alias -p tsconfig.esm.json --outDir dist/esm\"",
250
- "dev": "concurrently \"pnpm dev:cjs\" \"pnpm dev:esm\" \"pnpm dev:css\"",
251
- "dev:css": "postcss src/styles/index.css -o dist/styles/index.css --watch",
252
- "prepublishOnly": "pnpm build",
253
- "release:test": "pnpm version prerelease --preid test && git push --follow-tags && pnpm publish --tag test --no-git-checks",
254
- "release:alpha": "pnpm version prerelease --preid alpha && git push --follow-tags && pnpm publish --tag alpha --no-git-checks",
255
- "typecheck": "tsc --noEmit",
256
- "generate:thirdweb": "npx @hey-api/openapi-ts --file src/thirdweb/openapi-ts.config.ts --input src/thirdweb/insight-service.json",
257
- "lint": "eslint 'src/**/*.{ts,tsx}'",
258
- "lint:fix": "eslint 'src/**/*.{ts,tsx}' --fix"
259
- },
260
239
  "dependencies": {
261
240
  "@b3dotfun/b3-api": "0.0.50",
262
241
  "@b3dotfun/basement-api": "0.0.11",
@@ -369,5 +348,25 @@
369
348
  "three": {
370
349
  "optional": true
371
350
  }
351
+ },
352
+ "scripts": {
353
+ "clean": "rm -rf dist",
354
+ "prebuild": "pnpm clean",
355
+ "fix-dist": "[ -d ./dist/react/src ] && cp -r ./dist/react/src/* ./dist/ && rm -rf ./dist/react || echo \"No react directory found\"",
356
+ "build": "pnpm clean && pnpm lint && pnpm build:types && pnpm build:cjs && pnpm build:esm && pnpm build:css",
357
+ "build:types": "tsc -p tsconfig.cjs.json --emitDeclarationOnly --declarationDir dist/types",
358
+ "build:cjs": "tsc -p tsconfig.cjs.json --outDir dist/cjs --module commonjs && tsc-alias -p tsconfig.cjs.json --outDir dist/cjs && mkdir -p dist/cjs/shared/generated && cp src/shared/generated/chain-networks.json src/shared/generated/coingecko-chains.json dist/cjs/shared/generated/ && ([ -d src/bondkit/json_abis ] && mkdir -p dist/cjs/bondkit/json_abis && cp -r src/bondkit/json_abis/* dist/cjs/bondkit/json_abis/ || echo \"No bondkit json_abis\")",
359
+ "build:esm": "tsc -p tsconfig.esm.json --outDir dist/esm --module esnext && tsc-alias -p tsconfig.esm.json --outDir dist/esm && mkdir -p dist/esm/shared/generated && cp src/shared/generated/chain-networks.json src/shared/generated/coingecko-chains.json dist/esm/shared/generated/ && ([ -d src/bondkit/json_abis ] && mkdir -p dist/esm/bondkit/json_abis && cp -r src/bondkit/json_abis/* dist/esm/bondkit/json_abis/ || echo \"No bondkit json_abis\") && node scripts/fix-esm-imports.js",
360
+ "build:css": "postcss src/styles/index.css -o dist/styles/index.css",
361
+ "dev:cjs": "tsc-watch -p tsconfig.cjs.json --onSuccess \"tsc-alias -p tsconfig.cjs.json --outDir dist/cjs\"",
362
+ "dev:esm": "tsc-watch -p tsconfig.esm.json --onSuccess \"tsc-alias -p tsconfig.esm.json --outDir dist/esm\"",
363
+ "dev": "concurrently \"pnpm dev:cjs\" \"pnpm dev:esm\" \"pnpm dev:css\"",
364
+ "dev:css": "postcss src/styles/index.css -o dist/styles/index.css --watch",
365
+ "release:test": "pnpm version prerelease --preid test && git push --follow-tags && pnpm publish --tag test --no-git-checks",
366
+ "release:alpha": "pnpm version prerelease --preid alpha && git push --follow-tags && pnpm publish --tag alpha --no-git-checks",
367
+ "typecheck": "tsc --noEmit",
368
+ "generate:thirdweb": "npx @hey-api/openapi-ts --file src/thirdweb/openapi-ts.config.ts --input src/thirdweb/insight-service.json",
369
+ "lint": "eslint 'src/**/*.{ts,tsx}'",
370
+ "lint:fix": "eslint 'src/**/*.{ts,tsx}' --fix"
372
371
  }
373
- }
372
+ }
@@ -78,6 +78,7 @@ export function AnySpend(props: {
78
78
  * Useful for handling special cases like B3 token selection.
79
79
  */
80
80
  onTokenSelect?: (token: components["schemas"]["Token"], event: { preventDefault: () => void }) => void;
81
+ onSuccess?: (txHash?: string) => void;
81
82
  }) {
82
83
  const fingerprintConfig = getFingerprintConfig();
83
84
 
@@ -97,6 +98,7 @@ function AnySpendInner({
97
98
  hideTransactionHistoryButton,
98
99
  recipientAddress: recipientAddressFromProps,
99
100
  onTokenSelect,
101
+ onSuccess,
100
102
  }: {
101
103
  destinationTokenAddress?: string;
102
104
  destinationTokenChainId?: number;
@@ -106,6 +108,7 @@ function AnySpendInner({
106
108
  hideTransactionHistoryButton?: boolean;
107
109
  recipientAddress?: string;
108
110
  onTokenSelect?: (token: components["schemas"]["Token"], event: { preventDefault: () => void }) => void;
111
+ onSuccess?: (txHash?: string) => void;
109
112
  }) {
110
113
  const searchParams = useSearchParamsSSR();
111
114
  const router = useRouter();
@@ -446,8 +449,9 @@ function AnySpendInner({
446
449
  srcTokenAddress: selectedSrcToken.address,
447
450
  dstTokenAddress: isBuyMode ? destinationTokenAddress : selectedDstToken.address,
448
451
  type: "swap",
449
- tradeType: isSrcInputDirty ? "EXACT_INPUT" : "EXPECTED_OUTPUT",
452
+ tradeType: isSrcInputDirty ? "EXACT_INPUT" : "EXACT_OUTPUT",
450
453
  amount: activeInputAmountInWei,
454
+ recipientAddress,
451
455
  }
452
456
  : {
453
457
  srcChain: base.id,
@@ -457,6 +461,7 @@ function AnySpendInner({
457
461
  type: "swap",
458
462
  tradeType: "EXACT_INPUT",
459
463
  amount: srcAmountOnrampInWei,
464
+ recipientAddress,
460
465
  onrampVendor: getOnrampVendor(selectedFiatPaymentMethod),
461
466
  },
462
467
  );
@@ -514,6 +519,14 @@ function AnySpendInner({
514
519
  }
515
520
  }, [anyspendQuote, isSrcInputDirty]);
516
521
 
522
+ useEffect(() => {
523
+ if (oat?.data?.order.status === "executed") {
524
+ console.log("Calling onSuccess");
525
+ const txHash = oat?.data?.executeTx?.txHash;
526
+ onSuccess?.(txHash);
527
+ }
528
+ }, [oat?.data?.executeTx?.txHash, oat?.data?.order.status, onSuccess]);
529
+
517
530
  const { createOrder, isCreatingOrder } = useAnyspendCreateOrder({
518
531
  onSuccess: data => {
519
532
  const orderId = data.data.id;
@@ -366,7 +366,6 @@ export function AnySpendBondKit({
366
366
  contractAddress={contractAddress}
367
367
  encodedData={encodedData}
368
368
  metadata={{
369
- type: "custom",
370
369
  action: "BondKit Buy",
371
370
  }}
372
371
  header={header}
@@ -675,7 +675,6 @@ export function AnySpendBuySpin({
675
675
  spenderAddress={paymentConfig.entryModule}
676
676
  encodedData={encodedData}
677
677
  metadata={{
678
- type: "custom",
679
678
  action: `buy ${userSpinQuantity} spin${userSpinQuantity !== "1" ? "s" : ""}`,
680
679
  }}
681
680
  header={header}
@@ -42,12 +42,15 @@ import { motion } from "motion/react";
42
42
  import React, { useCallback, useEffect, useMemo, useState } from "react";
43
43
  import { toast } from "sonner";
44
44
  import { base } from "viem/chains";
45
+ import { useFeatureFlags } from "../contexts/FeatureFlagsContext";
45
46
  import { AnySpendFingerprintWrapper, getFingerprintConfig } from "./AnySpendFingerprintWrapper";
46
47
  import { CryptoPaymentMethod, CryptoPaymentMethodType } from "./common/CryptoPaymentMethod";
47
48
  import { FiatPaymentMethod, FiatPaymentMethodComponent } from "./common/FiatPaymentMethod";
48
49
  import { OrderDetails } from "./common/OrderDetails";
49
50
  import { OrderHistory } from "./common/OrderHistory";
50
51
  import { OrderToken } from "./common/OrderToken";
52
+ import { PointsBadge } from "./common/PointsBadge";
53
+ import { PointsDetailPanel } from "./common/PointsDetailPanel";
51
54
  import { RecipientSelection } from "./common/RecipientSelection";
52
55
 
53
56
  enum PanelView {
@@ -58,6 +61,7 @@ enum PanelView {
58
61
  RECIPIENT_SELECTION,
59
62
  CRYPTO_PAYMENT_METHOD,
60
63
  FIAT_PAYMENT_METHOD,
64
+ POINTS_DETAIL,
61
65
  }
62
66
 
63
67
  function generateGetRelayQuoteRequest({
@@ -66,6 +70,7 @@ function generateGetRelayQuoteRequest({
66
70
  srcToken,
67
71
  dstChainId,
68
72
  dstToken,
73
+ recipientAddress,
69
74
  dstAmount,
70
75
  contractAddress,
71
76
  tokenId,
@@ -78,6 +83,7 @@ function generateGetRelayQuoteRequest({
78
83
  srcToken: components["schemas"]["Token"];
79
84
  dstChainId: number;
80
85
  dstToken: components["schemas"]["Token"];
86
+ recipientAddress: string | undefined;
81
87
  dstAmount: string;
82
88
  contractAddress: string;
83
89
  tokenId?: number | null;
@@ -94,6 +100,7 @@ function generateGetRelayQuoteRequest({
94
100
  srcTokenAddress: srcToken.address,
95
101
  dstChain: dstChainId,
96
102
  dstTokenAddress: dstToken.address,
103
+ recipientAddress,
97
104
  price: dstAmount,
98
105
  contractAddress: contractAddress,
99
106
  tokenId: tokenId,
@@ -107,6 +114,7 @@ function generateGetRelayQuoteRequest({
107
114
  srcTokenAddress: srcToken.address,
108
115
  dstChain: dstChainId,
109
116
  dstTokenAddress: dstToken.address,
117
+ recipientAddress,
110
118
  price: dstAmount,
111
119
  contractAddress: contractAddress,
112
120
  };
@@ -118,6 +126,7 @@ function generateGetRelayQuoteRequest({
118
126
  srcTokenAddress: srcToken.address,
119
127
  dstChain: dstChainId,
120
128
  dstTokenAddress: dstToken.address,
129
+ recipientAddress,
121
130
  fundAmount: dstAmount,
122
131
  contractAddress: contractAddress,
123
132
  };
@@ -129,6 +138,7 @@ function generateGetRelayQuoteRequest({
129
138
  srcTokenAddress: srcToken.address,
130
139
  dstChain: dstChainId,
131
140
  dstTokenAddress: dstToken.address,
141
+ recipientAddress,
132
142
  payload: {
133
143
  amount: dstAmount,
134
144
  data: encodedData,
@@ -165,6 +175,7 @@ export function AnySpendCustom(props: {
165
175
  }) => React.JSX.Element;
166
176
  onSuccess?: (txHash?: string) => void;
167
177
  showRecipient?: boolean;
178
+ onShowPointsDetail?: () => void;
168
179
  }) {
169
180
  const fingerprintConfig = getFingerprintConfig();
170
181
 
@@ -191,6 +202,7 @@ function AnySpendCustomInner({
191
202
  header,
192
203
  onSuccess,
193
204
  showRecipient = true,
205
+ onShowPointsDetail,
194
206
  }: {
195
207
  loadOrder?: string;
196
208
  mode?: "modal" | "page";
@@ -213,8 +225,10 @@ function AnySpendCustomInner({
213
225
  }) => React.JSX.Element;
214
226
  onSuccess?: (txHash?: string) => void;
215
227
  showRecipient?: boolean;
228
+ onShowPointsDetail?: () => void;
216
229
  }) {
217
230
  const hasMounted = useHasMounted();
231
+ const featureFlags = useFeatureFlags();
218
232
 
219
233
  const searchParams = useSearchParamsSSR();
220
234
  const router = useRouter();
@@ -312,10 +326,11 @@ function AnySpendCustomInner({
312
326
  srcToken: activeTab === "fiat" ? USDC_BASE : srcToken,
313
327
  dstChainId: dstChainId,
314
328
  dstToken: dstToken,
329
+ recipientAddress,
315
330
  dstAmount: dstAmount,
316
331
  contractAddress: contractAddress,
317
- tokenId: metadata.type === "mint_nft" ? metadata.nftContract.tokenId : undefined,
318
- contractType: metadata.type === "mint_nft" ? metadata.nftContract.type : undefined,
332
+ tokenId: orderType === "mint_nft" ? metadata?.nftContract?.tokenId : undefined,
333
+ contractType: orderType === "mint_nft" ? metadata?.nftContract?.type : undefined,
319
334
  encodedData: encodedData,
320
335
  spenderAddress: spenderAddress,
321
336
  });
@@ -328,8 +343,8 @@ function AnySpendCustomInner({
328
343
  encodedData,
329
344
  metadata?.nftContract?.tokenId,
330
345
  metadata?.nftContract?.type,
331
- metadata?.type,
332
346
  orderType,
347
+ recipientAddress,
333
348
  spenderAddress,
334
349
  srcChainId,
335
350
  srcToken,
@@ -426,7 +441,7 @@ function AnySpendCustomInner({
426
441
  recipientAddress,
427
442
  creatorAddress: currentWallet?.wallet?.address,
428
443
  nft:
429
- metadata.type === "mint_nft"
444
+ orderType === "mint_nft"
430
445
  ? metadata.nftContract.type === "erc1155"
431
446
  ? {
432
447
  type: "erc1155",
@@ -448,7 +463,7 @@ function AnySpendCustomInner({
448
463
  }
449
464
  : undefined,
450
465
  tournament:
451
- metadata.type === "join_tournament" || metadata.type === "fund_tournament"
466
+ orderType === "join_tournament" || orderType === "fund_tournament"
452
467
  ? {
453
468
  ...metadata.tournament,
454
469
  contractAddress: contractAddress,
@@ -457,13 +472,12 @@ function AnySpendCustomInner({
457
472
  : undefined,
458
473
  // only populate payload for custom tx
459
474
  payload:
460
- metadata.type === "custom"
475
+ orderType === "custom"
461
476
  ? {
462
477
  amount: dstAmount,
463
478
  data: encodedData,
464
479
  spenderAddress: spenderAddress,
465
480
  to: contractAddress,
466
- action: metadata.action,
467
481
  }
468
482
  : undefined,
469
483
  } as CreateOrderParams;
@@ -749,6 +763,23 @@ function AnySpendCustomInner({
749
763
  </div>
750
764
  );
751
765
 
766
+ // Render points badge if conditions are met
767
+ const renderPointsBadge = () => {
768
+ if (featureFlags.showPoints && anyspendQuote?.data?.pointsAmount && anyspendQuote.data.pointsAmount > 0) {
769
+ return (
770
+ <PointsBadge
771
+ pointsAmount={anyspendQuote.data.pointsAmount}
772
+ pointsMultiplier={anyspendQuote.data.pointsMultiplier}
773
+ onClick={() => {
774
+ onShowPointsDetail?.();
775
+ setActivePanel(PanelView.POINTS_DETAIL);
776
+ }}
777
+ />
778
+ );
779
+ }
780
+ return null;
781
+ };
782
+
752
783
  // Confirm order view.
753
784
  const confirmOrderView = (
754
785
  <div className={"relative mx-auto flex w-full flex-col items-center"}>
@@ -917,9 +948,12 @@ function AnySpendCustomInner({
917
948
  transition={{ duration: 0.3, delay: 0.1, ease: "easeInOut" }}
918
949
  className="relative flex w-full items-center justify-between"
919
950
  >
920
- <span className="text-as-tertiarry text-sm">
921
- Total <span className="text-as-tertiarry">(with fee)</span>
922
- </span>
951
+ <div className="flex items-center gap-2">
952
+ <span className="text-as-tertiarry text-sm">
953
+ Total <span className="text-as-tertiarry">(with fee)</span>
954
+ </span>
955
+ {renderPointsBadge()}
956
+ </div>
923
957
  <span className="text-as-primary font-semibold">
924
958
  {formattedSrcAmount || "--"} {srcToken.symbol}
925
959
  </span>
@@ -1040,9 +1074,12 @@ function AnySpendCustomInner({
1040
1074
  transition={{ duration: 0.3, delay: 0.1, ease: "easeInOut" }}
1041
1075
  className="relative flex w-full items-center justify-between"
1042
1076
  >
1043
- <span className="text-as-tertiarry text-sm">
1044
- Total <span className="text-as-tertiarry">(USD)</span>
1045
- </span>
1077
+ <div className="flex items-center gap-2">
1078
+ <span className="text-as-tertiarry text-sm">
1079
+ Total <span className="text-as-tertiarry">(USD)</span>
1080
+ </span>
1081
+ {renderPointsBadge()}
1082
+ </div>
1046
1083
  <span className="text-as-primary text-xl font-semibold">${srcFiatAmount || "0.00"}</span>
1047
1084
  </motion.div>
1048
1085
  </div>
@@ -1153,6 +1190,16 @@ function AnySpendCustomInner({
1153
1190
  </div>
1154
1191
  );
1155
1192
 
1193
+ // Points detail view
1194
+ const pointsDetailView = (
1195
+ <div className={cn("bg-as-surface-primary mx-auto w-[460px] max-w-full rounded-xl p-4")}>
1196
+ <PointsDetailPanel
1197
+ pointsAmount={anyspendQuote?.data?.pointsAmount || 0}
1198
+ onBack={() => setActivePanel(PanelView.CONFIRM_ORDER)}
1199
+ />
1200
+ </div>
1201
+ );
1202
+
1156
1203
  // Return the TransitionPanel with all views
1157
1204
  return (
1158
1205
  <StyleRoot>
@@ -1196,6 +1243,9 @@ function AnySpendCustomInner({
1196
1243
  <div key="fiat-payment-method-view" className="w-full">
1197
1244
  {fiatPaymentMethodView}
1198
1245
  </div>,
1246
+ <div key="points-detail-view" className="w-full">
1247
+ {pointsDetailView}
1248
+ </div>,
1199
1249
  ]}
1200
1250
  </TransitionPanel>
1201
1251
  </StyleRoot>
@@ -36,12 +36,14 @@ export function AnySpendNFT({
36
36
  recipientAddress,
37
37
  nftContract,
38
38
  onSuccess,
39
+ onShowPointsDetail,
39
40
  }: {
40
41
  loadOrder?: string;
41
42
  mode?: "modal" | "page";
42
43
  recipientAddress?: string;
43
44
  nftContract: components["schemas"]["NftContract"];
44
45
  onSuccess?: (txHash?: string) => void;
46
+ onShowPointsDetail?: () => void;
45
47
  }) {
46
48
  const [imageUrlWithFallback, setFallbackImageUrl] = useState<string | null>(nftContract.imageUrl);
47
49
  const [isLoadingFallback, setIsLoadingFallback] = useState(false);
@@ -164,6 +166,7 @@ export function AnySpendNFT({
164
166
  }}
165
167
  header={header}
166
168
  onSuccess={onSuccess}
169
+ onShowPointsDetail={onShowPointsDetail}
167
170
  />
168
171
  );
169
172
  }
@@ -491,7 +491,6 @@ export function AnySpendStakeB3({
491
491
  contractAddress={ERC20Staking}
492
492
  encodedData={encodedData}
493
493
  metadata={{
494
- type: "custom",
495
494
  action: "stake B3",
496
495
  }}
497
496
  header={header}
@@ -141,10 +141,9 @@ export function AnyspendSignatureMint({
141
141
  dstChainId={signatureData.collection.chainId}
142
142
  dstToken={dstToken}
143
143
  dstAmount={price.toString()}
144
- contractAddress={signatureData.collection.address!}
144
+ contractAddress={signatureData.collection.address || ""}
145
145
  encodedData={encodedData}
146
146
  metadata={{
147
- type: "custom",
148
147
  action: "Signature Mint",
149
148
  }}
150
149
  header={header}
@@ -48,7 +48,7 @@ export function CryptoPaySection({
48
48
  const walletAddress =
49
49
  selectedCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET
50
50
  ? connectedSmartWallet?.getAccount()?.address
51
- : connectedEOAWallet?.getAccount()?.address || connectedSmartWallet?.getAccount()?.address;
51
+ : connectedEOAWallet?.getAccount()?.address;
52
52
 
53
53
  const { data: profileData } = useProfile({ address: walletAddress });
54
54
  const connectedName = profileData?.displayName;
@@ -7,6 +7,7 @@ import { motion } from "motion/react";
7
7
  import { components } from "../../../types/api";
8
8
  import { useFeatureFlags } from "../../contexts/FeatureFlagsContext";
9
9
  import { OrderTokenAmount } from "./OrderTokenAmount";
10
+ import { PointsBadge } from "./PointsBadge";
10
11
 
11
12
  interface CryptoReceiveSectionProps {
12
13
  isDepositMode?: boolean;
@@ -163,15 +164,12 @@ export function CryptoReceiveSection({
163
164
  );
164
165
  })()}
165
166
  </div>
166
- {featureFlags.showPoints && anyspendQuote?.data?.pointsAmount && anyspendQuote.data.pointsAmount > 0 && (
167
- <button
168
- key={`points-${anyspendQuote.data.pointsAmount}`}
169
- className="bg-as-brand hover:scale-102 active:scale-98 active:scale-98 relative flex cursor-pointer items-center gap-1 rounded-lg px-2 py-1 transition-all"
167
+ {featureFlags.showPoints && anyspendQuote?.data?.pointsAmount > 0 && (
168
+ <PointsBadge
169
+ pointsAmount={anyspendQuote.data.pointsAmount}
170
+ pointsMultiplier={anyspendQuote.data.pointsMultiplier}
170
171
  onClick={() => onShowPointsDetail?.()}
171
- >
172
- <div className="pointer-events-none absolute inset-0 h-full w-full rounded-lg border border-white/10 border-t-white/20 bg-gradient-to-b from-white/10 to-white/0" />
173
- <span className="text-xs text-white">+{anyspendQuote.data.pointsAmount.toLocaleString()} pts</span>
174
- </button>
172
+ />
175
173
  )}
176
174
  </div>
177
175
  </motion.div>
@@ -11,6 +11,7 @@ import { toast } from "sonner";
11
11
  import { useFeatureFlags } from "../../contexts/FeatureFlagsContext";
12
12
  import { FiatPaymentMethod } from "./FiatPaymentMethod";
13
13
  import { OrderTokenAmountFiat } from "./OrderTokenAmountFiat";
14
+ import { PointsBadge } from "./PointsBadge";
14
15
 
15
16
  export function PanelOnramp({
16
17
  srcAmountOnRamp,
@@ -259,16 +260,15 @@ export function PanelOnramp({
259
260
  return fee !== null ? `Total (included $${fee.toFixed(2)} fee)` : "Total";
260
261
  })()}
261
262
  </span>
262
- {featureFlags.showPoints && anyspendQuote?.data?.pointsAmount && anyspendQuote.data.pointsAmount > 0 && (
263
- <button
264
- key={`points-${anyspendQuote.data.pointsAmount}`}
265
- className="bg-as-brand hover:scale-102 active:scale-98 relative flex cursor-pointer items-center gap-1 rounded-lg px-2 py-1 transition-all"
266
- onClick={() => onShowPointsDetail?.()}
267
- >
268
- <div className="pointer-events-none absolute inset-0 h-full w-full rounded-lg border border-white/10 border-t-white/20 bg-gradient-to-b from-white/10 to-white/0" />
269
- <span className="text-xs text-white">+{anyspendQuote.data.pointsAmount.toLocaleString()} pts</span>
270
- </button>
271
- )}
263
+ {featureFlags.showPoints &&
264
+ anyspendQuote?.data?.pointsAmount &&
265
+ anyspendQuote?.data?.pointsAmount > 0 && (
266
+ <PointsBadge
267
+ pointsAmount={anyspendQuote.data.pointsAmount}
268
+ pointsMultiplier={anyspendQuote.data.pointsMultiplier}
269
+ onClick={() => onShowPointsDetail?.()}
270
+ />
271
+ )}
272
272
  </div>
273
273
  <span className="text-as-primary font-semibold">
274
274
  ${getTotalAmount(selectedPaymentMethod || FiatPaymentMethod.NONE).toFixed(2)}
@@ -0,0 +1,20 @@
1
+ interface PointsBadgeProps {
2
+ pointsAmount: number;
3
+ pointsMultiplier?: number;
4
+ onClick?: () => void;
5
+ }
6
+
7
+ export function PointsBadge({ pointsAmount, pointsMultiplier, onClick }: PointsBadgeProps) {
8
+ return (
9
+ <button
10
+ className="bg-as-brand hover:scale-102 active:scale-98 relative flex cursor-pointer items-center gap-1 rounded-lg px-2 py-1 transition-all"
11
+ onClick={onClick}
12
+ >
13
+ <div className="pointer-events-none absolute inset-0 h-full w-full rounded-lg border border-white/10 border-t-white/20 bg-gradient-to-b from-white/10 to-white/0" />
14
+ <span className="relative text-xs text-white">
15
+ +{pointsAmount.toLocaleString()} pts
16
+ {pointsMultiplier && pointsMultiplier > 1 && <span className="ml-1 opacity-80">({pointsMultiplier}x)</span>}
17
+ </span>
18
+ </button>
19
+ );
20
+ }
@@ -157,15 +157,17 @@ export function useAnyspendFlow({
157
157
  };
158
158
 
159
159
  // Get quote
160
- const activeInputAmountInWei = parseUnits(srcAmount.replace(/,/g, ""), selectedSrcToken.decimals).toString();
160
+ // For fiat payments, always use USDC decimals (6) regardless of selectedSrcToken
161
+ const effectiveDecimals = paymentType === "fiat" ? USDC_BASE.decimals : selectedSrcToken.decimals;
162
+ const activeInputAmountInWei = parseUnits(srcAmount.replace(/,/g, ""), effectiveDecimals).toString();
161
163
  const { anyspendQuote, isLoadingAnyspendQuote, getAnyspendQuoteError } = useAnyspendQuote({
162
164
  srcChain: paymentType === "fiat" ? base.id : selectedSrcChainId,
163
165
  dstChain: isDepositMode ? base.id : selectedDstChainId, // For deposits, always Base; for swaps, use selected destination
164
166
  srcTokenAddress: paymentType === "fiat" ? USDC_BASE.address : selectedSrcToken.address,
165
167
  dstTokenAddress: isDepositMode ? B3_TOKEN.address : selectedSrcToken.address, // For deposits, always B3
166
- type: "swap",
167
- tradeType: "EXACT_INPUT",
168
+ type: "hype_duel",
168
169
  amount: activeInputAmountInWei,
170
+ recipientAddress: selectedRecipientAddress,
169
171
  onrampVendor: paymentType === "fiat" ? getOnrampVendor(selectedFiatPaymentMethod) : undefined,
170
172
  });
171
173
 
@@ -35,7 +35,7 @@ export function useAnyspendOrderAndTransactions(orderId: string | undefined) {
35
35
 
36
36
  const { data, isLoading, refetch, error } = useQuery<GetOrderAndTxsResponse>({
37
37
  queryKey: ["getAnyspendOrderAndTransactions", orderId],
38
- queryFn: () => anyspendService.getOrderAndTransactions(orderId!),
38
+ queryFn: () => anyspendService.getOrderAndTransactions(orderId),
39
39
  enabled: !!orderId,
40
40
  refetchInterval: 3000,
41
41
  staleTime: 1000,
@@ -6,7 +6,7 @@ import { useMemo } from "react";
6
6
  export function useCoinbaseOnrampOptions(country?: string, visitorData?: VisitorData, isLoadingVisitorData?: boolean) {
7
7
  const { data, isLoading, error, refetch } = useQuery({
8
8
  queryKey: ["getCoinbaseOnrampOptions", country, visitorData],
9
- queryFn: () => anyspendService.getCoinbaseOnrampOptions(country!, visitorData),
9
+ queryFn: () => anyspendService.getCoinbaseOnrampOptions(country, visitorData),
10
10
  enabled: Boolean(country) && !isLoadingVisitorData,
11
11
  });
12
12
 
@@ -111,6 +111,7 @@ export const anyspendService = {
111
111
  },
112
112
 
113
113
  getOrderAndTransactions: async (orderId: string | undefined): Promise<GetOrderAndTxsResponse> => {
114
+ invariant(orderId, "orderId is required");
114
115
  const response = await fetch(`${ANYSPEND_MAINNET_BASE_URL}/orders/${orderId}`);
115
116
  const data: GetOrderAndTxsResponse = await response.json();
116
117
  return data;
@@ -134,9 +135,10 @@ export const anyspendService = {
134
135
  },
135
136
 
136
137
  getCoinbaseOnrampOptions: async (
137
- country: string,
138
+ country: string | undefined,
138
139
  visitorData?: VisitorData,
139
140
  ): Promise<GetCoinbaseOnrampOptionsResponse> => {
141
+ invariant(country, "country is required");
140
142
  const params = new URLSearchParams({
141
143
  country,
142
144
  // include fingerprintId and requestId in the query params