@b3dotfun/sdk 0.0.40-alpha.20 → 0.0.40-alpha.22

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 (36) hide show
  1. package/dist/cjs/anyspend/react/components/AnySpend.js +2 -0
  2. package/dist/cjs/anyspend/react/components/AnySpendCustom.d.ts +1 -0
  3. package/dist/cjs/anyspend/react/components/AnySpendCustom.js +30 -6
  4. package/dist/cjs/anyspend/react/components/AnySpendNFT.d.ts +2 -1
  5. package/dist/cjs/anyspend/react/components/AnySpendNFT.js +2 -2
  6. package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.js +2 -1
  7. package/dist/cjs/anyspend/react/components/common/PanelOnramp.js +4 -1
  8. package/dist/cjs/anyspend/react/components/common/PointsBadge.d.ts +7 -0
  9. package/dist/cjs/anyspend/react/components/common/PointsBadge.js +7 -0
  10. package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +1 -0
  11. package/dist/cjs/anyspend/types/api.d.ts +30 -0
  12. package/dist/esm/anyspend/react/components/AnySpend.js +2 -0
  13. package/dist/esm/anyspend/react/components/AnySpendCustom.d.ts +1 -0
  14. package/dist/esm/anyspend/react/components/AnySpendCustom.js +30 -6
  15. package/dist/esm/anyspend/react/components/AnySpendNFT.d.ts +2 -1
  16. package/dist/esm/anyspend/react/components/AnySpendNFT.js +2 -2
  17. package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.js +2 -1
  18. package/dist/esm/anyspend/react/components/common/PanelOnramp.js +4 -1
  19. package/dist/esm/anyspend/react/components/common/PointsBadge.d.ts +7 -0
  20. package/dist/esm/anyspend/react/components/common/PointsBadge.js +4 -0
  21. package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +1 -0
  22. package/dist/esm/anyspend/types/api.d.ts +30 -0
  23. package/dist/styles/index.css +1 -1
  24. package/dist/types/anyspend/react/components/AnySpendCustom.d.ts +1 -0
  25. package/dist/types/anyspend/react/components/AnySpendNFT.d.ts +2 -1
  26. package/dist/types/anyspend/react/components/common/PointsBadge.d.ts +7 -0
  27. package/dist/types/anyspend/types/api.d.ts +30 -0
  28. package/package.json +1 -1
  29. package/src/anyspend/react/components/AnySpend.tsx +2 -0
  30. package/src/anyspend/react/components/AnySpendCustom.tsx +60 -8
  31. package/src/anyspend/react/components/AnySpendNFT.tsx +3 -0
  32. package/src/anyspend/react/components/common/CryptoReceiveSection.tsx +6 -8
  33. package/src/anyspend/react/components/common/PanelOnramp.tsx +10 -10
  34. package/src/anyspend/react/components/common/PointsBadge.tsx +20 -0
  35. package/src/anyspend/react/hooks/useAnyspendFlow.ts +1 -0
  36. package/src/anyspend/types/api.ts +30 -0
@@ -448,6 +448,7 @@ function AnySpendInner({
448
448
  type: "swap",
449
449
  tradeType: isSrcInputDirty ? "EXACT_INPUT" : "EXACT_OUTPUT",
450
450
  amount: activeInputAmountInWei,
451
+ recipientAddress,
451
452
  }
452
453
  : {
453
454
  srcChain: base.id,
@@ -457,6 +458,7 @@ function AnySpendInner({
457
458
  type: "swap",
458
459
  tradeType: "EXACT_INPUT",
459
460
  amount: srcAmountOnrampInWei,
461
+ recipientAddress,
460
462
  onrampVendor: getOnrampVendor(selectedFiatPaymentMethod),
461
463
  },
462
464
  );
@@ -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: orderType === "mint_nft" ? metadata.nftContract.tokenId : undefined,
318
- contractType: orderType === "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
  });
@@ -329,6 +344,7 @@ function AnySpendCustomInner({
329
344
  metadata?.nftContract?.tokenId,
330
345
  metadata?.nftContract?.type,
331
346
  orderType,
347
+ recipientAddress,
332
348
  spenderAddress,
333
349
  srcChainId,
334
350
  srcToken,
@@ -747,6 +763,23 @@ function AnySpendCustomInner({
747
763
  </div>
748
764
  );
749
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
+
750
783
  // Confirm order view.
751
784
  const confirmOrderView = (
752
785
  <div className={"relative mx-auto flex w-full flex-col items-center"}>
@@ -915,9 +948,12 @@ function AnySpendCustomInner({
915
948
  transition={{ duration: 0.3, delay: 0.1, ease: "easeInOut" }}
916
949
  className="relative flex w-full items-center justify-between"
917
950
  >
918
- <span className="text-as-tertiarry text-sm">
919
- Total <span className="text-as-tertiarry">(with fee)</span>
920
- </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>
921
957
  <span className="text-as-primary font-semibold">
922
958
  {formattedSrcAmount || "--"} {srcToken.symbol}
923
959
  </span>
@@ -1038,9 +1074,12 @@ function AnySpendCustomInner({
1038
1074
  transition={{ duration: 0.3, delay: 0.1, ease: "easeInOut" }}
1039
1075
  className="relative flex w-full items-center justify-between"
1040
1076
  >
1041
- <span className="text-as-tertiarry text-sm">
1042
- Total <span className="text-as-tertiarry">(USD)</span>
1043
- </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>
1044
1083
  <span className="text-as-primary text-xl font-semibold">${srcFiatAmount || "0.00"}</span>
1045
1084
  </motion.div>
1046
1085
  </div>
@@ -1151,6 +1190,16 @@ function AnySpendCustomInner({
1151
1190
  </div>
1152
1191
  );
1153
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
+
1154
1203
  // Return the TransitionPanel with all views
1155
1204
  return (
1156
1205
  <StyleRoot>
@@ -1194,6 +1243,9 @@ function AnySpendCustomInner({
1194
1243
  <div key="fiat-payment-method-view" className="w-full">
1195
1244
  {fiatPaymentMethodView}
1196
1245
  </div>,
1246
+ <div key="points-detail-view" className="w-full">
1247
+ {pointsDetailView}
1248
+ </div>,
1197
1249
  ]}
1198
1250
  </TransitionPanel>
1199
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
  }
@@ -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
+ }
@@ -166,6 +166,7 @@ export function useAnyspendFlow({
166
166
  type: "swap",
167
167
  tradeType: "EXACT_INPUT",
168
168
  amount: activeInputAmountInWei,
169
+ recipientAddress: selectedRecipientAddress,
169
170
  onrampVendor: paymentType === "fiat" ? getOnrampVendor(selectedFiatPaymentMethod) : undefined,
170
171
  });
171
172
 
@@ -505,6 +505,11 @@ export interface paths {
505
505
  * @example 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
506
506
  */
507
507
  dstTokenAddress: string;
508
+ /**
509
+ * @description Recipient address
510
+ * @example 0x55c71fca5e01cf246718748ae540473e608d0282
511
+ */
512
+ recipientAddress?: string;
508
513
  /**
509
514
  * @description Type of trade execution
510
515
  * @enum {string}
@@ -547,6 +552,11 @@ export interface paths {
547
552
  * @example 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
548
553
  */
549
554
  dstTokenAddress: string;
555
+ /**
556
+ * @description Recipient address
557
+ * @example 0x55c71fca5e01cf246718748ae540473e608d0282
558
+ */
559
+ recipientAddress?: string;
550
560
  /** @description Custom payload for execution */
551
561
  payload: {
552
562
  /** @description Encoded transaction data */
@@ -571,6 +581,11 @@ export interface paths {
571
581
  dstChain: number;
572
582
  srcTokenAddress: string;
573
583
  dstTokenAddress: string;
584
+ /**
585
+ * @description Recipient address
586
+ * @example 0x55c71fca5e01cf246718748ae540473e608d0282
587
+ */
588
+ recipientAddress?: string;
574
589
  /** @enum {string} */
575
590
  onrampVendor?: "coinbase" | "stripe" | "stripe-web2";
576
591
  contractAddress: string;
@@ -586,6 +601,11 @@ export interface paths {
586
601
  dstChain: number;
587
602
  srcTokenAddress: string;
588
603
  dstTokenAddress: string;
604
+ /**
605
+ * @description Recipient address
606
+ * @example 0x55c71fca5e01cf246718748ae540473e608d0282
607
+ */
608
+ recipientAddress?: string;
589
609
  /** @enum {string} */
590
610
  onrampVendor?: "coinbase" | "stripe" | "stripe-web2";
591
611
  contractAddress: string;
@@ -598,6 +618,11 @@ export interface paths {
598
618
  dstChain: number;
599
619
  srcTokenAddress: string;
600
620
  dstTokenAddress: string;
621
+ /**
622
+ * @description Recipient address
623
+ * @example 0x55c71fca5e01cf246718748ae540473e608d0282
624
+ */
625
+ recipientAddress?: string;
601
626
  /** @enum {string} */
602
627
  onrampVendor?: "coinbase" | "stripe" | "stripe-web2";
603
628
  contractAddress: string;
@@ -629,6 +654,11 @@ export interface paths {
629
654
  * @example 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
630
655
  */
631
656
  dstTokenAddress: string;
657
+ /**
658
+ * @description Recipient address
659
+ * @example 0x55c71fca5e01cf246718748ae540473e608d0282
660
+ */
661
+ recipientAddress?: string;
632
662
  /**
633
663
  * @description Amount to quote
634
664
  * @example 1000000000000000000