@b3dotfun/sdk 0.0.88-alpha.7 → 0.0.88-alpha.9
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/constants/index.d.ts +2 -0
- package/dist/cjs/anyspend/constants/index.js +3 -1
- package/dist/cjs/anyspend/index.d.ts +2 -0
- package/dist/cjs/anyspend/index.js +3 -0
- package/dist/cjs/anyspend/react/components/AnySpend.js +4 -1
- package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.js +22 -18
- package/dist/cjs/anyspend/react/components/common/GasIndicator.d.ts +6 -0
- package/dist/cjs/anyspend/react/components/common/GasIndicator.js +34 -0
- package/dist/cjs/anyspend/react/hooks/index.d.ts +1 -0
- package/dist/cjs/anyspend/react/hooks/index.js +1 -0
- package/dist/cjs/anyspend/react/hooks/useGasPrice.d.ts +37 -0
- package/dist/cjs/anyspend/react/hooks/useGasPrice.js +43 -0
- package/dist/cjs/anyspend/services/gas.d.ts +21 -0
- package/dist/cjs/anyspend/services/gas.js +65 -0
- package/dist/cjs/anyspend/types/gas.d.ts +61 -0
- package/dist/cjs/anyspend/types/gas.js +2 -0
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +14 -2
- package/dist/cjs/global-account/react/hooks/useTokenBalancesByChain.js +4 -2
- package/dist/esm/anyspend/constants/index.d.ts +2 -0
- package/dist/esm/anyspend/constants/index.js +2 -0
- package/dist/esm/anyspend/index.d.ts +2 -0
- package/dist/esm/anyspend/index.js +3 -0
- package/dist/esm/anyspend/react/components/AnySpend.js +5 -2
- package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.js +5 -1
- package/dist/esm/anyspend/react/components/common/GasIndicator.d.ts +6 -0
- package/dist/esm/anyspend/react/components/common/GasIndicator.js +31 -0
- package/dist/esm/anyspend/react/hooks/index.d.ts +1 -0
- package/dist/esm/anyspend/react/hooks/index.js +1 -0
- package/dist/esm/anyspend/react/hooks/useGasPrice.d.ts +37 -0
- package/dist/esm/anyspend/react/hooks/useGasPrice.js +40 -0
- package/dist/esm/anyspend/services/gas.d.ts +21 -0
- package/dist/esm/anyspend/services/gas.js +59 -0
- package/dist/esm/anyspend/types/gas.d.ts +61 -0
- package/dist/esm/anyspend/types/gas.js +1 -0
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +14 -2
- package/dist/esm/global-account/react/hooks/useTokenBalancesByChain.js +4 -2
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/constants/index.d.ts +2 -0
- package/dist/types/anyspend/index.d.ts +2 -0
- package/dist/types/anyspend/react/components/common/GasIndicator.d.ts +6 -0
- package/dist/types/anyspend/react/hooks/index.d.ts +1 -0
- package/dist/types/anyspend/react/hooks/useGasPrice.d.ts +37 -0
- package/dist/types/anyspend/services/gas.d.ts +21 -0
- package/dist/types/anyspend/types/gas.d.ts +61 -0
- package/package.json +1 -1
- package/src/anyspend/constants/index.ts +3 -0
- package/src/anyspend/index.ts +4 -0
- package/src/anyspend/react/components/AnySpend.tsx +10 -0
- package/src/anyspend/react/components/AnySpendCustomExactIn.tsx +10 -0
- package/src/anyspend/react/components/common/GasIndicator.tsx +59 -0
- package/src/anyspend/react/hooks/index.ts +1 -0
- package/src/anyspend/react/hooks/useGasPrice.ts +70 -0
- package/src/anyspend/services/gas.test.ts +31 -0
- package/src/anyspend/services/gas.ts +73 -0
- package/src/anyspend/types/gas.ts +66 -0
- package/src/global-account/react/components/B3Provider/B3Provider.tsx +14 -2
- package/src/global-account/react/hooks/useTokenBalancesByChain.tsx +4 -2
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { components } from "../types/api";
|
|
2
2
|
export declare const ANYSPEND_MAINNET_BASE_URL: string;
|
|
3
3
|
export declare const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
4
|
+
export declare const GAS_ORACLE_BASE_URL: string;
|
|
5
|
+
export declare const RELAY_ETH_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
4
6
|
export declare const RELAY_SOL_ADDRESS = "11111111111111111111111111111111";
|
|
5
7
|
export declare const RELAY_SOLANA_MAINNET_CHAIN_ID = 792703809;
|
|
6
8
|
export declare const SOLANA_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.VENDOR_DISPLAY_NAMES = exports.PAYMENT_METHOD_ICONS = exports.STRIPE_CONFIG = exports.DEFAULT_NFT_CONTRACT = exports.NFT_CONTRACTS = exports.ETH_BASE = exports.USDC_BASE = exports.ANYSPEND_TOKEN = exports.B3_TOKEN = exports.SOLANA_TOKEN_2022_PROGRAM_ID = exports.SOLANA_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID = exports.RELAY_SOLANA_MAINNET_CHAIN_ID = exports.RELAY_SOL_ADDRESS = exports.ZERO_ADDRESS = exports.ANYSPEND_MAINNET_BASE_URL = void 0;
|
|
3
|
+
exports.VENDOR_DISPLAY_NAMES = exports.PAYMENT_METHOD_ICONS = exports.STRIPE_CONFIG = exports.DEFAULT_NFT_CONTRACT = exports.NFT_CONTRACTS = exports.ETH_BASE = exports.USDC_BASE = exports.ANYSPEND_TOKEN = exports.B3_TOKEN = exports.SOLANA_TOKEN_2022_PROGRAM_ID = exports.SOLANA_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID = exports.RELAY_SOLANA_MAINNET_CHAIN_ID = exports.RELAY_SOL_ADDRESS = exports.RELAY_ETH_ADDRESS = exports.GAS_ORACLE_BASE_URL = exports.ZERO_ADDRESS = exports.ANYSPEND_MAINNET_BASE_URL = void 0;
|
|
4
4
|
exports.getStripePublishableKey = getStripePublishableKey;
|
|
5
5
|
const chains_1 = require("viem/chains");
|
|
6
6
|
exports.ANYSPEND_MAINNET_BASE_URL = process.env.NEXT_PUBLIC_ANYSPEND_BASE_URL || "https://mainnet.anyspend.com";
|
|
7
7
|
exports.ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
8
|
+
exports.GAS_ORACLE_BASE_URL = process.env.NEXT_PUBLIC_GAS_ORACLE_URL || "https://gas-oracle.sean-430.workers.dev";
|
|
9
|
+
exports.RELAY_ETH_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
8
10
|
exports.RELAY_SOL_ADDRESS = "11111111111111111111111111111111";
|
|
9
11
|
exports.RELAY_SOLANA_MAINNET_CHAIN_ID = 792703809;
|
|
10
12
|
exports.SOLANA_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from "./types/api";
|
|
2
|
+
export * from "./types/gas";
|
|
2
3
|
export * from "./utils/address";
|
|
3
4
|
export * from "./utils/chain";
|
|
4
5
|
export * from "./utils/format";
|
|
@@ -8,5 +9,6 @@ export * from "./utils/string";
|
|
|
8
9
|
export * from "./utils/token";
|
|
9
10
|
export * from "./utils/validation";
|
|
10
11
|
export * from "./constants";
|
|
12
|
+
export * from "./services/gas";
|
|
11
13
|
export * from "./abis/abiUsdcBase";
|
|
12
14
|
export * from "./abis/erc20Staking";
|
|
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
// Types
|
|
18
18
|
__exportStar(require("./types/api"), exports);
|
|
19
|
+
__exportStar(require("./types/gas"), exports);
|
|
19
20
|
// Utils
|
|
20
21
|
__exportStar(require("./utils/address"), exports);
|
|
21
22
|
__exportStar(require("./utils/chain"), exports);
|
|
@@ -27,6 +28,8 @@ __exportStar(require("./utils/token"), exports);
|
|
|
27
28
|
__exportStar(require("./utils/validation"), exports);
|
|
28
29
|
// Constants
|
|
29
30
|
__exportStar(require("./constants"), exports);
|
|
31
|
+
// Services
|
|
32
|
+
__exportStar(require("./services/gas"), exports);
|
|
30
33
|
// Abis
|
|
31
34
|
__exportStar(require("./abis/abiUsdcBase"), exports);
|
|
32
35
|
__exportStar(require("./abis/erc20Staking"), exports);
|
|
@@ -31,6 +31,7 @@ const CryptoPaySection_1 = require("./common/CryptoPaySection");
|
|
|
31
31
|
const CryptoReceiveSection_1 = require("./common/CryptoReceiveSection");
|
|
32
32
|
const FeeDetailPanel_1 = require("./common/FeeDetailPanel");
|
|
33
33
|
const FiatPaymentMethod_1 = require("./common/FiatPaymentMethod");
|
|
34
|
+
const GasIndicator_1 = require("./common/GasIndicator");
|
|
34
35
|
const OrderDetails_1 = require("./common/OrderDetails");
|
|
35
36
|
const OrderHistory_1 = require("./common/OrderHistory");
|
|
36
37
|
const PanelOnramp_1 = require("./common/PanelOnramp");
|
|
@@ -372,6 +373,8 @@ function AnySpendInner({ sourceChainId, destinationTokenAddress, destinationToke
|
|
|
372
373
|
});
|
|
373
374
|
// Get geo-based onramp options for fiat payments
|
|
374
375
|
const { geoData, coinbaseAvailablePaymentMethods, stripeOnrampSupport, stripeWeb2Support } = (0, react_1.useGeoOnrampOptions)(srcAmountOnRamp);
|
|
376
|
+
// Get gas price for source chain (where the user pays from)
|
|
377
|
+
const { gasPrice: gasPriceData, isLoading: isLoadingGas } = (0, react_1.useGasPrice)(selectedSrcChainId);
|
|
375
378
|
// Helper function to map payment method to onramp vendor
|
|
376
379
|
const getOnrampVendor = (paymentMethod) => {
|
|
377
380
|
switch (paymentMethod) {
|
|
@@ -860,7 +863,7 @@ function AnySpendInner({ sourceChainId, destinationTokenAddress, destinationToke
|
|
|
860
863
|
}, children: (0, jsx_runtime_1.jsx)("div", { className: "relative flex items-center justify-center transition-opacity", children: (0, jsx_runtime_1.jsx)(lucide_react_1.ArrowDown, { className: "text-as-primary/50 h-5 w-5" }) }) }) })), activeTab === "crypto" && ((0, jsx_runtime_1.jsx)(CryptoReceiveSection_1.CryptoReceiveSection, { isDepositMode: false, isBuyMode: isBuyMode, effectiveRecipientAddress: effectiveRecipientAddress, recipientName: recipientName || undefined, customRecipientLabel: customRecipientLabel, onSelectRecipient: () => navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward"), dstAmount: dstAmount, dstToken: selectedDstToken, selectedDstChainId: selectedDstChainId, setSelectedDstChainId: setSelectedDstChainId, setSelectedDstToken: setSelectedDstToken, isSrcInputDirty: isSrcInputDirty, onChangeDstAmount: value => {
|
|
861
864
|
setIsSrcInputDirty(false);
|
|
862
865
|
setDstAmount(value);
|
|
863
|
-
}, anyspendQuote: anyspendQuote, onShowPointsDetail: () => navigateToPanel(PanelView.POINTS_DETAIL, "forward"), onShowFeeDetail: () => navigateToPanel(PanelView.FEE_DETAIL, "forward") }))] }), (0, jsx_runtime_1.jsxs)(react_3.motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0.2, ease: "easeInOut" }, className: (0, cn_1.cn)("mt-4 flex w-full max-w-[460px] flex-col gap-2"), children: [(0, jsx_runtime_1.jsx)(react_2.ShinyButton, { accentColor: "hsl(var(--as-brand))", disabled: btnInfo.disable, onClick: onMainButtonClick, className: (0, cn_1.cn)("as-main-button relative w-full", btnInfo.error ? "!bg-as-red" : btnInfo.disable ? "!bg-as-on-surface-2" : "!bg-as-brand"), textClassName: (0, cn_1.cn)(btnInfo.error ? "text-white" : btnInfo.disable ? "text-as-secondary" : "text-white"), children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-center gap-2", children: [btnInfo.loading && (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "h-4 w-4 animate-spin" }), btnInfo.text] }) }), !hideTransactionHistoryButton && (globalAddress || effectiveRecipientAddress) ? ((0, jsx_runtime_1.jsxs)(react_2.Button, { variant: "link", onClick: onClickHistory, className: "text-as-primary/50 hover:text-as-primary flex items-center gap-1 transition-colors", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.HistoryIcon, { className: "h-4 w-4" }), " ", (0, jsx_runtime_1.jsx)("span", { className: "pr-4", children: "Transaction History" })] })) : null] })] }), (0, jsx_runtime_1.jsx)("div", { className: "w-full", children: (0, jsx_runtime_1.jsx)(react_2.TabsPrimitive, { defaultValue: "swap", onValueChange: value => {
|
|
866
|
+
}, anyspendQuote: anyspendQuote, onShowPointsDetail: () => navigateToPanel(PanelView.POINTS_DETAIL, "forward"), onShowFeeDetail: () => navigateToPanel(PanelView.FEE_DETAIL, "forward") }))] }), gasPriceData && !isLoadingGas && activeTab === "crypto" && ((0, jsx_runtime_1.jsx)(GasIndicator_1.GasIndicator, { gasPrice: gasPriceData, className: "mt-2 w-full" })), (0, jsx_runtime_1.jsxs)(react_3.motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0.2, ease: "easeInOut" }, className: (0, cn_1.cn)("mt-4 flex w-full max-w-[460px] flex-col gap-2"), children: [(0, jsx_runtime_1.jsx)(react_2.ShinyButton, { accentColor: "hsl(var(--as-brand))", disabled: btnInfo.disable, onClick: onMainButtonClick, className: (0, cn_1.cn)("as-main-button relative w-full", btnInfo.error ? "!bg-as-red" : btnInfo.disable ? "!bg-as-on-surface-2" : "!bg-as-brand"), textClassName: (0, cn_1.cn)(btnInfo.error ? "text-white" : btnInfo.disable ? "text-as-secondary" : "text-white"), children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-center gap-2", children: [btnInfo.loading && (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "h-4 w-4 animate-spin" }), btnInfo.text] }) }), !hideTransactionHistoryButton && (globalAddress || effectiveRecipientAddress) ? ((0, jsx_runtime_1.jsxs)(react_2.Button, { variant: "link", onClick: onClickHistory, className: "text-as-primary/50 hover:text-as-primary flex items-center gap-1 transition-colors", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.HistoryIcon, { className: "h-4 w-4" }), " ", (0, jsx_runtime_1.jsx)("span", { className: "pr-4", children: "Transaction History" })] })) : null] })] }), (0, jsx_runtime_1.jsx)("div", { className: "w-full", children: (0, jsx_runtime_1.jsx)(react_2.TabsPrimitive, { defaultValue: "swap", onValueChange: value => {
|
|
864
867
|
if (value === "settings" || value === "home") {
|
|
865
868
|
setB3ModalContentType({
|
|
866
869
|
type: "manageAccount",
|
|
@@ -5,15 +5,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.AnySpendCustomExactIn = AnySpendCustomExactIn;
|
|
7
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = require("../../../anyspend/react");
|
|
8
9
|
const utils_1 = require("../../../anyspend/utils");
|
|
9
|
-
const
|
|
10
|
+
const react_2 = require("../../../global-account/react");
|
|
10
11
|
const cn_1 = require("../../../shared/utils/cn");
|
|
11
12
|
const number_1 = require("../../../shared/utils/number");
|
|
12
13
|
const invariant_1 = __importDefault(require("invariant"));
|
|
13
14
|
const lucide_react_1 = require("lucide-react");
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
15
|
+
const react_3 = require("motion/react");
|
|
16
|
+
const react_4 = require("react");
|
|
17
|
+
const react_5 = require("thirdweb/react");
|
|
17
18
|
const constants_1 = require("../../constants");
|
|
18
19
|
const useAnyspendFlow_1 = require("../hooks/useAnyspendFlow");
|
|
19
20
|
const AnySpendFingerprintWrapper_1 = require("./AnySpendFingerprintWrapper");
|
|
@@ -22,6 +23,7 @@ const CryptoPaymentMethod_1 = require("./common/CryptoPaymentMethod");
|
|
|
22
23
|
const CryptoReceiveSection_1 = require("./common/CryptoReceiveSection");
|
|
23
24
|
const FeeDetailPanel_1 = require("./common/FeeDetailPanel");
|
|
24
25
|
const FiatPaymentMethod_1 = require("./common/FiatPaymentMethod");
|
|
26
|
+
const GasIndicator_1 = require("./common/GasIndicator");
|
|
25
27
|
const OrderDetails_1 = require("./common/OrderDetails");
|
|
26
28
|
const PanelOnramp_1 = require("./common/PanelOnramp");
|
|
27
29
|
const PointsDetailPanel_1 = require("./common/PointsDetailPanel");
|
|
@@ -50,10 +52,12 @@ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddres
|
|
|
50
52
|
disableUrlParamManagement: true,
|
|
51
53
|
orderType,
|
|
52
54
|
});
|
|
53
|
-
const { connectedEOAWallet } = (0,
|
|
54
|
-
const setActiveWallet = (0,
|
|
55
|
-
|
|
56
|
-
(0,
|
|
55
|
+
const { connectedEOAWallet } = (0, react_2.useAccountWallet)();
|
|
56
|
+
const setActiveWallet = (0, react_5.useSetActiveWallet)();
|
|
57
|
+
// Get gas price for source chain (where the user pays from)
|
|
58
|
+
const { gasPrice: gasPriceData, isLoading: isLoadingGas } = (0, react_1.useGasPrice)(selectedSrcChainId);
|
|
59
|
+
const appliedPreferEoa = (0, react_4.useRef)(false);
|
|
60
|
+
(0, react_4.useEffect)(() => {
|
|
57
61
|
if (preferEoa && !appliedPreferEoa.current) {
|
|
58
62
|
if (connectedEOAWallet) {
|
|
59
63
|
appliedPreferEoa.current = true;
|
|
@@ -84,7 +88,7 @@ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddres
|
|
|
84
88
|
action: customExactInConfig.action,
|
|
85
89
|
};
|
|
86
90
|
};
|
|
87
|
-
const btnInfo = (0,
|
|
91
|
+
const btnInfo = (0, react_4.useMemo)(() => {
|
|
88
92
|
if (activeInputAmountInWei === "0")
|
|
89
93
|
return { text: "Enter an amount", disable: true, error: false, loading: false };
|
|
90
94
|
if (orderType === "hype_duel" && selectedSrcToken?.address?.toLowerCase() === constants_1.B3_TOKEN.address.toLowerCase()) {
|
|
@@ -181,10 +185,10 @@ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddres
|
|
|
181
185
|
}
|
|
182
186
|
};
|
|
183
187
|
const headerContent = header ? (header({ anyspendPrice: anyspendQuote, isLoadingAnyspendPrice: isLoadingAnyspendQuote })) : ((0, jsx_runtime_1.jsx)("div", { className: "mb-4 flex flex-col items-center gap-3 text-center", children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-as-primary text-xl font-bold", children: actionLabel }), (0, jsx_runtime_1.jsx)("p", { className: "text-as-secondary text-sm", children: "Pay from any token to execute a custom exact-in transaction." })] }) }));
|
|
184
|
-
const mainView = ((0, jsx_runtime_1.jsxs)("div", { className: "anyspend-custom-exact-in-container mx-auto flex w-[460px] max-w-full flex-col items-center gap-2", children: [headerContent, (0, jsx_runtime_1.jsx)("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: (0, jsx_runtime_1.jsxs)("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: [paymentType === "crypto" ? ((0, jsx_runtime_1.jsx)(CryptoPaySection_1.CryptoPaySection, { selectedSrcChainId: selectedSrcChainId, setSelectedSrcChainId: setSelectedSrcChainId, selectedSrcToken: selectedSrcToken, setSelectedSrcToken: setSelectedSrcToken, srcAmount: srcAmount, setSrcAmount: setSrcAmount, isSrcInputDirty: isSrcInputDirty, setIsSrcInputDirty: setIsSrcInputDirty, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod, onSelectCryptoPaymentMethod: () => setActivePanel(useAnyspendFlow_1.PanelView.CRYPTO_PAYMENT_METHOD), anyspendQuote: anyspendQuote, onTokenSelect: onTokenSelect })) : ((0, jsx_runtime_1.jsx)(
|
|
188
|
+
const mainView = ((0, jsx_runtime_1.jsxs)("div", { className: "anyspend-custom-exact-in-container mx-auto flex w-[460px] max-w-full flex-col items-center gap-2", children: [headerContent, (0, jsx_runtime_1.jsx)("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: (0, jsx_runtime_1.jsxs)("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: [paymentType === "crypto" ? ((0, jsx_runtime_1.jsx)(CryptoPaySection_1.CryptoPaySection, { selectedSrcChainId: selectedSrcChainId, setSelectedSrcChainId: setSelectedSrcChainId, selectedSrcToken: selectedSrcToken, setSelectedSrcToken: setSelectedSrcToken, srcAmount: srcAmount, setSrcAmount: setSrcAmount, isSrcInputDirty: isSrcInputDirty, setIsSrcInputDirty: setIsSrcInputDirty, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod, onSelectCryptoPaymentMethod: () => setActivePanel(useAnyspendFlow_1.PanelView.CRYPTO_PAYMENT_METHOD), anyspendQuote: anyspendQuote, onTokenSelect: onTokenSelect })) : ((0, jsx_runtime_1.jsx)(react_3.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: (0, jsx_runtime_1.jsx)(PanelOnramp_1.PanelOnramp, { srcAmountOnRamp: srcAmount, setSrcAmountOnRamp: setSrcAmount, selectedPaymentMethod: selectedFiatPaymentMethod, setActivePanel: setActivePanel, _recipientAddress: selectedRecipientOrDefault, destinationToken: selectedDstToken, destinationChainId: selectedDstChainId, dstTokenSymbol: DESTINATION_TOKEN_DETAILS.SYMBOL, hideDstToken: true, destinationAmount: dstAmount, onDestinationTokenChange: () => { }, onDestinationChainChange: () => { }, fiatPaymentMethodIndex: useAnyspendFlow_1.PanelView.FIAT_PAYMENT_METHOD, recipientSelectionPanelIndex: useAnyspendFlow_1.PanelView.RECIPIENT_SELECTION, anyspendQuote: anyspendQuote, onShowPointsDetail: () => setActivePanel(useAnyspendFlow_1.PanelView.POINTS_DETAIL), onShowFeeDetail: () => setActivePanel(useAnyspendFlow_1.PanelView.FEE_DETAIL), customUsdInputValues: customUsdInputValues, customRecipientLabel: customRecipientLabel }) })), (0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("relative -my-1 flex h-0 items-center justify-center", paymentType === "fiat" && "hidden"), children: (0, jsx_runtime_1.jsx)(react_2.Button, { variant: "ghost", className: (0, cn_1.cn)("swap-direction-button border-as-stroke bg-as-surface-primary z-10 h-10 w-10 cursor-default rounded-xl border-2 sm:h-8 sm:w-8 sm:rounded-xl"), children: (0, jsx_runtime_1.jsx)("div", { className: "relative flex items-center justify-center transition-opacity", children: (0, jsx_runtime_1.jsx)(lucide_react_1.ArrowDown, { className: "text-as-primary/50 h-5 w-5" }) }) }) }), paymentType === "crypto" && ((0, jsx_runtime_1.jsx)(CryptoReceiveSection_1.CryptoReceiveSection, { isDepositMode: false, isBuyMode: true, effectiveRecipientAddress: selectedRecipientOrDefault, recipientName: recipientName || undefined, customRecipientLabel: customRecipientLabel, onSelectRecipient: () => setActivePanel(useAnyspendFlow_1.PanelView.RECIPIENT_SELECTION), dstAmount: dstAmount, dstToken: selectedDstToken, dstTokenSymbol: DESTINATION_TOKEN_DETAILS.SYMBOL, dstTokenLogoURI: DESTINATION_TOKEN_DETAILS.LOGO_URI, selectedDstChainId: selectedDstChainId, setSelectedDstChainId: () => { }, setSelectedDstToken: () => { }, isSrcInputDirty: isSrcInputDirty, onChangeDstAmount: value => {
|
|
185
189
|
setIsSrcInputDirty(false);
|
|
186
190
|
setSrcAmount(value);
|
|
187
|
-
}, anyspendQuote: anyspendQuote, onShowPointsDetail: () => setActivePanel(useAnyspendFlow_1.PanelView.POINTS_DETAIL), onShowFeeDetail: () => setActivePanel(useAnyspendFlow_1.PanelView.FEE_DETAIL) }))] }) }), (0, jsx_runtime_1.jsx)(
|
|
191
|
+
}, anyspendQuote: anyspendQuote, onShowPointsDetail: () => setActivePanel(useAnyspendFlow_1.PanelView.POINTS_DETAIL), onShowFeeDetail: () => setActivePanel(useAnyspendFlow_1.PanelView.FEE_DETAIL) }))] }) }), (0, jsx_runtime_1.jsx)(react_3.motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0.2, ease: "easeInOut" }, className: (0, cn_1.cn)("mt-4 flex w-full max-w-[460px] flex-col gap-2"), children: (0, jsx_runtime_1.jsx)(react_2.ShinyButton, { accentColor: "hsl(var(--as-brand))", disabled: btnInfo.disable, onClick: onMainButtonClick, className: (0, cn_1.cn)("as-main-button relative w-full", btnInfo.error ? "!bg-as-red" : btnInfo.disable ? "!bg-as-on-surface-2" : "!bg-as-brand"), textClassName: (0, cn_1.cn)(btnInfo.error ? "text-white" : btnInfo.disable ? "text-as-secondary" : "text-white"), children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-center gap-2", children: [btnInfo.loading && (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "h-4 w-4 animate-spin" }), btnInfo.text] }) }) }), gasPriceData && !isLoadingGas && paymentType === "crypto" && ((0, jsx_runtime_1.jsx)(GasIndicator_1.GasIndicator, { gasPrice: gasPriceData, className: "mt-2 w-full" })), mainFooter ? mainFooter : null] }));
|
|
188
192
|
const handleCryptoOrder = async () => {
|
|
189
193
|
try {
|
|
190
194
|
(0, invariant_1.default)(anyspendQuote, "Relay price is not found");
|
|
@@ -206,7 +210,7 @@ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddres
|
|
|
206
210
|
}
|
|
207
211
|
catch (err) {
|
|
208
212
|
console.error(err);
|
|
209
|
-
|
|
213
|
+
react_2.toast.error("Failed to create order: " + err.message);
|
|
210
214
|
}
|
|
211
215
|
};
|
|
212
216
|
const handleFiatOrder = async () => {
|
|
@@ -214,14 +218,14 @@ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddres
|
|
|
214
218
|
(0, invariant_1.default)(anyspendQuote, "Relay price is not found");
|
|
215
219
|
(0, invariant_1.default)(selectedRecipientOrDefault, "Recipient address is not found");
|
|
216
220
|
if (!srcAmount || parseFloat(srcAmount) <= 0) {
|
|
217
|
-
|
|
221
|
+
react_2.toast.error("Please enter a valid amount");
|
|
218
222
|
return;
|
|
219
223
|
}
|
|
220
224
|
let vendor;
|
|
221
225
|
let paymentMethodString = "";
|
|
222
226
|
if (selectedFiatPaymentMethod === FiatPaymentMethod_1.FiatPaymentMethod.COINBASE_PAY) {
|
|
223
227
|
if (coinbaseAvailablePaymentMethods.length === 0) {
|
|
224
|
-
|
|
228
|
+
react_2.toast.error("Coinbase Pay not available");
|
|
225
229
|
return;
|
|
226
230
|
}
|
|
227
231
|
vendor = "coinbase";
|
|
@@ -229,13 +233,13 @@ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddres
|
|
|
229
233
|
}
|
|
230
234
|
else if (selectedFiatPaymentMethod === FiatPaymentMethod_1.FiatPaymentMethod.STRIPE) {
|
|
231
235
|
if (!stripeWeb2Support || !stripeWeb2Support.isSupport) {
|
|
232
|
-
|
|
236
|
+
react_2.toast.error("Stripe not available");
|
|
233
237
|
return;
|
|
234
238
|
}
|
|
235
239
|
vendor = "stripe-web2";
|
|
236
240
|
}
|
|
237
241
|
else {
|
|
238
|
-
|
|
242
|
+
react_2.toast.error("Please select a payment method");
|
|
239
243
|
return;
|
|
240
244
|
}
|
|
241
245
|
const payload = buildCustomPayload(selectedRecipientOrDefault);
|
|
@@ -258,7 +262,7 @@ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddres
|
|
|
258
262
|
}
|
|
259
263
|
catch (err) {
|
|
260
264
|
console.error(err);
|
|
261
|
-
|
|
265
|
+
react_2.toast.error("Failed to create order: " + err.message);
|
|
262
266
|
}
|
|
263
267
|
};
|
|
264
268
|
const orderDetailsView = ((0, jsx_runtime_1.jsx)("div", { className: "mx-auto w-[460px] max-w-full", children: (0, jsx_runtime_1.jsx)("div", { className: "relative flex flex-col gap-4", children: oat && ((0, jsx_runtime_1.jsx)(OrderDetails_1.OrderDetails, { mode: mode, order: oat.data.order, depositTxs: oat.data.depositTxs, relayTxs: oat.data.relayTxs, executeTx: oat.data.executeTx, refundTxs: oat.data.refundTxs, cryptoPaymentMethod: paymentType === "fiat" ? CryptoPaymentMethod_1.CryptoPaymentMethodType.NONE : effectiveCryptoPaymentMethod, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod, onPaymentMethodChange: setSelectedCryptoPaymentMethod, onBack: () => {
|
|
@@ -284,7 +288,7 @@ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddres
|
|
|
284
288
|
: anyspendQuote.data.currencyIn?.amountUsd
|
|
285
289
|
? Number(anyspendQuote.data.currencyIn.amountUsd)
|
|
286
290
|
: undefined, onBack: () => setActivePanel(useAnyspendFlow_1.PanelView.MAIN) })) : null;
|
|
287
|
-
return ((0, jsx_runtime_1.jsx)(
|
|
291
|
+
return ((0, jsx_runtime_1.jsx)(react_2.StyleRoot, { children: (0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("anyspend-container font-inter bg-as-surface-primary mx-auto w-full max-w-[460px] p-6", mode === "page" && "border-as-border-secondary overflow-hidden rounded-2xl border shadow-xl"), children: (0, jsx_runtime_1.jsx)(react_2.TransitionPanel, { activeIndex: orderId
|
|
288
292
|
? oat
|
|
289
293
|
? useAnyspendFlow_1.PanelView.ORDER_DETAILS
|
|
290
294
|
: useAnyspendFlow_1.PanelView.LOADING
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { GasPriceData } from "../../../types/gas";
|
|
2
|
+
export interface GasIndicatorProps {
|
|
3
|
+
gasPrice: GasPriceData;
|
|
4
|
+
className?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function GasIndicator({ gasPrice, className }: GasIndicatorProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.GasIndicator = GasIndicator;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const cn_1 = require("../../../../shared/utils/cn");
|
|
7
|
+
const react_1 = require("motion/react");
|
|
8
|
+
const LEVEL_LABELS = {
|
|
9
|
+
low: "Low",
|
|
10
|
+
normal: "Normal",
|
|
11
|
+
elevated: "Elevated",
|
|
12
|
+
high: "High",
|
|
13
|
+
spike: "Spike",
|
|
14
|
+
};
|
|
15
|
+
const LEVEL_STYLES = {
|
|
16
|
+
low: "bg-green-500/20 text-green-500",
|
|
17
|
+
normal: "bg-as-surface-tertiary text-as-secondary",
|
|
18
|
+
elevated: "bg-yellow-500/20 text-yellow-600",
|
|
19
|
+
high: "bg-orange-500/20 text-orange-500",
|
|
20
|
+
spike: "bg-red-500/20 text-red-500",
|
|
21
|
+
};
|
|
22
|
+
function formatGasPrice(gweiString) {
|
|
23
|
+
const gwei = parseFloat(gweiString);
|
|
24
|
+
if (gwei < 0.001)
|
|
25
|
+
return "<0.001";
|
|
26
|
+
if (gwei < 1)
|
|
27
|
+
return gwei.toFixed(3);
|
|
28
|
+
if (gwei < 10)
|
|
29
|
+
return gwei.toFixed(2);
|
|
30
|
+
return gwei.toFixed(1);
|
|
31
|
+
}
|
|
32
|
+
function GasIndicator({ gasPrice, className }) {
|
|
33
|
+
return ((0, jsx_runtime_1.jsxs)(react_1.motion.div, { initial: { opacity: 0, y: 10 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.2 }, className: (0, cn_1.cn)("flex items-center justify-between rounded-lg px-3 py-2", gasPrice.isSpike ? "bg-yellow-500/10" : "bg-as-surface-secondary", className), children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-2", children: (0, jsx_runtime_1.jsxs)("span", { className: "text-as-secondary text-xs", children: ["Gas on ", gasPrice.chainName] }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("span", { className: (0, cn_1.cn)("rounded px-1.5 py-0.5 text-xs font-medium", LEVEL_STYLES[gasPrice.level]), children: LEVEL_LABELS[gasPrice.level] }), (0, jsx_runtime_1.jsxs)("span", { className: "text-as-primary text-xs font-medium", children: [formatGasPrice(gasPrice.gasPriceGwei), " Gwei"] })] })] }));
|
|
34
|
+
}
|
|
@@ -7,6 +7,7 @@ export * from "./useAnyspendQuote";
|
|
|
7
7
|
export * from "./useAnyspendTokens";
|
|
8
8
|
export * from "./useCoinbaseOnrampOptions";
|
|
9
9
|
export * from "./useConnectedUserProfile";
|
|
10
|
+
export * from "./useGasPrice";
|
|
10
11
|
export * from "./useGeoOnrampOptions";
|
|
11
12
|
export * from "./useGetGeo";
|
|
12
13
|
export * from "./useHyperliquidTransfer";
|
|
@@ -23,6 +23,7 @@ __exportStar(require("./useAnyspendQuote"), exports);
|
|
|
23
23
|
__exportStar(require("./useAnyspendTokens"), exports);
|
|
24
24
|
__exportStar(require("./useCoinbaseOnrampOptions"), exports);
|
|
25
25
|
__exportStar(require("./useConnectedUserProfile"), exports);
|
|
26
|
+
__exportStar(require("./useGasPrice"), exports);
|
|
26
27
|
__exportStar(require("./useGeoOnrampOptions"), exports);
|
|
27
28
|
__exportStar(require("./useGetGeo"), exports);
|
|
28
29
|
__exportStar(require("./useHyperliquidTransfer"), exports);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { GasPriceData } from "../../types/gas";
|
|
2
|
+
export interface UseGasPriceOptions {
|
|
3
|
+
/** Refetch interval in ms (default: 10000 = 10s) */
|
|
4
|
+
refetchInterval?: number;
|
|
5
|
+
/** Whether to enable the query (default: true if chainId is supported) */
|
|
6
|
+
enabled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface UseGasPriceResult {
|
|
9
|
+
/** Gas price data */
|
|
10
|
+
gasPrice: GasPriceData | undefined;
|
|
11
|
+
/** Whether the query is loading */
|
|
12
|
+
isLoading: boolean;
|
|
13
|
+
/** Whether there's an error */
|
|
14
|
+
isError: boolean;
|
|
15
|
+
/** Error object if any */
|
|
16
|
+
error: Error | null;
|
|
17
|
+
/** Whether gas is currently spiking */
|
|
18
|
+
isSpike: boolean;
|
|
19
|
+
/** Refetch function */
|
|
20
|
+
refetch: () => void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* React hook to fetch current gas price for a chain.
|
|
24
|
+
*
|
|
25
|
+
* @param chainId - The chain ID to fetch gas price for
|
|
26
|
+
* @param options - Optional configuration
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* const { gasPrice, isSpike, isLoading } = useGasPrice(8453); // Base
|
|
31
|
+
*
|
|
32
|
+
* if (isSpike) {
|
|
33
|
+
* return <Warning>Gas prices are high: {gasPrice?.recommendation}</Warning>;
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function useGasPrice(chainId: number | undefined, options?: UseGasPriceOptions): UseGasPriceResult;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useGasPrice = useGasPrice;
|
|
4
|
+
const react_query_1 = require("@tanstack/react-query");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const gas_1 = require("../../services/gas");
|
|
7
|
+
/**
|
|
8
|
+
* React hook to fetch current gas price for a chain.
|
|
9
|
+
*
|
|
10
|
+
* @param chainId - The chain ID to fetch gas price for
|
|
11
|
+
* @param options - Optional configuration
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* const { gasPrice, isSpike, isLoading } = useGasPrice(8453); // Base
|
|
16
|
+
*
|
|
17
|
+
* if (isSpike) {
|
|
18
|
+
* return <Warning>Gas prices are high: {gasPrice?.recommendation}</Warning>;
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
function useGasPrice(chainId, options = {}) {
|
|
23
|
+
const { refetchInterval = 10000, enabled } = options;
|
|
24
|
+
const isSupported = chainId !== undefined && (0, gas_1.isGasOracleSupported)(chainId);
|
|
25
|
+
const queryEnabled = enabled ?? isSupported;
|
|
26
|
+
const { data, isLoading, isError, error, refetch } = (0, react_query_1.useQuery)({
|
|
27
|
+
queryKey: ["gasPrice", chainId],
|
|
28
|
+
queryFn: () => gas_1.gasService.fetch(chainId),
|
|
29
|
+
enabled: queryEnabled && chainId !== undefined,
|
|
30
|
+
refetchInterval,
|
|
31
|
+
staleTime: 5000, // Consider data fresh for 5s
|
|
32
|
+
retry: 2,
|
|
33
|
+
refetchOnWindowFocus: true,
|
|
34
|
+
});
|
|
35
|
+
return (0, react_1.useMemo)(() => ({
|
|
36
|
+
gasPrice: data,
|
|
37
|
+
isLoading,
|
|
38
|
+
isError,
|
|
39
|
+
error: error,
|
|
40
|
+
isSpike: data?.isSpike ?? false,
|
|
41
|
+
refetch,
|
|
42
|
+
}), [data, isLoading, isError, error, refetch]);
|
|
43
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { GasOracleResponse, GasPriceData } from "../types/gas";
|
|
2
|
+
/** Supported chain IDs for gas oracle */
|
|
3
|
+
export declare const GAS_ORACLE_SUPPORTED_CHAINS: readonly [1, 137, 42161, 8453, 56, 10, 43114, 8333, 2741, 4689, 3338, 1329];
|
|
4
|
+
export type GasOracleSupportedChainId = (typeof GAS_ORACLE_SUPPORTED_CHAINS)[number];
|
|
5
|
+
/** Check if a chain is supported by the gas oracle */
|
|
6
|
+
export declare function isGasOracleSupported(chainId: number): chainId is GasOracleSupportedChainId;
|
|
7
|
+
/** Fetch gas price data from the gas oracle */
|
|
8
|
+
export declare function fetchGasPrice(chainId: number): Promise<GasOracleResponse>;
|
|
9
|
+
/** Transform raw oracle response to simplified UI data */
|
|
10
|
+
export declare function toGasPriceData(response: GasOracleResponse): GasPriceData;
|
|
11
|
+
/** Gas service for fetching and transforming gas data */
|
|
12
|
+
export declare const gasService: {
|
|
13
|
+
/** Fetch raw gas oracle response */
|
|
14
|
+
fetchRaw: typeof fetchGasPrice;
|
|
15
|
+
/** Fetch and transform to UI-friendly format */
|
|
16
|
+
fetch: (chainId: number) => Promise<GasPriceData>;
|
|
17
|
+
/** Check if chain is supported */
|
|
18
|
+
isSupported: typeof isGasOracleSupported;
|
|
19
|
+
/** List of supported chain IDs */
|
|
20
|
+
supportedChains: readonly [1, 137, 42161, 8453, 56, 10, 43114, 8333, 2741, 4689, 3338, 1329];
|
|
21
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.gasService = exports.GAS_ORACLE_SUPPORTED_CHAINS = void 0;
|
|
4
|
+
exports.isGasOracleSupported = isGasOracleSupported;
|
|
5
|
+
exports.fetchGasPrice = fetchGasPrice;
|
|
6
|
+
exports.toGasPriceData = toGasPriceData;
|
|
7
|
+
const constants_1 = require("../constants");
|
|
8
|
+
/** Supported chain IDs for gas oracle */
|
|
9
|
+
exports.GAS_ORACLE_SUPPORTED_CHAINS = [
|
|
10
|
+
1, // Ethereum
|
|
11
|
+
137, // Polygon
|
|
12
|
+
42161, // Arbitrum
|
|
13
|
+
8453, // Base
|
|
14
|
+
56, // BSC
|
|
15
|
+
10, // Optimism
|
|
16
|
+
43114, // Avalanche
|
|
17
|
+
8333, // B3
|
|
18
|
+
2741, // Abstract
|
|
19
|
+
4689, // IoTeX
|
|
20
|
+
3338, // Peaq
|
|
21
|
+
1329, // Sei
|
|
22
|
+
];
|
|
23
|
+
/** Check if a chain is supported by the gas oracle */
|
|
24
|
+
function isGasOracleSupported(chainId) {
|
|
25
|
+
return exports.GAS_ORACLE_SUPPORTED_CHAINS.includes(chainId);
|
|
26
|
+
}
|
|
27
|
+
/** Fetch gas price data from the gas oracle */
|
|
28
|
+
async function fetchGasPrice(chainId) {
|
|
29
|
+
const response = await fetch(`${constants_1.GAS_ORACLE_BASE_URL}/gas/${chainId}`);
|
|
30
|
+
if (!response.ok) {
|
|
31
|
+
throw new Error(`Failed to fetch gas price for chain ${chainId}: ${response.status}`);
|
|
32
|
+
}
|
|
33
|
+
return response.json();
|
|
34
|
+
}
|
|
35
|
+
/** Transform raw oracle response to simplified UI data */
|
|
36
|
+
function toGasPriceData(response) {
|
|
37
|
+
const { analysis } = response;
|
|
38
|
+
const isSpike = analysis.level === "elevated" || analysis.level === "high" || analysis.level === "spike";
|
|
39
|
+
return {
|
|
40
|
+
chainId: response.chainId,
|
|
41
|
+
chainName: response.chainName,
|
|
42
|
+
gasPriceGwei: response.gasPrice.standard,
|
|
43
|
+
baseFeeGwei: response.eip1559?.baseFee,
|
|
44
|
+
level: analysis.level,
|
|
45
|
+
isSpike,
|
|
46
|
+
recommendation: analysis.recommendation,
|
|
47
|
+
vsMedian: analysis.vs1h, // Use 1h as primary comparison
|
|
48
|
+
source: response.source,
|
|
49
|
+
timestamp: response.timestamp,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** Gas service for fetching and transforming gas data */
|
|
53
|
+
exports.gasService = {
|
|
54
|
+
/** Fetch raw gas oracle response */
|
|
55
|
+
fetchRaw: fetchGasPrice,
|
|
56
|
+
/** Fetch and transform to UI-friendly format */
|
|
57
|
+
fetch: async (chainId) => {
|
|
58
|
+
const response = await fetchGasPrice(chainId);
|
|
59
|
+
return toGasPriceData(response);
|
|
60
|
+
},
|
|
61
|
+
/** Check if chain is supported */
|
|
62
|
+
isSupported: isGasOracleSupported,
|
|
63
|
+
/** List of supported chain IDs */
|
|
64
|
+
supportedChains: exports.GAS_ORACLE_SUPPORTED_CHAINS,
|
|
65
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/** Gas level classification based on historical percentiles */
|
|
2
|
+
export type GasLevel = "low" | "normal" | "elevated" | "high" | "spike";
|
|
3
|
+
/** Gas prices in Gwei for different speed tiers */
|
|
4
|
+
export interface GasPrices {
|
|
5
|
+
low: string;
|
|
6
|
+
standard: string;
|
|
7
|
+
fast: string;
|
|
8
|
+
instant?: string;
|
|
9
|
+
}
|
|
10
|
+
/** EIP-1559 specific gas data */
|
|
11
|
+
export interface Eip1559Data {
|
|
12
|
+
baseFee: string;
|
|
13
|
+
maxPriorityFee: GasPrices;
|
|
14
|
+
maxFee: GasPrices;
|
|
15
|
+
}
|
|
16
|
+
/** Spike analysis comparing current gas to historical data */
|
|
17
|
+
export interface GasSpikeAnalysis {
|
|
18
|
+
level: GasLevel;
|
|
19
|
+
percentile: number;
|
|
20
|
+
/** Ratio to 1h median (primary spike detection) */
|
|
21
|
+
vs1h: number;
|
|
22
|
+
/** Ratio to 4h median (short-term context) */
|
|
23
|
+
vs4h: number;
|
|
24
|
+
/** Ratio to 24h median (daily context) */
|
|
25
|
+
vs24h: number;
|
|
26
|
+
recommendation: string;
|
|
27
|
+
}
|
|
28
|
+
/** Full gas response from the gas oracle */
|
|
29
|
+
export interface GasOracleResponse {
|
|
30
|
+
chainId: number;
|
|
31
|
+
chainName: string;
|
|
32
|
+
timestamp: string;
|
|
33
|
+
blockNumber?: number;
|
|
34
|
+
source: "blocknative" | "rpc";
|
|
35
|
+
gasPrice: GasPrices;
|
|
36
|
+
eip1559?: Eip1559Data;
|
|
37
|
+
analysis: GasSpikeAnalysis;
|
|
38
|
+
cached: boolean;
|
|
39
|
+
cacheAge?: number;
|
|
40
|
+
}
|
|
41
|
+
/** Simplified gas data for UI display */
|
|
42
|
+
export interface GasPriceData {
|
|
43
|
+
chainId: number;
|
|
44
|
+
chainName: string;
|
|
45
|
+
/** Standard gas price in Gwei */
|
|
46
|
+
gasPriceGwei: string;
|
|
47
|
+
/** Base fee in Gwei (EIP-1559 chains) */
|
|
48
|
+
baseFeeGwei?: string;
|
|
49
|
+
/** Gas level classification */
|
|
50
|
+
level: GasLevel;
|
|
51
|
+
/** Whether gas is currently spiking (elevated, high, or spike) */
|
|
52
|
+
isSpike: boolean;
|
|
53
|
+
/** Human-readable recommendation */
|
|
54
|
+
recommendation: string;
|
|
55
|
+
/** Ratio to recent median (1 = normal, >1.5 = elevated) */
|
|
56
|
+
vsMedian: number;
|
|
57
|
+
/** Data source */
|
|
58
|
+
source: "blocknative" | "rpc";
|
|
59
|
+
/** Timestamp of the data */
|
|
60
|
+
timestamp: string;
|
|
61
|
+
}
|
|
@@ -28,7 +28,7 @@ function B3Provider({ theme = "light", children, accountOverride, environment, a
|
|
|
28
28
|
// deprecated since v0.0.87
|
|
29
29
|
toaster: _toaster, clientType = "rest", rpcUrls, partnerId, stripePublishableKey, onConnect, connectors, overrideDefaultConnectors = false, createClientReferenceId, enableTurnkey = false, defaultPermissions, }) {
|
|
30
30
|
const setConfig = (0, configStore_1.useB3ConfigStore)(state => state.setConfig);
|
|
31
|
-
// Initialize config store on mount
|
|
31
|
+
// Initialize config store on mount
|
|
32
32
|
(0, react_2.useEffect)(() => {
|
|
33
33
|
setConfig({
|
|
34
34
|
accountOverride,
|
|
@@ -42,7 +42,19 @@ toaster: _toaster, clientType = "rest", rpcUrls, partnerId, stripePublishableKey
|
|
|
42
42
|
enableTurnkey,
|
|
43
43
|
defaultPermissions,
|
|
44
44
|
});
|
|
45
|
-
}, [
|
|
45
|
+
}, [
|
|
46
|
+
accountOverride,
|
|
47
|
+
environment,
|
|
48
|
+
automaticallySetFirstEoa,
|
|
49
|
+
theme,
|
|
50
|
+
clientType,
|
|
51
|
+
partnerId,
|
|
52
|
+
stripePublishableKey,
|
|
53
|
+
createClientReferenceId,
|
|
54
|
+
enableTurnkey,
|
|
55
|
+
defaultPermissions,
|
|
56
|
+
setConfig,
|
|
57
|
+
]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
46
58
|
// Initialize Google Analytics on mount
|
|
47
59
|
(0, react_2.useEffect)(() => {
|
|
48
60
|
(0, analytics_1.loadGA4Script)();
|
|
@@ -10,8 +10,8 @@ const react_query_1 = require("@tanstack/react-query");
|
|
|
10
10
|
const b3Chain_1 = require("../../../shared/constants/chains/b3Chain");
|
|
11
11
|
const chains_1 = require("../../../shared/utils/chains");
|
|
12
12
|
const thirdweb_1 = require("../../../shared/utils/thirdweb");
|
|
13
|
-
const wallets_1 = require("thirdweb/wallets");
|
|
14
13
|
const invariant_1 = __importDefault(require("invariant"));
|
|
14
|
+
const wallets_1 = require("thirdweb/wallets");
|
|
15
15
|
function useTokenBalancesByChain({ address, chainsIds, enabled = true, }) {
|
|
16
16
|
// Normalize chains to array
|
|
17
17
|
const chainIds = Array.isArray(chainsIds) ? chainsIds : [chainsIds];
|
|
@@ -52,7 +52,9 @@ function useTokenBalancesByChain({ address, chainsIds, enabled = true, }) {
|
|
|
52
52
|
staleTime: 30000, // Consider data fresh for 30 seconds
|
|
53
53
|
gcTime: 5 * 60 * 1000, // Keep in cache for 5 minutes
|
|
54
54
|
retry: 2, // Limit retries on failure
|
|
55
|
-
|
|
55
|
+
// Enable structural sharing to prevent infinite loops
|
|
56
|
+
// This ensures we only get new references when data actually changes
|
|
57
|
+
structuralSharing: true,
|
|
56
58
|
});
|
|
57
59
|
return {
|
|
58
60
|
nativeTokens: combinedData?.nativeTokens ?? [],
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { components } from "../types/api";
|
|
2
2
|
export declare const ANYSPEND_MAINNET_BASE_URL: string;
|
|
3
3
|
export declare const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
4
|
+
export declare const GAS_ORACLE_BASE_URL: string;
|
|
5
|
+
export declare const RELAY_ETH_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
4
6
|
export declare const RELAY_SOL_ADDRESS = "11111111111111111111111111111111";
|
|
5
7
|
export declare const RELAY_SOLANA_MAINNET_CHAIN_ID = 792703809;
|
|
6
8
|
export declare const SOLANA_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { base } from "viem/chains";
|
|
2
2
|
export const ANYSPEND_MAINNET_BASE_URL = process.env.NEXT_PUBLIC_ANYSPEND_BASE_URL || "https://mainnet.anyspend.com";
|
|
3
3
|
export const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
4
|
+
export const GAS_ORACLE_BASE_URL = process.env.NEXT_PUBLIC_GAS_ORACLE_URL || "https://gas-oracle.sean-430.workers.dev";
|
|
5
|
+
export const RELAY_ETH_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
4
6
|
export const RELAY_SOL_ADDRESS = "11111111111111111111111111111111";
|
|
5
7
|
export const RELAY_SOLANA_MAINNET_CHAIN_ID = 792703809;
|
|
6
8
|
export const SOLANA_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from "./types/api";
|
|
2
|
+
export * from "./types/gas";
|
|
2
3
|
export * from "./utils/address";
|
|
3
4
|
export * from "./utils/chain";
|
|
4
5
|
export * from "./utils/format";
|
|
@@ -8,5 +9,6 @@ export * from "./utils/string";
|
|
|
8
9
|
export * from "./utils/token";
|
|
9
10
|
export * from "./utils/validation";
|
|
10
11
|
export * from "./constants";
|
|
12
|
+
export * from "./services/gas";
|
|
11
13
|
export * from "./abis/abiUsdcBase";
|
|
12
14
|
export * from "./abis/erc20Staking";
|