@b3dotfun/sdk 0.0.40-alpha.6 → 0.0.40-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/anyspend/react/components/AnySpend.js +1 -1
- package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +1 -1
- package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.js +38 -36
- package/dist/cjs/anyspend/react/components/common/PanelOnramp.d.ts +3 -1
- package/dist/cjs/anyspend/react/components/common/PanelOnramp.js +7 -6
- package/dist/cjs/anyspend/react/contexts/FeatureFlagsContext.d.ts +11 -0
- package/dist/cjs/anyspend/react/contexts/FeatureFlagsContext.js +21 -0
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +1 -65
- package/dist/cjs/anyspend/react/providers/AnyspendProvider.d.ts +5 -2
- package/dist/cjs/anyspend/react/providers/AnyspendProvider.js +5 -3
- package/dist/cjs/anyspend/react/providers/index.d.ts +1 -0
- package/dist/cjs/anyspend/react/providers/index.js +3 -0
- package/dist/cjs/anyspend/types/api_req_res.d.ts +8 -1
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +3 -2
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +35 -16
- package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStepCustom.js +4 -3
- package/dist/cjs/global-account/react/hooks/useAuthentication.js +1 -2
- package/dist/esm/anyspend/react/components/AnySpend.js +1 -1
- package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +1 -1
- package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.js +38 -36
- package/dist/esm/anyspend/react/components/common/PanelOnramp.d.ts +3 -1
- package/dist/esm/anyspend/react/components/common/PanelOnramp.js +7 -6
- package/dist/esm/anyspend/react/contexts/FeatureFlagsContext.d.ts +11 -0
- package/dist/esm/anyspend/react/contexts/FeatureFlagsContext.js +17 -0
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +1 -65
- package/dist/esm/anyspend/react/providers/AnyspendProvider.d.ts +5 -2
- package/dist/esm/anyspend/react/providers/AnyspendProvider.js +5 -3
- package/dist/esm/anyspend/react/providers/index.d.ts +1 -0
- package/dist/esm/anyspend/react/providers/index.js +1 -0
- package/dist/esm/anyspend/types/api_req_res.d.ts +8 -1
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +3 -2
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +36 -17
- package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStepCustom.js +3 -2
- package/dist/esm/global-account/react/hooks/useAuthentication.js +1 -2
- package/dist/types/anyspend/react/components/common/PanelOnramp.d.ts +3 -1
- package/dist/types/anyspend/react/contexts/FeatureFlagsContext.d.ts +11 -0
- package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +1 -65
- package/dist/types/anyspend/react/providers/AnyspendProvider.d.ts +5 -2
- package/dist/types/anyspend/react/providers/index.d.ts +1 -0
- package/dist/types/anyspend/types/api_req_res.d.ts +8 -1
- package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +3 -2
- package/package.json +6 -5
- package/src/anyspend/react/components/AnySpend.tsx +1 -0
- package/src/anyspend/react/components/AnyspendDepositHype.tsx +1 -0
- package/src/anyspend/react/components/common/CryptoReceiveSection.tsx +56 -45
- package/src/anyspend/react/components/common/PanelOnramp.tsx +22 -16
- package/src/anyspend/react/contexts/FeatureFlagsContext.tsx +34 -0
- package/src/anyspend/react/providers/AnyspendProvider.tsx +11 -6
- package/src/anyspend/react/providers/index.ts +1 -0
- package/src/anyspend/types/api_req_res.ts +10 -1
- package/src/global-account/react/components/B3Provider/B3Provider.tsx +49 -24
- package/src/global-account/react/components/SignInWithB3/steps/LoginStepCustom.tsx +4 -2
- package/src/global-account/react/hooks/useAuthentication.ts +1 -2
|
@@ -78,71 +78,7 @@ export declare function useAnyspendFlow({ paymentType, recipientAddress, loadOrd
|
|
|
78
78
|
globalAddress: string | undefined;
|
|
79
79
|
hasEnoughBalance: boolean;
|
|
80
80
|
isBalanceLoading: boolean;
|
|
81
|
-
anyspendQuote:
|
|
82
|
-
success: boolean;
|
|
83
|
-
message: string;
|
|
84
|
-
data: {
|
|
85
|
-
operation?: string;
|
|
86
|
-
sender?: string;
|
|
87
|
-
recipient?: string;
|
|
88
|
-
currencyIn?: {
|
|
89
|
-
currency?: {
|
|
90
|
-
chainId?: number;
|
|
91
|
-
address?: string;
|
|
92
|
-
symbol?: string;
|
|
93
|
-
name?: string;
|
|
94
|
-
decimals?: number;
|
|
95
|
-
metadata?: {
|
|
96
|
-
logoURI?: string;
|
|
97
|
-
};
|
|
98
|
-
};
|
|
99
|
-
amount?: string;
|
|
100
|
-
amountFormatted?: string;
|
|
101
|
-
amountUsd?: string;
|
|
102
|
-
minimumAmount?: string;
|
|
103
|
-
};
|
|
104
|
-
currencyOut?: {
|
|
105
|
-
currency?: {
|
|
106
|
-
chainId?: number;
|
|
107
|
-
address?: string;
|
|
108
|
-
symbol?: string;
|
|
109
|
-
name?: string;
|
|
110
|
-
decimals?: number;
|
|
111
|
-
metadata?: {
|
|
112
|
-
logoURI?: string;
|
|
113
|
-
};
|
|
114
|
-
};
|
|
115
|
-
amount?: string;
|
|
116
|
-
amountFormatted?: string;
|
|
117
|
-
amountUsd?: string;
|
|
118
|
-
minimumAmount?: string;
|
|
119
|
-
};
|
|
120
|
-
totalImpact?: {
|
|
121
|
-
usd?: string;
|
|
122
|
-
percent?: string;
|
|
123
|
-
};
|
|
124
|
-
swapImpact?: {
|
|
125
|
-
usd?: string;
|
|
126
|
-
percent?: string;
|
|
127
|
-
};
|
|
128
|
-
rate?: string;
|
|
129
|
-
slippageTolerance?: {
|
|
130
|
-
origin?: {
|
|
131
|
-
usd?: string;
|
|
132
|
-
value?: string;
|
|
133
|
-
percent?: string;
|
|
134
|
-
};
|
|
135
|
-
destination?: {
|
|
136
|
-
usd?: string;
|
|
137
|
-
value?: string;
|
|
138
|
-
percent?: string;
|
|
139
|
-
};
|
|
140
|
-
};
|
|
141
|
-
timeEstimate?: number;
|
|
142
|
-
userBalance?: string;
|
|
143
|
-
};
|
|
144
|
-
statusCode: number;
|
|
145
|
-
} | undefined;
|
|
81
|
+
anyspendQuote: import("../../types/api_req_res").GetQuoteResponse | undefined;
|
|
146
82
|
isLoadingAnyspendQuote: boolean;
|
|
147
83
|
getAnyspendQuoteError: Error | null;
|
|
148
84
|
activeInputAmountInWei: string;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
|
+
import { FeatureFlags } from "../contexts/FeatureFlagsContext";
|
|
2
3
|
interface AnyspendProviderProps {
|
|
3
4
|
children: ReactNode;
|
|
5
|
+
featureFlags?: FeatureFlags;
|
|
4
6
|
}
|
|
5
7
|
/**
|
|
6
8
|
* AnyspendProvider is a top-level provider that wraps your application to provide
|
|
@@ -12,17 +14,18 @@ interface AnyspendProviderProps {
|
|
|
12
14
|
* - Safe to use at the application root
|
|
13
15
|
* - Configures sensible defaults for query caching
|
|
14
16
|
* - Handles Stripe payment redirects and modal state
|
|
17
|
+
* - Provides feature flags configuration
|
|
15
18
|
*
|
|
16
19
|
* @example
|
|
17
20
|
* ```tsx
|
|
18
21
|
* function App() {
|
|
19
22
|
* return (
|
|
20
|
-
* <AnyspendProvider>
|
|
23
|
+
* <AnyspendProvider featureFlags={{ showPoints: true }}>
|
|
21
24
|
* <YourApp />
|
|
22
25
|
* </AnyspendProvider>
|
|
23
26
|
* );
|
|
24
27
|
* }
|
|
25
28
|
* ```
|
|
26
29
|
*/
|
|
27
|
-
export declare const AnyspendProvider: ({ children }: AnyspendProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
export declare const AnyspendProvider: ({ children, featureFlags }: AnyspendProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
28
31
|
export {};
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { paths } from "./api";
|
|
2
2
|
export type GetOrderAndTxsResponse = paths["/orders/{orderId}"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
3
3
|
export type GetQuoteRequest = paths["/orders/quote"]["post"]["requestBody"]["content"]["application/json"];
|
|
4
|
-
|
|
4
|
+
type BaseGetQuoteResponse = paths["/orders/quote"]["post"]["responses"]["200"]["content"]["application/json"];
|
|
5
|
+
export type GetQuoteResponse = BaseGetQuoteResponse & {
|
|
6
|
+
data: BaseGetQuoteResponse["data"] & {
|
|
7
|
+
pointsAmount?: number;
|
|
8
|
+
pointsMultiplier?: number;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
5
11
|
export type GetCoinbaseOnrampOptionsResponse = paths["/onramp/coinbase/options"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
6
12
|
export type GetOrderHistoryResponse = paths["/orders"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
7
13
|
export type GetTokenListResponse = paths["/chains/{chainId}/tokens"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
8
14
|
export type CreateOrderResponse = paths["/orders"]["post"]["responses"]["200"]["content"]["application/json"];
|
|
9
15
|
export type GetStripeSupportedResponse = paths["/onramp/stripe/supported"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
10
16
|
export type GetStripeClientSecret = paths["/stripe/clientSecret"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
17
|
+
export {};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { PermissionsConfig } from "@b3dotfun/sdk/global-account/types/permissions";
|
|
2
|
+
import "@reservoir0x/relay-kit-ui/styles.css";
|
|
2
3
|
import { Account } from "thirdweb/wallets";
|
|
3
4
|
import { ClientType } from "../../../client-manager";
|
|
4
5
|
import { B3ContextType } from "./types";
|
|
5
|
-
import "@reservoir0x/relay-kit-ui/styles.css";
|
|
6
6
|
/**
|
|
7
7
|
* Main B3Provider component
|
|
8
8
|
*/
|
|
9
|
-
export declare function B3Provider({ theme, children, accountOverride, environment, automaticallySetFirstEoa, simDuneApiKey, toaster, clientType, rpcUrls, }: {
|
|
9
|
+
export declare function B3Provider({ theme, children, accountOverride, environment, automaticallySetFirstEoa, simDuneApiKey, toaster, clientType, rpcUrls, partnerId, }: {
|
|
10
10
|
theme: "light" | "dark";
|
|
11
11
|
children: React.ReactNode;
|
|
12
12
|
accountOverride?: Account;
|
|
@@ -19,6 +19,7 @@ export declare function B3Provider({ theme, children, accountOverride, environme
|
|
|
19
19
|
};
|
|
20
20
|
clientType?: ClientType;
|
|
21
21
|
rpcUrls?: Record<number, string>;
|
|
22
|
+
partnerId?: string;
|
|
22
23
|
}): import("react/jsx-runtime").JSX.Element;
|
|
23
24
|
/**
|
|
24
25
|
* Inner provider component that provides the actual B3Context
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@b3dotfun/sdk",
|
|
3
|
-
"version": "0.0.40-alpha.
|
|
3
|
+
"version": "0.0.40-alpha.8",
|
|
4
4
|
"source": "src/index.ts",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"react-native": "./dist/cjs/index.native.js",
|
|
@@ -241,8 +241,8 @@
|
|
|
241
241
|
"@b3dotfun/basement-api": "0.0.11",
|
|
242
242
|
"@feathersjs/authentication-client": "5.0.33",
|
|
243
243
|
"@feathersjs/feathers": "5.0.33",
|
|
244
|
-
"@feathersjs/socketio-client": "5.0.33",
|
|
245
244
|
"@feathersjs/rest-client": "5.0.33",
|
|
245
|
+
"@feathersjs/socketio-client": "5.0.33",
|
|
246
246
|
"@feathersjs/typebox": "5.0.33",
|
|
247
247
|
"@fingerprintjs/fingerprintjs-pro-react": "^2.7.0",
|
|
248
248
|
"@hey-api/client-fetch": "0.8.3",
|
|
@@ -261,6 +261,7 @@
|
|
|
261
261
|
"@solana/web3.js": "^1.98.2",
|
|
262
262
|
"@stripe/react-stripe-js": "^3.7.0",
|
|
263
263
|
"@stripe/stripe-js": "^7.3.1",
|
|
264
|
+
"@thirdweb-dev/wagmi-adapter": "^0.2.141",
|
|
264
265
|
"@web3icons/react": "3.16.0",
|
|
265
266
|
"big.js": "^7.0.1",
|
|
266
267
|
"class-variance-authority": "0.7.0",
|
|
@@ -329,10 +330,10 @@
|
|
|
329
330
|
"react": "^18.0.0 || ^19.0.0",
|
|
330
331
|
"react-dom": "^18.0.0 || ^19.0.0",
|
|
331
332
|
"react-native-mmkv": "^3.2.0",
|
|
332
|
-
"thirdweb": "
|
|
333
|
+
"thirdweb": "5.106.0",
|
|
333
334
|
"three": "^0.175.0",
|
|
334
|
-
"
|
|
335
|
-
"
|
|
335
|
+
"viem": "^2.28.1",
|
|
336
|
+
"wagmi": "^2.14.15"
|
|
336
337
|
},
|
|
337
338
|
"peerDependenciesMeta": {
|
|
338
339
|
"@react-three/postprocessing": {
|
|
@@ -223,6 +223,7 @@ function AnySpendDepositHypeInner({
|
|
|
223
223
|
onDestinationChainChange={() => {}}
|
|
224
224
|
fiatPaymentMethodIndex={PanelView.FIAT_PAYMENT_METHOD}
|
|
225
225
|
recipientSelectionPanelIndex={PanelView.RECIPIENT_SELECTION}
|
|
226
|
+
anyspendQuote={anyspendQuote}
|
|
226
227
|
/>
|
|
227
228
|
</motion.div>
|
|
228
229
|
)}
|
|
@@ -4,7 +4,9 @@ import { shortenAddress } from "@b3dotfun/sdk/shared/utils/formatAddress";
|
|
|
4
4
|
import { formatDisplayNumber } from "@b3dotfun/sdk/shared/utils/number";
|
|
5
5
|
import { ChevronRight } from "lucide-react";
|
|
6
6
|
import { motion } from "motion/react";
|
|
7
|
+
import { useEffect } from "react";
|
|
7
8
|
import { components } from "../../../types/api";
|
|
9
|
+
import { useFeatureFlags } from "../../contexts/FeatureFlagsContext";
|
|
8
10
|
import { OrderTokenAmount } from "./OrderTokenAmount";
|
|
9
11
|
|
|
10
12
|
interface CryptoReceiveSectionProps {
|
|
@@ -45,6 +47,8 @@ export function CryptoReceiveSection({
|
|
|
45
47
|
dstTokenSymbol,
|
|
46
48
|
dstTokenLogoURI,
|
|
47
49
|
}: CryptoReceiveSectionProps) {
|
|
50
|
+
const featureFlags = useFeatureFlags();
|
|
51
|
+
|
|
48
52
|
return (
|
|
49
53
|
<motion.div
|
|
50
54
|
initial={{ opacity: 0, y: 20, filter: "blur(10px)" }}
|
|
@@ -100,61 +104,68 @@ export function CryptoReceiveSection({
|
|
|
100
104
|
setToken={setSelectedDstToken || (() => {})}
|
|
101
105
|
/>
|
|
102
106
|
)}
|
|
103
|
-
<div className="text-as-primary/50 flex h-5 items-center text-sm">
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
anyspendQuote?.data?.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
107
|
+
<div className="text-as-primary/50 flex h-5 items-center justify-between text-sm">
|
|
108
|
+
<div className="flex items-center gap-2">
|
|
109
|
+
{formatDisplayNumber(anyspendQuote?.data?.currencyOut?.amountUsd, {
|
|
110
|
+
style: "currency",
|
|
111
|
+
fallback: "",
|
|
112
|
+
})}
|
|
113
|
+
{anyspendQuote?.data?.currencyIn?.amountUsd &&
|
|
114
|
+
anyspendQuote?.data?.currencyOut?.amountUsd &&
|
|
115
|
+
(() => {
|
|
116
|
+
const calculatePriceImpact = (inputUsd?: string | number, outputUsd?: string | number) => {
|
|
117
|
+
if (!inputUsd || !outputUsd) {
|
|
118
|
+
return { percentage: "0.00", isNegative: false };
|
|
119
|
+
}
|
|
115
120
|
|
|
116
|
-
|
|
117
|
-
|
|
121
|
+
const input = Number(inputUsd);
|
|
122
|
+
const output = Number(outputUsd);
|
|
118
123
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
124
|
+
// Handle edge cases
|
|
125
|
+
if (input === 0 || isNaN(input) || isNaN(output) || input <= output) {
|
|
126
|
+
return { percentage: "0.00", isNegative: false };
|
|
127
|
+
}
|
|
123
128
|
|
|
124
|
-
|
|
129
|
+
const percentageValue = ((output - input) / input) * 100;
|
|
125
130
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
131
|
+
// Handle the -0.00% case
|
|
132
|
+
if (percentageValue > -0.005 && percentageValue < 0) {
|
|
133
|
+
return { percentage: "0.00", isNegative: false };
|
|
134
|
+
}
|
|
130
135
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
136
|
+
return {
|
|
137
|
+
percentage: Math.abs(percentageValue).toFixed(2),
|
|
138
|
+
isNegative: percentageValue < 0,
|
|
139
|
+
};
|
|
134
140
|
};
|
|
135
|
-
};
|
|
136
141
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
142
|
+
const { percentage, isNegative } = calculatePriceImpact(
|
|
143
|
+
anyspendQuote.data.currencyIn.amountUsd,
|
|
144
|
+
anyspendQuote.data.currencyOut.amountUsd,
|
|
145
|
+
);
|
|
141
146
|
|
|
142
|
-
|
|
143
|
-
|
|
147
|
+
// Parse the percentage as a number for comparison
|
|
148
|
+
const percentageNum = parseFloat(percentage);
|
|
144
149
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
150
|
+
// Don't show if less than 1%
|
|
151
|
+
if (percentageNum < 1) {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
149
154
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
// Using inline style to ensure color displays
|
|
156
|
+
return (
|
|
157
|
+
<span className="ml-2" style={{ color: percentageNum >= 10 ? "red" : "#FFD700" }}>
|
|
158
|
+
({isNegative ? "-" : ""}
|
|
159
|
+
{percentage}%)
|
|
160
|
+
</span>
|
|
161
|
+
);
|
|
162
|
+
})()}
|
|
163
|
+
</div>
|
|
164
|
+
{featureFlags.showPoints && anyspendQuote?.data?.pointsAmount && anyspendQuote.data.pointsAmount > 0 && (
|
|
165
|
+
<div key={`points-${anyspendQuote.data.pointsAmount}`} className="flex items-center gap-1">
|
|
166
|
+
<span className="text-as-brand font-medium">+{anyspendQuote.data.pointsAmount.toLocaleString()} pts</span>
|
|
167
|
+
</div>
|
|
168
|
+
)}
|
|
158
169
|
</div>
|
|
159
170
|
</motion.div>
|
|
160
171
|
);
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { useCoinbaseOnrampOptions, useGeoOnrampOptions } from "@b3dotfun/sdk/anyspend/react";
|
|
2
2
|
import { components } from "@b3dotfun/sdk/anyspend/types/api";
|
|
3
|
+
import { GetQuoteResponse } from "@b3dotfun/sdk/anyspend/types/api_req_res";
|
|
3
4
|
import { ALL_CHAINS } from "@b3dotfun/sdk/anyspend/utils/chain";
|
|
4
5
|
import { Input, useGetGeo, useProfile } from "@b3dotfun/sdk/global-account/react";
|
|
5
6
|
import { cn, formatUsername } from "@b3dotfun/sdk/shared/utils";
|
|
6
7
|
import { formatAddress } from "@b3dotfun/sdk/shared/utils/formatAddress";
|
|
7
8
|
import { ChevronRight, Wallet } from "lucide-react";
|
|
8
|
-
import { useRef } from "react";
|
|
9
|
+
import { useRef, useEffect } from "react";
|
|
9
10
|
import { toast } from "sonner";
|
|
11
|
+
import { useFeatureFlags } from "../../contexts/FeatureFlagsContext";
|
|
10
12
|
import { FiatPaymentMethod } from "./FiatPaymentMethod";
|
|
11
13
|
import { OrderTokenAmountFiat } from "./OrderTokenAmountFiat";
|
|
12
14
|
|
|
@@ -25,6 +27,7 @@ export function PanelOnramp({
|
|
|
25
27
|
recipientSelectionPanelIndex,
|
|
26
28
|
dstTokenSymbol,
|
|
27
29
|
hideDstToken = false,
|
|
30
|
+
anyspendQuote,
|
|
28
31
|
}: {
|
|
29
32
|
srcAmountOnRamp: string;
|
|
30
33
|
setSrcAmountOnRamp: (amount: string) => void;
|
|
@@ -40,7 +43,9 @@ export function PanelOnramp({
|
|
|
40
43
|
recipientSelectionPanelIndex: number;
|
|
41
44
|
dstTokenSymbol?: string;
|
|
42
45
|
hideDstToken?: boolean;
|
|
46
|
+
anyspendQuote?: GetQuoteResponse;
|
|
43
47
|
}) {
|
|
48
|
+
const featureFlags = useFeatureFlags();
|
|
44
49
|
// Get geo-based onramp options to access fee information
|
|
45
50
|
const { stripeWeb2Support } = useGeoOnrampOptions(srcAmountOnRamp);
|
|
46
51
|
|
|
@@ -245,21 +250,22 @@ export function PanelOnramp({
|
|
|
245
250
|
|
|
246
251
|
<div className="">
|
|
247
252
|
<div className="flex items-center justify-between">
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
253
|
+
<div className="flex items-center gap-2">
|
|
254
|
+
<span className="text-as-tertiarry text-sm">
|
|
255
|
+
{(() => {
|
|
256
|
+
const fee = getFeeFromApi(selectedPaymentMethod || FiatPaymentMethod.NONE);
|
|
257
|
+
return fee !== null ? `Total (included $${fee.toFixed(2)} fee)` : "Total";
|
|
258
|
+
})()}
|
|
259
|
+
</span>
|
|
260
|
+
{featureFlags.showPoints && anyspendQuote?.data?.pointsAmount && anyspendQuote.data.pointsAmount > 0 && (
|
|
261
|
+
<span key={`points-${anyspendQuote.data.pointsAmount}`} className="text-as-brand text-sm font-medium">
|
|
262
|
+
+{anyspendQuote.data.pointsAmount.toLocaleString()} pts
|
|
263
|
+
</span>
|
|
264
|
+
)}
|
|
265
|
+
</div>
|
|
266
|
+
<span className="text-as-primary font-semibold">
|
|
267
|
+
${getTotalAmount(selectedPaymentMethod || FiatPaymentMethod.NONE).toFixed(2)}
|
|
268
|
+
</span>
|
|
263
269
|
</div>
|
|
264
270
|
</div>
|
|
265
271
|
</div>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { createContext, useContext, ReactNode } from "react";
|
|
4
|
+
|
|
5
|
+
export interface FeatureFlags {
|
|
6
|
+
showPoints?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface FeatureFlagsContextType {
|
|
10
|
+
featureFlags: FeatureFlags;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const FeatureFlagsContext = createContext<FeatureFlagsContextType | undefined>(undefined);
|
|
14
|
+
|
|
15
|
+
interface FeatureFlagsProviderProps {
|
|
16
|
+
children: ReactNode;
|
|
17
|
+
featureFlags?: FeatureFlags;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const defaultFeatureFlags: FeatureFlags = {
|
|
21
|
+
showPoints: false,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export function FeatureFlagsProvider({ children, featureFlags = defaultFeatureFlags }: FeatureFlagsProviderProps) {
|
|
25
|
+
return <FeatureFlagsContext.Provider value={{ featureFlags }}>{children}</FeatureFlagsContext.Provider>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function useFeatureFlags(): FeatureFlags {
|
|
29
|
+
const context = useContext(FeatureFlagsContext);
|
|
30
|
+
if (!context) {
|
|
31
|
+
return defaultFeatureFlags;
|
|
32
|
+
}
|
|
33
|
+
return context.featureFlags;
|
|
34
|
+
}
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
import { TooltipProvider } from "@b3dotfun/sdk/global-account/react";
|
|
4
4
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
5
5
|
import { ReactNode, useState } from "react";
|
|
6
|
+
import { FeatureFlags, FeatureFlagsProvider } from "../contexts/FeatureFlagsContext";
|
|
6
7
|
import { StripeRedirectHandler } from "./StripeRedirectHandler";
|
|
7
8
|
|
|
8
9
|
interface AnyspendProviderProps {
|
|
9
10
|
children: ReactNode;
|
|
11
|
+
featureFlags?: FeatureFlags;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
const defaultQueryClientConfig = {
|
|
@@ -29,27 +31,30 @@ const defaultQueryClientConfig = {
|
|
|
29
31
|
* - Safe to use at the application root
|
|
30
32
|
* - Configures sensible defaults for query caching
|
|
31
33
|
* - Handles Stripe payment redirects and modal state
|
|
34
|
+
* - Provides feature flags configuration
|
|
32
35
|
*
|
|
33
36
|
* @example
|
|
34
37
|
* ```tsx
|
|
35
38
|
* function App() {
|
|
36
39
|
* return (
|
|
37
|
-
* <AnyspendProvider>
|
|
40
|
+
* <AnyspendProvider featureFlags={{ showPoints: true }}>
|
|
38
41
|
* <YourApp />
|
|
39
42
|
* </AnyspendProvider>
|
|
40
43
|
* );
|
|
41
44
|
* }
|
|
42
45
|
* ```
|
|
43
46
|
*/
|
|
44
|
-
export const AnyspendProvider = function AnyspendProvider({ children }: AnyspendProviderProps) {
|
|
47
|
+
export const AnyspendProvider = function AnyspendProvider({ children, featureFlags }: AnyspendProviderProps) {
|
|
45
48
|
const [queryClient] = useState(() => new QueryClient(defaultQueryClientConfig));
|
|
46
49
|
|
|
47
50
|
return (
|
|
48
51
|
<QueryClientProvider client={queryClient}>
|
|
49
|
-
<
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
<FeatureFlagsProvider featureFlags={featureFlags}>
|
|
53
|
+
<TooltipProvider>
|
|
54
|
+
<StripeRedirectHandler />
|
|
55
|
+
{children}
|
|
56
|
+
</TooltipProvider>
|
|
57
|
+
</FeatureFlagsProvider>
|
|
53
58
|
</QueryClientProvider>
|
|
54
59
|
);
|
|
55
60
|
};
|
|
@@ -3,7 +3,16 @@ import { paths } from "./api";
|
|
|
3
3
|
export type GetOrderAndTxsResponse =
|
|
4
4
|
paths["/orders/{orderId}"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
5
5
|
export type GetQuoteRequest = paths["/orders/quote"]["post"]["requestBody"]["content"]["application/json"];
|
|
6
|
-
|
|
6
|
+
// Base type from auto-generated API
|
|
7
|
+
type BaseGetQuoteResponse = paths["/orders/quote"]["post"]["responses"]["200"]["content"]["application/json"];
|
|
8
|
+
|
|
9
|
+
// Extended type with additional points fields
|
|
10
|
+
export type GetQuoteResponse = BaseGetQuoteResponse & {
|
|
11
|
+
data: BaseGetQuoteResponse["data"] & {
|
|
12
|
+
pointsAmount?: number;
|
|
13
|
+
pointsMultiplier?: number;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
7
16
|
export type GetCoinbaseOnrampOptionsResponse =
|
|
8
17
|
paths["/onramp/coinbase/options"]["get"]["responses"]["200"]["content"]["application/json"];
|
|
9
18
|
export type GetOrderHistoryResponse = paths["/orders"]["get"]["responses"]["200"]["content"]["application/json"];
|