@b3dotfun/sdk 0.0.40-alpha.26 → 0.0.40-alpha.27
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/AnyspendSignatureMint.js +1 -1
- package/dist/cjs/anyspend/services/anyspend.d.ts +1 -1
- package/dist/cjs/anyspend/services/anyspend.js +2 -0
- package/dist/cjs/bondkit/components/TradingView.js +3 -4
- package/dist/cjs/bondkit/swapService.js +3 -0
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +18 -12
- package/dist/cjs/global-account/react/hooks/useAccountAssets.js +5 -2
- package/dist/cjs/global-account/react/hooks/useAuthentication.js +1 -1
- package/dist/cjs/global-account/react/hooks/useQueryB3.js +5 -2
- package/dist/cjs/global-account/react/hooks/useQueryBSMNT.js +5 -2
- package/dist/cjs/global-account/react/hooks/useTokenBalancesByChain.js +7 -1
- package/dist/cjs/global-account/react/hooks/useTokenFromUrl.js +2 -2
- package/dist/cjs/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +1 -2
- package/dist/cjs/shared/utils/fetchBalances.d.ts +1 -1
- package/dist/esm/anyspend/react/components/AnyspendSignatureMint.js +1 -1
- package/dist/esm/anyspend/services/anyspend.d.ts +1 -1
- package/dist/esm/anyspend/services/anyspend.js +2 -0
- package/dist/esm/bondkit/components/TradingView.js +3 -4
- package/dist/esm/bondkit/swapService.js +5 -2
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +18 -12
- package/dist/esm/global-account/react/hooks/useAccountAssets.js +2 -2
- package/dist/esm/global-account/react/hooks/useAuthentication.js +1 -1
- package/dist/esm/global-account/react/hooks/useQueryB3.js +5 -2
- package/dist/esm/global-account/react/hooks/useQueryBSMNT.js +5 -2
- package/dist/esm/global-account/react/hooks/useTokenBalancesByChain.js +4 -1
- package/dist/esm/global-account/react/hooks/useTokenFromUrl.js +2 -2
- package/dist/esm/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +2 -3
- package/dist/esm/shared/utils/fetchBalances.d.ts +1 -1
- package/dist/types/anyspend/services/anyspend.d.ts +1 -1
- package/dist/types/shared/utils/fetchBalances.d.ts +1 -1
- package/package.json +1 -1
- package/src/anyspend/react/components/AnyspendSignatureMint.tsx +1 -1
- package/src/anyspend/react/hooks/useAnyspendOrderAndTransactions.ts +1 -1
- package/src/anyspend/react/hooks/useCoinbaseOnrampOptions.ts +1 -1
- package/src/anyspend/services/anyspend.ts +3 -1
- package/src/bondkit/components/TradingView.tsx +3 -5
- package/src/bondkit/swapService.ts +10 -7
- package/src/global-account/react/components/B3Provider/B3Provider.tsx +20 -16
- package/src/global-account/react/hooks/useAccountAssets.ts +4 -3
- package/src/global-account/react/hooks/useAuthentication.ts +1 -1
- package/src/global-account/react/hooks/useOneBalance.tsx +1 -1
- package/src/global-account/react/hooks/useQueryB3.ts +22 -15
- package/src/global-account/react/hooks/useQueryBSMNT.ts +22 -15
- package/src/global-account/react/hooks/useTokenBalancesByChain.tsx +4 -1
- package/src/global-account/react/hooks/useTokenFromUrl.tsx +2 -2
- package/src/global-account/react/hooks/useUnifiedChainSwitchAndExecute.ts +2 -3
- package/src/shared/utils/fetchBalances.ts +1 -1
|
@@ -72,7 +72,7 @@ function AnyspendSignatureMint({ loadOrder, mode = "modal", signatureData, image
|
|
|
72
72
|
}
|
|
73
73
|
const encodedData = generateEncodedDataForSignatureMint(signatureData);
|
|
74
74
|
const price = (0, viem_1.parseEther)(signatureData.payload.price?.toString() || "0");
|
|
75
|
-
return ((0, jsx_runtime_1.jsx)(AnySpendCustom_1.AnySpendCustom, { loadOrder: loadOrder, mode: mode, recipientAddress: signatureData.payload.to, orderType: "custom", dstChainId: signatureData.collection.chainId, dstToken: dstToken, dstAmount: price.toString(), contractAddress: signatureData.collection.address, encodedData: encodedData, metadata: {
|
|
75
|
+
return ((0, jsx_runtime_1.jsx)(AnySpendCustom_1.AnySpendCustom, { loadOrder: loadOrder, mode: mode, recipientAddress: signatureData.payload.to, orderType: "custom", dstChainId: signatureData.collection.chainId, dstToken: dstToken, dstAmount: price.toString(), contractAddress: signatureData.collection.address || "", encodedData: encodedData, metadata: {
|
|
76
76
|
action: "Signature Mint",
|
|
77
77
|
}, header: header, onSuccess: onSuccess, showRecipient: true }));
|
|
78
78
|
}
|
|
@@ -28,7 +28,7 @@ export declare const anyspendService: {
|
|
|
28
28
|
}>;
|
|
29
29
|
getOrderAndTransactions: (orderId: string | undefined) => Promise<GetOrderAndTxsResponse>;
|
|
30
30
|
getOrderHistory: (creatorAddress: string | undefined, limit?: number, offset?: number) => Promise<GetOrderHistoryResponse>;
|
|
31
|
-
getCoinbaseOnrampOptions: (country: string, visitorData?: VisitorData) => Promise<GetCoinbaseOnrampOptionsResponse>;
|
|
31
|
+
getCoinbaseOnrampOptions: (country: string | undefined, visitorData?: VisitorData) => Promise<GetCoinbaseOnrampOptionsResponse>;
|
|
32
32
|
checkStripeSupport: (usdAmount?: string, visitorData?: VisitorData) => Promise<{
|
|
33
33
|
stripeOnramp: boolean;
|
|
34
34
|
stripeWeb2: components["schemas"]["StripeWeb2Support"];
|
|
@@ -69,6 +69,7 @@ exports.anyspendService = {
|
|
|
69
69
|
return data;
|
|
70
70
|
},
|
|
71
71
|
getOrderAndTransactions: async (orderId) => {
|
|
72
|
+
(0, invariant_1.default)(orderId, "orderId is required");
|
|
72
73
|
const response = await fetch(`${constants_1.ANYSPEND_MAINNET_BASE_URL}/orders/${orderId}`);
|
|
73
74
|
const data = await response.json();
|
|
74
75
|
return data;
|
|
@@ -86,6 +87,7 @@ exports.anyspendService = {
|
|
|
86
87
|
return data;
|
|
87
88
|
},
|
|
88
89
|
getCoinbaseOnrampOptions: async (country, visitorData) => {
|
|
90
|
+
(0, invariant_1.default)(country, "country is required");
|
|
89
91
|
const params = new URLSearchParams({
|
|
90
92
|
country,
|
|
91
93
|
// include fingerprintId and requestId in the query params
|
|
@@ -2,16 +2,15 @@
|
|
|
2
2
|
"use client";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const cdn_loader_1 = require("./utils/cdn-loader");
|
|
6
|
-
const format_1 = require("./utils/format");
|
|
7
5
|
const lucide_react_1 = require("lucide-react");
|
|
8
6
|
const react_1 = require("react");
|
|
7
|
+
const cdn_loader_1 = require("./utils/cdn-loader");
|
|
8
|
+
const format_1 = require("./utils/format");
|
|
9
9
|
// TradingView will be available on window after loading from CDN
|
|
10
10
|
// Datafeed will be implemented inline
|
|
11
11
|
// Mock loading overlay - replace with your actual loading component
|
|
12
12
|
const GifLoadingOverlay = ({ className }) => ((0, jsx_runtime_1.jsx)("div", { className: `absolute inset-0 flex items-center justify-center bg-white/50 backdrop-blur-sm ${className || ""}`, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "text-secondary-grey h-8 w-8 animate-spin" }) }));
|
|
13
13
|
const TradingView = ({ className, tokenAddress, tokenSymbol }) => {
|
|
14
|
-
const theme = "light";
|
|
15
14
|
// Use token info for the current trade
|
|
16
15
|
const currentTrade = {
|
|
17
16
|
product_id: tokenAddress && tokenSymbol ? `${tokenSymbol}-${tokenAddress}` : "BONDKIT",
|
|
@@ -247,7 +246,7 @@ const TradingView = ({ className, tokenAddress, tokenSymbol }) => {
|
|
|
247
246
|
tvWidgetRef.current = null;
|
|
248
247
|
}
|
|
249
248
|
};
|
|
250
|
-
}, [
|
|
249
|
+
}, [librariesLoaded, currentTrade?.product_id, tradingViewDefaultInterval, tradingViewTimezone]);
|
|
251
250
|
(0, react_1.useEffect)(() => {
|
|
252
251
|
if (chartLoaded &&
|
|
253
252
|
currentTrade?.product_id &&
|
|
@@ -52,22 +52,28 @@ function B3Provider({ theme = "light", children, accountOverride, environment, a
|
|
|
52
52
|
client: thirdweb_1.client,
|
|
53
53
|
};
|
|
54
54
|
}, [partnerId]);
|
|
55
|
+
// Stringify rpcUrls for stable comparison to prevent wagmiConfig recreation
|
|
56
|
+
// when parent component passes new object references with same content
|
|
57
|
+
const rpcUrlsString = (0, react_2.useMemo)(() => (rpcUrls ? JSON.stringify(rpcUrls) : undefined), [rpcUrls]);
|
|
55
58
|
/**
|
|
56
59
|
* Creates wagmi config with optional custom RPC URLs
|
|
57
60
|
* @param rpcUrls - Optional mapping of chain IDs to RPC URLs
|
|
58
61
|
*/
|
|
59
|
-
const wagmiConfig = (0, react_2.useMemo)(() =>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
(0,
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
62
|
+
const wagmiConfig = (0, react_2.useMemo)(() => {
|
|
63
|
+
const parsedRpcUrls = rpcUrlsString ? JSON.parse(rpcUrlsString) : undefined;
|
|
64
|
+
return (0, wagmi_1.createConfig)({
|
|
65
|
+
chains: [supported_1.supportedChains[0], ...supported_1.supportedChains.slice(1)],
|
|
66
|
+
transports: Object.fromEntries(supported_1.supportedChains.map(chain => [chain.id, (0, wagmi_1.http)(parsedRpcUrls?.[chain.id])])),
|
|
67
|
+
connectors: [
|
|
68
|
+
(0, wagmi_adapter_1.inAppWalletConnector)({
|
|
69
|
+
...(ecocystemConfig || {}),
|
|
70
|
+
client: thirdweb_1.client,
|
|
71
|
+
}),
|
|
72
|
+
// injected(),
|
|
73
|
+
// coinbaseWallet({ appName: "HypeDuel" }),
|
|
74
|
+
],
|
|
75
|
+
});
|
|
76
|
+
}, [ecocystemConfig, rpcUrlsString]);
|
|
71
77
|
return ((0, jsx_runtime_1.jsx)(react_3.ThirdwebProvider, { children: (0, jsx_runtime_1.jsx)(wagmi_1.WagmiProvider, { config: wagmiConfig, children: (0, jsx_runtime_1.jsx)(react_query_1.QueryClientProvider, { client: queryClient, children: (0, jsx_runtime_1.jsx)(react_1.TooltipProvider, { children: (0, jsx_runtime_1.jsx)(InnerProvider, { accountOverride: accountOverride, environment: environment, theme: theme, automaticallySetFirstEoa: !!automaticallySetFirstEoa, clientType: clientType, children: (0, jsx_runtime_1.jsxs)(react_1.RelayKitProviderWrapper, { simDuneApiKey: simDuneApiKey, children: [children, (0, jsx_runtime_1.jsx)(StyleRoot_1.StyleRoot, { id: "b3-root" }), (0, jsx_runtime_1.jsx)(sonner_1.Toaster, { theme: theme, position: toaster?.position, style: toaster?.style })] }) }) }) }) }) }));
|
|
72
78
|
}
|
|
73
79
|
/**
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.useAccountAssets = useAccountAssets;
|
|
4
7
|
const simplehash_1 = require("../../../shared/utils/simplehash");
|
|
5
8
|
const react_query_1 = require("@tanstack/react-query");
|
|
9
|
+
const invariant_1 = __importDefault(require("invariant"));
|
|
6
10
|
async function fetchAccountAssets(address) {
|
|
7
|
-
|
|
8
|
-
throw new Error("Address is required");
|
|
11
|
+
(0, invariant_1.default)(address, "Address is required");
|
|
9
12
|
const [nftResponse] = await Promise.all([
|
|
10
13
|
(0, simplehash_1.fetchSimpleHashData)(`/v0/nfts/owners`, {
|
|
11
14
|
chains: "b3,b3-sepolia,base",
|
|
@@ -98,7 +98,7 @@ function useAuthentication(partnerId, loginWithSiwe) {
|
|
|
98
98
|
setIsAuthenticating(false);
|
|
99
99
|
}
|
|
100
100
|
useAutoConnectLoadingPrevious.current = useAutoConnectLoading;
|
|
101
|
-
}, [useAutoConnectLoading]);
|
|
101
|
+
}, [useAutoConnectLoading, hasStartedConnecting, setIsAuthenticating]);
|
|
102
102
|
// Ensure isAuthenticating stays true until we're fully ready
|
|
103
103
|
(0, react_2.useEffect)(() => {
|
|
104
104
|
if (useAutoConnectLoading) {
|
|
@@ -30,11 +30,14 @@ fetchInitially = true) {
|
|
|
30
30
|
finally {
|
|
31
31
|
setIsLoading(false);
|
|
32
32
|
}
|
|
33
|
-
}, []);
|
|
33
|
+
}, [service, method]);
|
|
34
|
+
// Serialize params for stable comparison
|
|
35
|
+
const paramsJson = JSON.stringify(params);
|
|
34
36
|
(0, react_1.useEffect)(() => {
|
|
35
37
|
if (fetchInitially) {
|
|
36
38
|
runQuery(params);
|
|
37
39
|
}
|
|
38
|
-
|
|
40
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
41
|
+
}, [runQuery, fetchInitially, paramsJson]);
|
|
39
42
|
return { data, error, isLoading, runQuery };
|
|
40
43
|
}
|
|
@@ -30,11 +30,14 @@ fetchInitially = true) {
|
|
|
30
30
|
finally {
|
|
31
31
|
setIsLoading(false);
|
|
32
32
|
}
|
|
33
|
-
}, []);
|
|
33
|
+
}, [service, method]);
|
|
34
|
+
// Serialize params for stable comparison
|
|
35
|
+
const paramsJson = JSON.stringify(params);
|
|
34
36
|
(0, react_1.useEffect)(() => {
|
|
35
37
|
if (fetchInitially) {
|
|
36
38
|
runQuery(params);
|
|
37
39
|
}
|
|
38
|
-
|
|
40
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
41
|
+
}, [runQuery, fetchInitially, paramsJson]);
|
|
39
42
|
return { data, error, isLoading, runQuery };
|
|
40
43
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
"use client";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
3
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
7
|
exports.useTokenBalancesByChain = useTokenBalancesByChain;
|
|
5
8
|
const thirdweb_insights_1 = require("../../../shared/utils/thirdweb-insights");
|
|
@@ -8,6 +11,7 @@ const b3Chain_1 = require("../../../shared/constants/chains/b3Chain");
|
|
|
8
11
|
const chains_1 = require("../../../shared/utils/chains");
|
|
9
12
|
const thirdweb_1 = require("../../../shared/utils/thirdweb");
|
|
10
13
|
const wallets_1 = require("thirdweb/wallets");
|
|
14
|
+
const invariant_1 = __importDefault(require("invariant"));
|
|
11
15
|
function useTokenBalancesByChain({ address, chainsIds, enabled = true, }) {
|
|
12
16
|
// Normalize chains to array
|
|
13
17
|
const chainIds = Array.isArray(chainsIds) ? chainsIds : [chainsIds];
|
|
@@ -19,10 +23,12 @@ function useTokenBalancesByChain({ address, chainsIds, enabled = true, }) {
|
|
|
19
23
|
const [nativeTokens, fungibleResponse] = await Promise.all([
|
|
20
24
|
// Fetch native token balances
|
|
21
25
|
Promise.all(chainIds.map(async (chainId) => {
|
|
26
|
+
const chain = (0, chains_1.getChainById)(chainId);
|
|
27
|
+
(0, invariant_1.default)(chain, "Chain is required");
|
|
22
28
|
const walletBalance = await (0, wallets_1.getWalletBalance)({
|
|
23
29
|
address,
|
|
24
30
|
client: thirdweb_1.client,
|
|
25
|
-
chain: (0, b3Chain_1.viemToThirdwebChain)(
|
|
31
|
+
chain: (0, b3Chain_1.viemToThirdwebChain)(chain),
|
|
26
32
|
});
|
|
27
33
|
return {
|
|
28
34
|
...walletBalance,
|
|
@@ -38,7 +38,7 @@ function useTokenFromUrl({ defaultToken, prefix }) {
|
|
|
38
38
|
const network = chainIdParam ? (0, supported_1.getCoingeckoChainInfo)(Number(chainIdParam)).coingecko_id : "";
|
|
39
39
|
const { data: tokenInfo, isError } = (0, react_query_1.useQuery)({
|
|
40
40
|
queryKey: ["tokenInfo", network, currencyParam],
|
|
41
|
-
queryFn: () => fetchTokenInfo(network, currencyParam),
|
|
41
|
+
queryFn: () => fetchTokenInfo(network, currencyParam || ""),
|
|
42
42
|
enabled: shouldFetchToken,
|
|
43
43
|
staleTime: Infinity,
|
|
44
44
|
gcTime: Infinity,
|
|
@@ -51,7 +51,7 @@ function useTokenFromUrl({ defaultToken, prefix }) {
|
|
|
51
51
|
if (isError || !tokenInfo) {
|
|
52
52
|
return {
|
|
53
53
|
...defaultToken,
|
|
54
|
-
address: currencyParam,
|
|
54
|
+
address: currencyParam || "",
|
|
55
55
|
chainId: Number(chainIdParam),
|
|
56
56
|
};
|
|
57
57
|
}
|
|
@@ -23,7 +23,6 @@ const partnerId = String(process.env.PUBLIC_THIRDWEB_PARTNER_ID ||
|
|
|
23
23
|
process.env.NEXT_PUBLIC_GLOBAL_ACCOUNTS_PARTNER_ID);
|
|
24
24
|
(0, invariant_1.default)(partnerId, "Partner ID is required");
|
|
25
25
|
function useUnifiedChainSwitchAndExecute() {
|
|
26
|
-
const { data: walletClient } = (0, wagmi_1.useWalletClient)();
|
|
27
26
|
const { switchChainAsync } = (0, wagmi_1.useSwitchChain)();
|
|
28
27
|
const [isSwitchingOrExecuting, setIsSwitchingOrExecuting] = (0, react_1.useState)(false);
|
|
29
28
|
const activeWallet = (0, react_2.useActiveWallet)();
|
|
@@ -104,7 +103,7 @@ function useUnifiedChainSwitchAndExecute() {
|
|
|
104
103
|
finally {
|
|
105
104
|
setIsSwitchingOrExecuting(false);
|
|
106
105
|
}
|
|
107
|
-
}, [
|
|
106
|
+
}, [connectedEOAWallet, activeWallet, switchChainAsync]);
|
|
108
107
|
// Handle AA wallet transaction (no chain switch needed for AA)
|
|
109
108
|
const handleAASendTransaction = (0, react_1.useCallback)(async (targetChainId, params) => {
|
|
110
109
|
if (!aaAccount) {
|
|
@@ -13,4 +13,4 @@ export interface AssetBalance {
|
|
|
13
13
|
totalBalance: string;
|
|
14
14
|
chainBalances: ChainBalance[];
|
|
15
15
|
}
|
|
16
|
-
export declare const fetchBalances: (address: string, testnet?: boolean) => Promise<AssetBalance[]>;
|
|
16
|
+
export declare const fetchBalances: (address: string | undefined, testnet?: boolean) => Promise<AssetBalance[]>;
|
|
@@ -66,7 +66,7 @@ export function AnyspendSignatureMint({ loadOrder, mode = "modal", signatureData
|
|
|
66
66
|
}
|
|
67
67
|
const encodedData = generateEncodedDataForSignatureMint(signatureData);
|
|
68
68
|
const price = parseEther(signatureData.payload.price?.toString() || "0");
|
|
69
|
-
return (_jsx(AnySpendCustom, { loadOrder: loadOrder, mode: mode, recipientAddress: signatureData.payload.to, orderType: "custom", dstChainId: signatureData.collection.chainId, dstToken: dstToken, dstAmount: price.toString(), contractAddress: signatureData.collection.address, encodedData: encodedData, metadata: {
|
|
69
|
+
return (_jsx(AnySpendCustom, { loadOrder: loadOrder, mode: mode, recipientAddress: signatureData.payload.to, orderType: "custom", dstChainId: signatureData.collection.chainId, dstToken: dstToken, dstAmount: price.toString(), contractAddress: signatureData.collection.address || "", encodedData: encodedData, metadata: {
|
|
70
70
|
action: "Signature Mint",
|
|
71
71
|
}, header: header, onSuccess: onSuccess, showRecipient: true }));
|
|
72
72
|
}
|
|
@@ -28,7 +28,7 @@ export declare const anyspendService: {
|
|
|
28
28
|
}>;
|
|
29
29
|
getOrderAndTransactions: (orderId: string | undefined) => Promise<GetOrderAndTxsResponse>;
|
|
30
30
|
getOrderHistory: (creatorAddress: string | undefined, limit?: number, offset?: number) => Promise<GetOrderHistoryResponse>;
|
|
31
|
-
getCoinbaseOnrampOptions: (country: string, visitorData?: VisitorData) => Promise<GetCoinbaseOnrampOptionsResponse>;
|
|
31
|
+
getCoinbaseOnrampOptions: (country: string | undefined, visitorData?: VisitorData) => Promise<GetCoinbaseOnrampOptionsResponse>;
|
|
32
32
|
checkStripeSupport: (usdAmount?: string, visitorData?: VisitorData) => Promise<{
|
|
33
33
|
stripeOnramp: boolean;
|
|
34
34
|
stripeWeb2: components["schemas"]["StripeWeb2Support"];
|
|
@@ -63,6 +63,7 @@ export const anyspendService = {
|
|
|
63
63
|
return data;
|
|
64
64
|
},
|
|
65
65
|
getOrderAndTransactions: async (orderId) => {
|
|
66
|
+
invariant(orderId, "orderId is required");
|
|
66
67
|
const response = await fetch(`${ANYSPEND_MAINNET_BASE_URL}/orders/${orderId}`);
|
|
67
68
|
const data = await response.json();
|
|
68
69
|
return data;
|
|
@@ -80,6 +81,7 @@ export const anyspendService = {
|
|
|
80
81
|
return data;
|
|
81
82
|
},
|
|
82
83
|
getCoinbaseOnrampOptions: async (country, visitorData) => {
|
|
84
|
+
invariant(country, "country is required");
|
|
83
85
|
const params = new URLSearchParams({
|
|
84
86
|
country,
|
|
85
87
|
// include fingerprintId and requestId in the query params
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { loadScriptFromCDN } from "./utils/cdn-loader.js";
|
|
4
|
-
import { formatNumberSmall } from "./utils/format.js";
|
|
5
3
|
import { Loader2 } from "lucide-react";
|
|
6
4
|
import { useEffect, useRef, useState } from "react";
|
|
5
|
+
import { loadScriptFromCDN } from "./utils/cdn-loader.js";
|
|
6
|
+
import { formatNumberSmall } from "./utils/format.js";
|
|
7
7
|
// TradingView will be available on window after loading from CDN
|
|
8
8
|
// Datafeed will be implemented inline
|
|
9
9
|
// Mock loading overlay - replace with your actual loading component
|
|
10
10
|
const GifLoadingOverlay = ({ className }) => (_jsx("div", { className: `absolute inset-0 flex items-center justify-center bg-white/50 backdrop-blur-sm ${className || ""}`, children: _jsx(Loader2, { className: "text-secondary-grey h-8 w-8 animate-spin" }) }));
|
|
11
11
|
const TradingView = ({ className, tokenAddress, tokenSymbol }) => {
|
|
12
|
-
const theme = "light";
|
|
13
12
|
// Use token info for the current trade
|
|
14
13
|
const currentTrade = {
|
|
15
14
|
product_id: tokenAddress && tokenSymbol ? `${tokenSymbol}-${tokenAddress}` : "BONDKIT",
|
|
@@ -245,7 +244,7 @@ const TradingView = ({ className, tokenAddress, tokenSymbol }) => {
|
|
|
245
244
|
tvWidgetRef.current = null;
|
|
246
245
|
}
|
|
247
246
|
};
|
|
248
|
-
}, [
|
|
247
|
+
}, [librariesLoaded, currentTrade?.product_id, tradingViewDefaultInterval, tradingViewTimezone]);
|
|
249
248
|
useEffect(() => {
|
|
250
249
|
if (chartLoaded &&
|
|
251
250
|
currentTrade?.product_id &&
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createPublicClient, encodeAbiParameters, formatUnits, getContract, http, parseAbiParameters, parseUnits, } from "viem";
|
|
2
2
|
import { base } from "viem/chains";
|
|
3
|
-
import {
|
|
3
|
+
import { BaseMainnetRpcUrl, Permit2Address, QuoterAddress, UniversalRouterAddress } from "./constants.js";
|
|
4
4
|
// Minimal ABIs needed for swap functionality
|
|
5
5
|
const UNIVERSAL_ROUTER_ABI = [
|
|
6
6
|
{
|
|
@@ -187,6 +187,9 @@ export class BondkitSwapService {
|
|
|
187
187
|
*/
|
|
188
188
|
async getV4Config() {
|
|
189
189
|
await this.initializeV4Config();
|
|
190
|
+
if (!this.v4Config) {
|
|
191
|
+
throw new Error("Failed to initialize V4 configuration");
|
|
192
|
+
}
|
|
190
193
|
return this.v4Config;
|
|
191
194
|
}
|
|
192
195
|
/**
|
|
@@ -48,22 +48,28 @@ export function B3Provider({ theme = "light", children, accountOverride, environ
|
|
|
48
48
|
client,
|
|
49
49
|
};
|
|
50
50
|
}, [partnerId]);
|
|
51
|
+
// Stringify rpcUrls for stable comparison to prevent wagmiConfig recreation
|
|
52
|
+
// when parent component passes new object references with same content
|
|
53
|
+
const rpcUrlsString = useMemo(() => (rpcUrls ? JSON.stringify(rpcUrls) : undefined), [rpcUrls]);
|
|
51
54
|
/**
|
|
52
55
|
* Creates wagmi config with optional custom RPC URLs
|
|
53
56
|
* @param rpcUrls - Optional mapping of chain IDs to RPC URLs
|
|
54
57
|
*/
|
|
55
|
-
const wagmiConfig = useMemo(() =>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
58
|
+
const wagmiConfig = useMemo(() => {
|
|
59
|
+
const parsedRpcUrls = rpcUrlsString ? JSON.parse(rpcUrlsString) : undefined;
|
|
60
|
+
return createConfig({
|
|
61
|
+
chains: [supportedChains[0], ...supportedChains.slice(1)],
|
|
62
|
+
transports: Object.fromEntries(supportedChains.map(chain => [chain.id, http(parsedRpcUrls?.[chain.id])])),
|
|
63
|
+
connectors: [
|
|
64
|
+
inAppWalletConnector({
|
|
65
|
+
...(ecocystemConfig || {}),
|
|
66
|
+
client,
|
|
67
|
+
}),
|
|
68
|
+
// injected(),
|
|
69
|
+
// coinbaseWallet({ appName: "HypeDuel" }),
|
|
70
|
+
],
|
|
71
|
+
});
|
|
72
|
+
}, [ecocystemConfig, rpcUrlsString]);
|
|
67
73
|
return (_jsx(ThirdwebProvider, { children: _jsx(WagmiProvider, { config: wagmiConfig, children: _jsx(QueryClientProvider, { client: queryClient, children: _jsx(TooltipProvider, { children: _jsx(InnerProvider, { accountOverride: accountOverride, environment: environment, theme: theme, automaticallySetFirstEoa: !!automaticallySetFirstEoa, clientType: clientType, children: _jsxs(RelayKitProviderWrapper, { simDuneApiKey: simDuneApiKey, children: [children, _jsx(StyleRoot, { id: "b3-root" }), _jsx(Toaster, { theme: theme, position: toaster?.position, style: toaster?.style })] }) }) }) }) }) }));
|
|
68
74
|
}
|
|
69
75
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { fetchSimpleHashData } from "../../../shared/utils/simplehash.js";
|
|
2
2
|
import { useQuery } from "@tanstack/react-query";
|
|
3
|
+
import invariant from "invariant";
|
|
3
4
|
async function fetchAccountAssets(address) {
|
|
4
|
-
|
|
5
|
-
throw new Error("Address is required");
|
|
5
|
+
invariant(address, "Address is required");
|
|
6
6
|
const [nftResponse] = await Promise.all([
|
|
7
7
|
fetchSimpleHashData(`/v0/nfts/owners`, {
|
|
8
8
|
chains: "b3,b3-sepolia,base",
|
|
@@ -92,7 +92,7 @@ export function useAuthentication(partnerId, loginWithSiwe) {
|
|
|
92
92
|
setIsAuthenticating(false);
|
|
93
93
|
}
|
|
94
94
|
useAutoConnectLoadingPrevious.current = useAutoConnectLoading;
|
|
95
|
-
}, [useAutoConnectLoading]);
|
|
95
|
+
}, [useAutoConnectLoading, hasStartedConnecting, setIsAuthenticating]);
|
|
96
96
|
// Ensure isAuthenticating stays true until we're fully ready
|
|
97
97
|
useEffect(() => {
|
|
98
98
|
if (useAutoConnectLoading) {
|
|
@@ -24,11 +24,14 @@ fetchInitially = true) {
|
|
|
24
24
|
finally {
|
|
25
25
|
setIsLoading(false);
|
|
26
26
|
}
|
|
27
|
-
}, []);
|
|
27
|
+
}, [service, method]);
|
|
28
|
+
// Serialize params for stable comparison
|
|
29
|
+
const paramsJson = JSON.stringify(params);
|
|
28
30
|
useEffect(() => {
|
|
29
31
|
if (fetchInitially) {
|
|
30
32
|
runQuery(params);
|
|
31
33
|
}
|
|
32
|
-
|
|
34
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
35
|
+
}, [runQuery, fetchInitially, paramsJson]);
|
|
33
36
|
return { data, error, isLoading, runQuery };
|
|
34
37
|
}
|
|
@@ -24,11 +24,14 @@ fetchInitially = true) {
|
|
|
24
24
|
finally {
|
|
25
25
|
setIsLoading(false);
|
|
26
26
|
}
|
|
27
|
-
}, []);
|
|
27
|
+
}, [service, method]);
|
|
28
|
+
// Serialize params for stable comparison
|
|
29
|
+
const paramsJson = JSON.stringify(params);
|
|
28
30
|
useEffect(() => {
|
|
29
31
|
if (fetchInitially) {
|
|
30
32
|
runQuery(params);
|
|
31
33
|
}
|
|
32
|
-
|
|
34
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
35
|
+
}, [runQuery, fetchInitially, paramsJson]);
|
|
33
36
|
return { data, error, isLoading, runQuery };
|
|
34
37
|
}
|
|
@@ -5,6 +5,7 @@ import { viemToThirdwebChain } from "../../../shared/constants/chains/b3Chain.js
|
|
|
5
5
|
import { getChainById } from "../../../shared/utils/chains.js";
|
|
6
6
|
import { client } from "../../../shared/utils/thirdweb.js";
|
|
7
7
|
import { getWalletBalance } from "thirdweb/wallets";
|
|
8
|
+
import invariant from "invariant";
|
|
8
9
|
export function useTokenBalancesByChain({ address, chainsIds, enabled = true, }) {
|
|
9
10
|
// Normalize chains to array
|
|
10
11
|
const chainIds = Array.isArray(chainsIds) ? chainsIds : [chainsIds];
|
|
@@ -16,10 +17,12 @@ export function useTokenBalancesByChain({ address, chainsIds, enabled = true, })
|
|
|
16
17
|
const [nativeTokens, fungibleResponse] = await Promise.all([
|
|
17
18
|
// Fetch native token balances
|
|
18
19
|
Promise.all(chainIds.map(async (chainId) => {
|
|
20
|
+
const chain = getChainById(chainId);
|
|
21
|
+
invariant(chain, "Chain is required");
|
|
19
22
|
const walletBalance = await getWalletBalance({
|
|
20
23
|
address,
|
|
21
24
|
client,
|
|
22
|
-
chain: viemToThirdwebChain(
|
|
25
|
+
chain: viemToThirdwebChain(chain),
|
|
23
26
|
});
|
|
24
27
|
return {
|
|
25
28
|
...walletBalance,
|
|
@@ -34,7 +34,7 @@ export function useTokenFromUrl({ defaultToken, prefix }) {
|
|
|
34
34
|
const network = chainIdParam ? getCoingeckoChainInfo(Number(chainIdParam)).coingecko_id : "";
|
|
35
35
|
const { data: tokenInfo, isError } = useQuery({
|
|
36
36
|
queryKey: ["tokenInfo", network, currencyParam],
|
|
37
|
-
queryFn: () => fetchTokenInfo(network, currencyParam),
|
|
37
|
+
queryFn: () => fetchTokenInfo(network, currencyParam || ""),
|
|
38
38
|
enabled: shouldFetchToken,
|
|
39
39
|
staleTime: Infinity,
|
|
40
40
|
gcTime: Infinity,
|
|
@@ -47,7 +47,7 @@ export function useTokenFromUrl({ defaultToken, prefix }) {
|
|
|
47
47
|
if (isError || !tokenInfo) {
|
|
48
48
|
return {
|
|
49
49
|
...defaultToken,
|
|
50
|
-
address: currencyParam,
|
|
50
|
+
address: currencyParam || "",
|
|
51
51
|
chainId: Number(chainIdParam),
|
|
52
52
|
};
|
|
53
53
|
}
|
|
@@ -8,7 +8,7 @@ import { toast } from "sonner";
|
|
|
8
8
|
import { prepareTransaction, sendTransaction as twSendTransaction } from "thirdweb";
|
|
9
9
|
import { useActiveWallet } from "thirdweb/react";
|
|
10
10
|
import { isAddress } from "viem";
|
|
11
|
-
import { useSwitchChain
|
|
11
|
+
import { useSwitchChain } from "wagmi";
|
|
12
12
|
import { useB3 } from "../components/index.js";
|
|
13
13
|
import { useAccountWallet } from "./useAccountWallet.js";
|
|
14
14
|
const partnerId = String(process.env.PUBLIC_THIRDWEB_PARTNER_ID ||
|
|
@@ -17,7 +17,6 @@ const partnerId = String(process.env.PUBLIC_THIRDWEB_PARTNER_ID ||
|
|
|
17
17
|
process.env.NEXT_PUBLIC_GLOBAL_ACCOUNTS_PARTNER_ID);
|
|
18
18
|
invariant(partnerId, "Partner ID is required");
|
|
19
19
|
export function useUnifiedChainSwitchAndExecute() {
|
|
20
|
-
const { data: walletClient } = useWalletClient();
|
|
21
20
|
const { switchChainAsync } = useSwitchChain();
|
|
22
21
|
const [isSwitchingOrExecuting, setIsSwitchingOrExecuting] = useState(false);
|
|
23
22
|
const activeWallet = useActiveWallet();
|
|
@@ -98,7 +97,7 @@ export function useUnifiedChainSwitchAndExecute() {
|
|
|
98
97
|
finally {
|
|
99
98
|
setIsSwitchingOrExecuting(false);
|
|
100
99
|
}
|
|
101
|
-
}, [
|
|
100
|
+
}, [connectedEOAWallet, activeWallet, switchChainAsync]);
|
|
102
101
|
// Handle AA wallet transaction (no chain switch needed for AA)
|
|
103
102
|
const handleAASendTransaction = useCallback(async (targetChainId, params) => {
|
|
104
103
|
if (!aaAccount) {
|
|
@@ -13,4 +13,4 @@ export interface AssetBalance {
|
|
|
13
13
|
totalBalance: string;
|
|
14
14
|
chainBalances: ChainBalance[];
|
|
15
15
|
}
|
|
16
|
-
export declare const fetchBalances: (address: string, testnet?: boolean) => Promise<AssetBalance[]>;
|
|
16
|
+
export declare const fetchBalances: (address: string | undefined, testnet?: boolean) => Promise<AssetBalance[]>;
|
|
@@ -28,7 +28,7 @@ export declare const anyspendService: {
|
|
|
28
28
|
}>;
|
|
29
29
|
getOrderAndTransactions: (orderId: string | undefined) => Promise<GetOrderAndTxsResponse>;
|
|
30
30
|
getOrderHistory: (creatorAddress: string | undefined, limit?: number, offset?: number) => Promise<GetOrderHistoryResponse>;
|
|
31
|
-
getCoinbaseOnrampOptions: (country: string, visitorData?: VisitorData) => Promise<GetCoinbaseOnrampOptionsResponse>;
|
|
31
|
+
getCoinbaseOnrampOptions: (country: string | undefined, visitorData?: VisitorData) => Promise<GetCoinbaseOnrampOptionsResponse>;
|
|
32
32
|
checkStripeSupport: (usdAmount?: string, visitorData?: VisitorData) => Promise<{
|
|
33
33
|
stripeOnramp: boolean;
|
|
34
34
|
stripeWeb2: components["schemas"]["StripeWeb2Support"];
|
|
@@ -13,4 +13,4 @@ export interface AssetBalance {
|
|
|
13
13
|
totalBalance: string;
|
|
14
14
|
chainBalances: ChainBalance[];
|
|
15
15
|
}
|
|
16
|
-
export declare const fetchBalances: (address: string, testnet?: boolean) => Promise<AssetBalance[]>;
|
|
16
|
+
export declare const fetchBalances: (address: string | undefined, testnet?: boolean) => Promise<AssetBalance[]>;
|
package/package.json
CHANGED
|
@@ -141,7 +141,7 @@ 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
147
|
action: "Signature Mint",
|
|
@@ -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
|
|
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
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { loadScriptFromCDN } from "./utils/cdn-loader";
|
|
4
|
-
import { formatNumberSmall } from "./utils/format";
|
|
5
3
|
import { Loader2 } from "lucide-react";
|
|
6
4
|
import { useEffect, useRef, useState } from "react";
|
|
7
5
|
import { TradingViewProps } from "./types";
|
|
6
|
+
import { loadScriptFromCDN } from "./utils/cdn-loader";
|
|
7
|
+
import { formatNumberSmall } from "./utils/format";
|
|
8
8
|
|
|
9
9
|
// TypeScript types - these will be loaded from CDN at runtime
|
|
10
10
|
type ChartingLibraryWidgetOptions = any;
|
|
@@ -24,8 +24,6 @@ const GifLoadingOverlay = ({ className }: { className?: string }) => (
|
|
|
24
24
|
);
|
|
25
25
|
|
|
26
26
|
const TradingView = ({ className, tokenAddress, tokenSymbol }: TradingViewProps) => {
|
|
27
|
-
const theme = "light";
|
|
28
|
-
|
|
29
27
|
// Use token info for the current trade
|
|
30
28
|
const currentTrade = {
|
|
31
29
|
product_id: tokenAddress && tokenSymbol ? `${tokenSymbol}-${tokenAddress}` : "BONDKIT",
|
|
@@ -282,7 +280,7 @@ const TradingView = ({ className, tokenAddress, tokenSymbol }: TradingViewProps)
|
|
|
282
280
|
tvWidgetRef.current = null;
|
|
283
281
|
}
|
|
284
282
|
};
|
|
285
|
-
}, [
|
|
283
|
+
}, [librariesLoaded, currentTrade?.product_id, tradingViewDefaultInterval, tradingViewTimezone]);
|
|
286
284
|
|
|
287
285
|
useEffect(() => {
|
|
288
286
|
if (
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type { Address, Hex,
|
|
1
|
+
import type { Address, Hex, PublicClient, WalletClient } from "viem";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
formatUnits,
|
|
3
|
+
createPublicClient,
|
|
5
4
|
encodeAbiParameters,
|
|
6
|
-
|
|
5
|
+
formatUnits,
|
|
7
6
|
getContract,
|
|
8
|
-
createPublicClient,
|
|
9
7
|
http,
|
|
8
|
+
parseAbiParameters,
|
|
9
|
+
parseUnits,
|
|
10
10
|
} from "viem";
|
|
11
11
|
import { base } from "viem/chains";
|
|
12
|
-
import {
|
|
12
|
+
import { BaseMainnetRpcUrl, Permit2Address, QuoterAddress, UniversalRouterAddress } from "./constants";
|
|
13
13
|
import type { SwapQuote } from "./types";
|
|
14
14
|
|
|
15
15
|
// Minimal ABIs needed for swap functionality
|
|
@@ -230,7 +230,10 @@ export class BondkitSwapService {
|
|
|
230
230
|
*/
|
|
231
231
|
private async getV4Config(): Promise<V4PoolConfig> {
|
|
232
232
|
await this.initializeV4Config();
|
|
233
|
-
|
|
233
|
+
if (!this.v4Config) {
|
|
234
|
+
throw new Error("Failed to initialize V4 configuration");
|
|
235
|
+
}
|
|
236
|
+
return this.v4Config;
|
|
234
237
|
}
|
|
235
238
|
|
|
236
239
|
/**
|
|
@@ -88,26 +88,30 @@ export function B3Provider({
|
|
|
88
88
|
};
|
|
89
89
|
}, [partnerId]);
|
|
90
90
|
|
|
91
|
+
// Stringify rpcUrls for stable comparison to prevent wagmiConfig recreation
|
|
92
|
+
// when parent component passes new object references with same content
|
|
93
|
+
const rpcUrlsString = useMemo(() => (rpcUrls ? JSON.stringify(rpcUrls) : undefined), [rpcUrls]);
|
|
94
|
+
|
|
91
95
|
/**
|
|
92
96
|
* Creates wagmi config with optional custom RPC URLs
|
|
93
97
|
* @param rpcUrls - Optional mapping of chain IDs to RPC URLs
|
|
94
98
|
*/
|
|
95
|
-
const wagmiConfig = useMemo(
|
|
96
|
-
()
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
);
|
|
99
|
+
const wagmiConfig = useMemo(() => {
|
|
100
|
+
const parsedRpcUrls = rpcUrlsString ? JSON.parse(rpcUrlsString) : undefined;
|
|
101
|
+
|
|
102
|
+
return createConfig({
|
|
103
|
+
chains: [supportedChains[0], ...supportedChains.slice(1)],
|
|
104
|
+
transports: Object.fromEntries(supportedChains.map(chain => [chain.id, http(parsedRpcUrls?.[chain.id])])),
|
|
105
|
+
connectors: [
|
|
106
|
+
inAppWalletConnector({
|
|
107
|
+
...(ecocystemConfig || {}),
|
|
108
|
+
client,
|
|
109
|
+
}),
|
|
110
|
+
// injected(),
|
|
111
|
+
// coinbaseWallet({ appName: "HypeDuel" }),
|
|
112
|
+
],
|
|
113
|
+
});
|
|
114
|
+
}, [ecocystemConfig, rpcUrlsString]);
|
|
111
115
|
|
|
112
116
|
return (
|
|
113
117
|
<ThirdwebProvider>
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { fetchSimpleHashData } from "@b3dotfun/sdk/shared/utils/simplehash";
|
|
2
2
|
import { useQuery } from "@tanstack/react-query";
|
|
3
|
+
import invariant from "invariant";
|
|
3
4
|
|
|
4
|
-
async function fetchAccountAssets(address: string) {
|
|
5
|
-
|
|
5
|
+
async function fetchAccountAssets(address: string | undefined) {
|
|
6
|
+
invariant(address, "Address is required");
|
|
6
7
|
|
|
7
8
|
const [nftResponse] = await Promise.all([
|
|
8
9
|
fetchSimpleHashData(`/v0/nfts/owners`, {
|
|
@@ -27,7 +28,7 @@ async function fetchAccountAssets(address: string) {
|
|
|
27
28
|
export function useAccountAssets(address?: string) {
|
|
28
29
|
return useQuery({
|
|
29
30
|
queryKey: ["accountAssets", address],
|
|
30
|
-
queryFn: () => fetchAccountAssets(address
|
|
31
|
+
queryFn: () => fetchAccountAssets(address),
|
|
31
32
|
enabled: Boolean(address),
|
|
32
33
|
staleTime: 30 * 1000, // Consider data fresh for 30 seconds
|
|
33
34
|
gcTime: 5 * 60 * 1000, // Keep unused data in cache for 5 minutes
|
|
@@ -100,7 +100,7 @@ export function useAuthentication(partnerId: string, loginWithSiwe?: boolean) {
|
|
|
100
100
|
setIsAuthenticating(false);
|
|
101
101
|
}
|
|
102
102
|
useAutoConnectLoadingPrevious.current = useAutoConnectLoading;
|
|
103
|
-
}, [useAutoConnectLoading]);
|
|
103
|
+
}, [useAutoConnectLoading, hasStartedConnecting, setIsAuthenticating]);
|
|
104
104
|
|
|
105
105
|
// Ensure isAuthenticating stays true until we're fully ready
|
|
106
106
|
useEffect(() => {
|
|
@@ -30,7 +30,7 @@ export const useOneBalance = (bypassCache = false) => {
|
|
|
30
30
|
|
|
31
31
|
const { data, isLoading, refetch } = useQuery({
|
|
32
32
|
queryKey: ["balances", address, `testnet-${sprinterTestnet}`],
|
|
33
|
-
queryFn: () => fetchBalances(address
|
|
33
|
+
queryFn: () => fetchBalances(address, sprinterTestnet),
|
|
34
34
|
enabled: !!address,
|
|
35
35
|
staleTime: 1000 * 60 * 1, // 1 minute
|
|
36
36
|
gcTime: 1000 * 60 * 5, // 5 minutes (renamed from cacheTime in v5)
|
|
@@ -47,26 +47,33 @@ export function useQueryB3<
|
|
|
47
47
|
const [error, setError] = useState<Error | null>(null);
|
|
48
48
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
|
49
49
|
|
|
50
|
-
const runQuery = useCallback(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
50
|
+
const runQuery = useCallback(
|
|
51
|
+
async (queryParams: ParamsType<T, M>) => {
|
|
52
|
+
setIsLoading(true);
|
|
53
|
+
try {
|
|
54
|
+
// Cast the service to avoid TypeScript issues with dynamic services
|
|
55
|
+
const serviceInstance = app.service(service) as any;
|
|
56
|
+
const result = await serviceInstance[method](queryParams);
|
|
57
|
+
setData(result); // Now `data` is correctly typed!
|
|
58
|
+
return result;
|
|
59
|
+
} catch (err) {
|
|
60
|
+
setError(err instanceof Error ? err : new Error("An error occurred"));
|
|
61
|
+
} finally {
|
|
62
|
+
setIsLoading(false);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
[service, method],
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
// Serialize params for stable comparison
|
|
69
|
+
const paramsJson = JSON.stringify(params);
|
|
64
70
|
|
|
65
71
|
useEffect(() => {
|
|
66
72
|
if (fetchInitially) {
|
|
67
73
|
runQuery(params);
|
|
68
74
|
}
|
|
69
|
-
|
|
75
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
76
|
+
}, [runQuery, fetchInitially, paramsJson]);
|
|
70
77
|
|
|
71
78
|
return { data, error, isLoading, runQuery };
|
|
72
79
|
}
|
|
@@ -47,26 +47,33 @@ export function useQueryBSMNT<
|
|
|
47
47
|
const [error, setError] = useState<Error | null>(null);
|
|
48
48
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
|
49
49
|
|
|
50
|
-
const runQuery = useCallback(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
50
|
+
const runQuery = useCallback(
|
|
51
|
+
async (queryParams: ParamsType<T, M>) => {
|
|
52
|
+
setIsLoading(true);
|
|
53
|
+
try {
|
|
54
|
+
// Cast the service to avoid TypeScript issues with dynamic services
|
|
55
|
+
const serviceInstance = app.service(service) as any;
|
|
56
|
+
const result = await serviceInstance[method](queryParams);
|
|
57
|
+
setData(result); // Now `data` is correctly typed!
|
|
58
|
+
return result;
|
|
59
|
+
} catch (err) {
|
|
60
|
+
setError(err instanceof Error ? err : new Error("An error occurred"));
|
|
61
|
+
} finally {
|
|
62
|
+
setIsLoading(false);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
[service, method],
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
// Serialize params for stable comparison
|
|
69
|
+
const paramsJson = JSON.stringify(params);
|
|
64
70
|
|
|
65
71
|
useEffect(() => {
|
|
66
72
|
if (fetchInitially) {
|
|
67
73
|
runQuery(params);
|
|
68
74
|
}
|
|
69
|
-
|
|
75
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
76
|
+
}, [runQuery, fetchInitially, paramsJson]);
|
|
70
77
|
|
|
71
78
|
return { data, error, isLoading, runQuery };
|
|
72
79
|
}
|
|
@@ -7,6 +7,7 @@ import { viemToThirdwebChain } from "@b3dotfun/sdk/shared/constants/chains/b3Cha
|
|
|
7
7
|
import { getChainById } from "@b3dotfun/sdk/shared/utils/chains";
|
|
8
8
|
import { client } from "@b3dotfun/sdk/shared/utils/thirdweb";
|
|
9
9
|
import { getWalletBalance } from "thirdweb/wallets";
|
|
10
|
+
import invariant from "invariant";
|
|
10
11
|
|
|
11
12
|
type GetWalletBalanceResult = {
|
|
12
13
|
value: bigint;
|
|
@@ -51,10 +52,12 @@ export function useTokenBalancesByChain({
|
|
|
51
52
|
// Fetch native token balances
|
|
52
53
|
Promise.all(
|
|
53
54
|
chainIds.map(async chainId => {
|
|
55
|
+
const chain = getChainById(chainId);
|
|
56
|
+
invariant(chain, "Chain is required");
|
|
54
57
|
const walletBalance = await getWalletBalance({
|
|
55
58
|
address,
|
|
56
59
|
client,
|
|
57
|
-
chain: viemToThirdwebChain(
|
|
60
|
+
chain: viemToThirdwebChain(chain),
|
|
58
61
|
});
|
|
59
62
|
|
|
60
63
|
return {
|
|
@@ -69,7 +69,7 @@ export function useTokenFromUrl({ defaultToken, prefix }: UseTokenFromUrlOptions
|
|
|
69
69
|
|
|
70
70
|
const { data: tokenInfo, isError } = useQuery({
|
|
71
71
|
queryKey: ["tokenInfo", network, currencyParam],
|
|
72
|
-
queryFn: () => fetchTokenInfo(network, currencyParam
|
|
72
|
+
queryFn: () => fetchTokenInfo(network, currencyParam || ""),
|
|
73
73
|
enabled: shouldFetchToken,
|
|
74
74
|
staleTime: Infinity,
|
|
75
75
|
gcTime: Infinity,
|
|
@@ -84,7 +84,7 @@ export function useTokenFromUrl({ defaultToken, prefix }: UseTokenFromUrlOptions
|
|
|
84
84
|
if (isError || !tokenInfo) {
|
|
85
85
|
return {
|
|
86
86
|
...defaultToken,
|
|
87
|
-
address: currencyParam
|
|
87
|
+
address: currencyParam || "",
|
|
88
88
|
chainId: Number(chainIdParam),
|
|
89
89
|
};
|
|
90
90
|
}
|
|
@@ -8,7 +8,7 @@ import { toast } from "sonner";
|
|
|
8
8
|
import { prepareTransaction, sendTransaction as twSendTransaction } from "thirdweb";
|
|
9
9
|
import { useActiveWallet } from "thirdweb/react";
|
|
10
10
|
import { isAddress } from "viem";
|
|
11
|
-
import { useSwitchChain
|
|
11
|
+
import { useSwitchChain } from "wagmi";
|
|
12
12
|
import { useB3 } from "../components";
|
|
13
13
|
import { useAccountWallet } from "./useAccountWallet";
|
|
14
14
|
|
|
@@ -27,7 +27,6 @@ const partnerId = String(
|
|
|
27
27
|
invariant(partnerId, "Partner ID is required");
|
|
28
28
|
|
|
29
29
|
export function useUnifiedChainSwitchAndExecute() {
|
|
30
|
-
const { data: walletClient } = useWalletClient();
|
|
31
30
|
const { switchChainAsync } = useSwitchChain();
|
|
32
31
|
const [isSwitchingOrExecuting, setIsSwitchingOrExecuting] = useState(false);
|
|
33
32
|
const activeWallet = useActiveWallet();
|
|
@@ -122,7 +121,7 @@ export function useUnifiedChainSwitchAndExecute() {
|
|
|
122
121
|
setIsSwitchingOrExecuting(false);
|
|
123
122
|
}
|
|
124
123
|
},
|
|
125
|
-
[
|
|
124
|
+
[connectedEOAWallet, activeWallet, switchChainAsync],
|
|
126
125
|
);
|
|
127
126
|
|
|
128
127
|
// Handle AA wallet transaction (no chain switch needed for AA)
|
|
@@ -19,7 +19,7 @@ export interface AssetBalance {
|
|
|
19
19
|
chainBalances: ChainBalance[];
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export const fetchBalances = async (address: string, testnet?: boolean): Promise<AssetBalance[]> => {
|
|
22
|
+
export const fetchBalances = async (address: string | undefined, testnet?: boolean): Promise<AssetBalance[]> => {
|
|
23
23
|
if (!address) return [];
|
|
24
24
|
|
|
25
25
|
const assetsResponse = await fetch(`${getSprinterBaseUrl(testnet)}/assets/fungible`);
|