@b3dotfun/sdk 0.1.70-alpha.18 → 0.1.70-alpha.19
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/README.md +3 -3
- package/dist/cjs/anyspend/constants/rpc.d.ts +1 -0
- package/dist/cjs/anyspend/constants/rpc.js +3 -1
- package/dist/cjs/anyspend/react/components/AnySpendDeposit.d.ts +1 -3
- package/dist/cjs/anyspend/react/components/AnySpendDeposit.js +14 -12
- package/dist/cjs/anyspend/react/components/AnySpendStakeB3.js +32 -13
- package/dist/cjs/anyspend/react/components/AnySpendStakeB3ExactIn.js +32 -10
- package/dist/cjs/anyspend/react/components/checkout/CryptoPayPanel.js +16 -8
- package/dist/cjs/anyspend/react/components/common/TokenBalance.js +4 -5
- package/dist/cjs/anyspend/react/hooks/useSigMint.d.ts +1 -1
- package/dist/cjs/anyspend/utils/chain.d.ts +45 -0
- package/dist/cjs/anyspend/utils/chain.js +51 -2
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +1 -2
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +2 -2
- package/dist/cjs/global-account/react/components/B3Provider/RelayKitProviderWrapper.d.ts +1 -2
- package/dist/cjs/global-account/react/components/B3Provider/RelayKitProviderWrapper.js +4 -5
- package/dist/cjs/global-account/react/components/ManageAccount/ContentTokens.js +23 -15
- package/dist/cjs/global-account/react/components/ManageAccount/NFTContent.js +2 -2
- package/dist/cjs/global-account/react/components/ManageAccount/ProfileSection.js +8 -6
- package/dist/cjs/global-account/react/components/ManageAccount/TokenContent.js +17 -8
- package/dist/cjs/global-account/react/components/Send/Send.js +15 -11
- package/dist/cjs/global-account/react/hooks/index.d.ts +2 -2
- package/dist/cjs/global-account/react/hooks/index.js +7 -8
- package/dist/cjs/global-account/react/hooks/useAuth.d.ts +2 -1
- package/dist/cjs/global-account/react/hooks/useAuth.js +1 -0
- package/dist/cjs/global-account/react/hooks/useAuthentication.d.ts +2 -1
- package/dist/cjs/global-account/react/hooks/useAuthentication.js +1 -0
- package/dist/cjs/global-account/react/hooks/useFirstEOA.d.ts +4 -7666
- package/dist/cjs/global-account/react/hooks/useFirstEOA.js +1 -0
- package/dist/cjs/global-account/react/hooks/usePortfolioBalance.d.ts +15 -0
- package/dist/cjs/global-account/react/hooks/usePortfolioBalance.js +76 -0
- package/dist/cjs/global-account/react/hooks/usePortfolioCollectibles.d.ts +12 -0
- package/dist/cjs/global-account/react/hooks/usePortfolioCollectibles.js +178 -0
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +0 -2
- package/dist/cjs/global-account/react/utils/createWagmiConfig.d.ts +2 -2
- package/dist/cjs/shared/constants/chains/b3Chain.d.ts +24 -0
- package/dist/cjs/shared/constants/chains/supported.d.ts +4 -4
- package/dist/cjs/shared/constants/index.d.ts +4 -0
- package/dist/cjs/shared/utils/zerionPositions.d.ts +96 -0
- package/dist/cjs/shared/utils/zerionPositions.js +186 -0
- package/dist/cjs/wallet/utils/createWalletConfig.d.ts +2 -2
- package/dist/esm/anyspend/constants/rpc.d.ts +1 -0
- package/dist/esm/anyspend/constants/rpc.js +2 -0
- package/dist/esm/anyspend/react/components/AnySpendDeposit.d.ts +1 -3
- package/dist/esm/anyspend/react/components/AnySpendDeposit.js +15 -13
- package/dist/esm/anyspend/react/components/AnySpendStakeB3.js +33 -14
- package/dist/esm/anyspend/react/components/AnySpendStakeB3ExactIn.js +33 -11
- package/dist/esm/anyspend/react/components/checkout/CryptoPayPanel.js +18 -10
- package/dist/esm/anyspend/react/components/common/TokenBalance.js +6 -7
- package/dist/esm/anyspend/react/hooks/useSigMint.d.ts +1 -1
- package/dist/esm/anyspend/utils/chain.d.ts +45 -0
- package/dist/esm/anyspend/utils/chain.js +50 -3
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +1 -2
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +2 -2
- package/dist/esm/global-account/react/components/B3Provider/RelayKitProviderWrapper.d.ts +1 -2
- package/dist/esm/global-account/react/components/B3Provider/RelayKitProviderWrapper.js +4 -5
- package/dist/esm/global-account/react/components/ManageAccount/ContentTokens.js +24 -16
- package/dist/esm/global-account/react/components/ManageAccount/NFTContent.js +3 -3
- package/dist/esm/global-account/react/components/ManageAccount/ProfileSection.js +9 -7
- package/dist/esm/global-account/react/components/ManageAccount/TokenContent.js +18 -9
- package/dist/esm/global-account/react/components/Send/Send.js +16 -12
- package/dist/esm/global-account/react/hooks/index.d.ts +2 -2
- package/dist/esm/global-account/react/hooks/index.js +2 -2
- package/dist/esm/global-account/react/hooks/useAuth.d.ts +2 -1
- package/dist/esm/global-account/react/hooks/useAuth.js +1 -0
- package/dist/esm/global-account/react/hooks/useAuthentication.d.ts +2 -1
- package/dist/esm/global-account/react/hooks/useAuthentication.js +1 -0
- package/dist/esm/global-account/react/hooks/useFirstEOA.d.ts +4 -7666
- package/dist/esm/global-account/react/hooks/useFirstEOA.js +1 -0
- package/dist/esm/global-account/react/hooks/usePortfolioBalance.d.ts +15 -0
- package/dist/esm/global-account/react/hooks/usePortfolioBalance.js +72 -0
- package/dist/esm/global-account/react/hooks/usePortfolioCollectibles.d.ts +12 -0
- package/dist/esm/global-account/react/hooks/usePortfolioCollectibles.js +175 -0
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +0 -2
- package/dist/esm/global-account/react/utils/createWagmiConfig.d.ts +2 -2
- package/dist/esm/shared/constants/chains/b3Chain.d.ts +24 -0
- package/dist/esm/shared/constants/chains/supported.d.ts +4 -4
- package/dist/esm/shared/constants/index.d.ts +4 -0
- package/dist/esm/shared/utils/zerionPositions.d.ts +96 -0
- package/dist/esm/shared/utils/zerionPositions.js +178 -0
- package/dist/esm/wallet/utils/createWalletConfig.d.ts +2 -2
- package/dist/types/anyspend/constants/rpc.d.ts +1 -0
- package/dist/types/anyspend/react/components/AnySpendDeposit.d.ts +1 -3
- package/dist/types/anyspend/react/hooks/useSigMint.d.ts +1 -1
- package/dist/types/anyspend/utils/chain.d.ts +45 -0
- package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +1 -2
- package/dist/types/global-account/react/components/B3Provider/RelayKitProviderWrapper.d.ts +1 -2
- package/dist/types/global-account/react/hooks/index.d.ts +2 -2
- package/dist/types/global-account/react/hooks/useAuth.d.ts +2 -1
- package/dist/types/global-account/react/hooks/useAuthentication.d.ts +2 -1
- package/dist/types/global-account/react/hooks/useFirstEOA.d.ts +4 -7666
- package/dist/types/global-account/react/hooks/usePortfolioBalance.d.ts +15 -0
- package/dist/types/global-account/react/hooks/usePortfolioCollectibles.d.ts +12 -0
- package/dist/types/global-account/react/stores/useModalStore.d.ts +0 -2
- package/dist/types/global-account/react/utils/createWagmiConfig.d.ts +2 -2
- package/dist/types/shared/constants/chains/b3Chain.d.ts +24 -0
- package/dist/types/shared/constants/chains/supported.d.ts +4 -4
- package/dist/types/shared/constants/index.d.ts +4 -0
- package/dist/types/shared/utils/zerionPositions.d.ts +96 -0
- package/dist/types/wallet/utils/createWalletConfig.d.ts +2 -2
- package/node_modules/@b3/chain-registry/chains.json +29 -1
- package/node_modules/@b3/chain-registry/package.json +18 -2
- package/package.json +2 -2
- package/src/anyspend/README.md +2 -2
- package/src/anyspend/constants/rpc.ts +2 -0
- package/src/anyspend/docs/components.md +6 -6
- package/src/anyspend/docs/contributing.md +1 -1
- package/src/anyspend/docs/hooks.md +3 -3
- package/src/anyspend/docs/installation.md +2 -2
- package/src/anyspend/react/components/AnySpendDeposit.tsx +26 -19
- package/src/anyspend/react/components/AnySpendStakeB3.tsx +55 -14
- package/src/anyspend/react/components/AnySpendStakeB3ExactIn.tsx +55 -11
- package/src/anyspend/react/components/__tests__/QRDeposit.test.tsx +3 -4
- package/src/anyspend/react/components/checkout/CryptoPayPanel.tsx +25 -12
- package/src/anyspend/react/components/common/TokenBalance.tsx +10 -7
- package/src/anyspend/utils/__tests__/deprecatedChains.test.ts +44 -0
- package/src/anyspend/utils/__tests__/toRegistryChainId.test.ts +17 -0
- package/src/anyspend/utils/chain.ts +53 -2
- package/src/global-account/react/components/B3Provider/B3Provider.tsx +1 -3
- package/src/global-account/react/components/B3Provider/RelayKitProviderWrapper.tsx +4 -11
- package/src/global-account/react/components/ManageAccount/ContentTokens.tsx +50 -21
- package/src/global-account/react/components/ManageAccount/NFTContent.tsx +5 -3
- package/src/global-account/react/components/ManageAccount/ProfileSection.tsx +10 -6
- package/src/global-account/react/components/ManageAccount/TokenContent.tsx +22 -9
- package/src/global-account/react/components/Send/Send.tsx +39 -15
- package/src/global-account/react/hooks/index.ts +2 -2
- package/src/global-account/react/hooks/useAuth.ts +3 -2
- package/src/global-account/react/hooks/useAuthentication.ts +3 -2
- package/src/global-account/react/hooks/useFirstEOA.tsx +9 -2
- package/src/global-account/react/hooks/usePortfolioBalance.ts +89 -0
- package/src/global-account/react/hooks/usePortfolioCollectibles.ts +212 -0
- package/src/global-account/react/stores/useModalStore.ts +0 -2
- package/src/shared/constants/index.ts +8 -0
- package/src/shared/utils/__tests__/zerionPositions.test.ts +226 -0
- package/src/shared/utils/zerionPositions.ts +244 -0
- package/dist/cjs/global-account/react/hooks/useSimBalance.d.ts +0 -59
- package/dist/cjs/global-account/react/hooks/useSimBalance.js +0 -98
- package/dist/cjs/global-account/react/hooks/useSimCollectibles.d.ts +0 -45
- package/dist/cjs/global-account/react/hooks/useSimCollectibles.js +0 -190
- package/dist/cjs/global-account/react/utils/simdune.d.ts +0 -7
- package/dist/cjs/global-account/react/utils/simdune.js +0 -21
- package/dist/esm/global-account/react/hooks/useSimBalance.d.ts +0 -59
- package/dist/esm/global-account/react/hooks/useSimBalance.js +0 -93
- package/dist/esm/global-account/react/hooks/useSimCollectibles.d.ts +0 -45
- package/dist/esm/global-account/react/hooks/useSimCollectibles.js +0 -187
- package/dist/esm/global-account/react/utils/simdune.d.ts +0 -7
- package/dist/esm/global-account/react/utils/simdune.js +0 -17
- package/dist/types/global-account/react/hooks/useSimBalance.d.ts +0 -59
- package/dist/types/global-account/react/hooks/useSimCollectibles.d.ts +0 -45
- package/dist/types/global-account/react/utils/simdune.d.ts +0 -7
- package/node_modules/@b3/chain-registry/src/index.ts +0 -169
- package/node_modules/@b3/chain-registry/tsconfig.json +0 -16
- package/src/global-account/react/hooks/useSimBalance.ts +0 -164
- package/src/global-account/react/hooks/useSimCollectibles.ts +0 -238
- package/src/global-account/react/utils/simdune.ts +0 -20
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
toast,
|
|
9
9
|
useHasMounted,
|
|
10
10
|
useModalStore,
|
|
11
|
-
|
|
11
|
+
usePortfolioBalance,
|
|
12
12
|
useUnifiedChainSwitchAndExecute,
|
|
13
13
|
} from "@b3dotfun/sdk/global-account/react";
|
|
14
14
|
import { PUBLIC_BASE_RPC_URL } from "@b3dotfun/sdk/shared/constants";
|
|
@@ -75,12 +75,32 @@ export function AnySpendStakeB3({
|
|
|
75
75
|
const { address } = useAccount();
|
|
76
76
|
const { switchChainAndExecute, isSwitchingOrExecuting } = useUnifiedChainSwitchAndExecute();
|
|
77
77
|
|
|
78
|
-
// Fetch B3 token balance
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
// Fetch B3 token balance. `isBalanceUnknown` must gate every use of `b3RawBalance`: a failed read
|
|
79
|
+
// yields the same 0 as an empty wallet, and acting on it pushes a holder into the swap flow to
|
|
80
|
+
// buy a token they already have.
|
|
81
|
+
const {
|
|
82
|
+
data: balances,
|
|
83
|
+
isLoading: isBalanceLoading,
|
|
84
|
+
isError: isBalanceError,
|
|
85
|
+
refetch: refetchBalance,
|
|
86
|
+
} = usePortfolioBalance(address, [base.id]);
|
|
87
|
+
// Guarded on `address`: with no wallet connected the query never runs, and a query that was
|
|
88
|
+
// never asked is not a query that failed. Without this the screen tells a visitor their
|
|
89
|
+
// balance is unavailable and refuses to continue, when they simply have not connected yet.
|
|
90
|
+
const isBalanceUnknown = Boolean(address) && (isBalanceError || (!isBalanceLoading && balances === undefined));
|
|
91
|
+
const b3RawBalanceStr = balances?.find(b => eqci(b.address, B3_TOKEN.address))?.amount || "0";
|
|
81
92
|
const b3RawBalance = BigInt(b3RawBalanceStr);
|
|
82
93
|
const b3Balance = formatTokenAmount(b3RawBalance, B3_TOKEN.decimals);
|
|
83
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Whether the wallet demonstrably holds enough B3 to stake `amountRaw` directly.
|
|
97
|
+
*
|
|
98
|
+
* False while the balance is unknown — but callers must not read that as a shortfall. An unknown
|
|
99
|
+
* balance is neither enough nor short, and the two need different UI: a shortfall offers the swap
|
|
100
|
+
* flow, an unknown offers a retry. Check `isBalanceUnknown` first.
|
|
101
|
+
*/
|
|
102
|
+
const hasEnoughB3 = (amountRaw: string) => !isBalanceUnknown && BigInt(amountRaw || "0") <= b3RawBalance;
|
|
103
|
+
|
|
84
104
|
// State for direct staking flow
|
|
85
105
|
const [isStaking, setIsStaking] = useState(false);
|
|
86
106
|
const [stakingTxHash, setStakingTxHash] = useState<string>("");
|
|
@@ -273,10 +293,12 @@ export function AnySpendStakeB3({
|
|
|
273
293
|
return;
|
|
274
294
|
}
|
|
275
295
|
|
|
276
|
-
|
|
277
|
-
|
|
296
|
+
if (isBalanceUnknown) {
|
|
297
|
+
toast.error("Can't read your B3 balance right now. Please try again.");
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
278
300
|
|
|
279
|
-
if (
|
|
301
|
+
if (hasEnoughB3(userStakeAmount)) {
|
|
280
302
|
// User has enough B3, proceed with direct staking
|
|
281
303
|
handleDirectStaking();
|
|
282
304
|
} else {
|
|
@@ -334,10 +356,9 @@ export function AnySpendStakeB3({
|
|
|
334
356
|
transition={{ duration: 0.3, delay: 0.1, ease: "easeInOut" }}
|
|
335
357
|
>
|
|
336
358
|
<h2 className="font-sf-rounded font-neue-montreal-medium mb-1 text-center text-2xl font-semibold">
|
|
337
|
-
{(
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
})()}
|
|
359
|
+
{isBalanceUnknown || !debouncedAmount || hasEnoughB3(debouncedUserStakeAmount)
|
|
360
|
+
? "Stake B3"
|
|
361
|
+
: "Swap & Stake B3"}
|
|
341
362
|
</h2>
|
|
342
363
|
</motion.div>
|
|
343
364
|
</div>
|
|
@@ -356,7 +377,14 @@ export function AnySpendStakeB3({
|
|
|
356
377
|
<div className="flex items-center justify-between">
|
|
357
378
|
<p className="text-as-primary/70 text-sm font-medium">I want to stake</p>
|
|
358
379
|
<span className="text-as-primary/50 flex items-center gap-1 text-sm">
|
|
359
|
-
Available:
|
|
380
|
+
Available:{" "}
|
|
381
|
+
{isBalanceLoading ? (
|
|
382
|
+
<Loader2 className="h-3 w-3 animate-spin" />
|
|
383
|
+
) : isBalanceUnknown ? (
|
|
384
|
+
"unavailable"
|
|
385
|
+
) : (
|
|
386
|
+
`${b3Balance} B3`
|
|
387
|
+
)}
|
|
360
388
|
</span>
|
|
361
389
|
</div>
|
|
362
390
|
</div>
|
|
@@ -379,9 +407,22 @@ export function AnySpendStakeB3({
|
|
|
379
407
|
|
|
380
408
|
<div className="mt-4">
|
|
381
409
|
{(() => {
|
|
382
|
-
|
|
410
|
+
// An unreadable balance is not a shortfall, so it must not open the swap upsell —
|
|
411
|
+
// that would sell a swap to someone who may already hold the tokens.
|
|
412
|
+
if (isBalanceUnknown) {
|
|
413
|
+
return (
|
|
414
|
+
<div className="bg-as-brand/10 flex flex-col items-center gap-2 rounded-lg p-4 pb-5">
|
|
415
|
+
<p className="text-as-primary/70 text-sm font-medium">
|
|
416
|
+
We couldn't read your B3 balance just now.
|
|
417
|
+
</p>
|
|
418
|
+
<Button variant="ghost" onClick={() => refetchBalance()} className="text-as-primary text-sm">
|
|
419
|
+
Try again
|
|
420
|
+
</Button>
|
|
421
|
+
</div>
|
|
422
|
+
);
|
|
423
|
+
}
|
|
383
424
|
|
|
384
|
-
if (!
|
|
425
|
+
if (!hasEnoughB3(debouncedUserStakeAmount) || !debouncedAmount) {
|
|
385
426
|
return (
|
|
386
427
|
<div className="bg-as-brand/10 flex flex-col items-center gap-2 rounded-lg p-4 pb-5">
|
|
387
428
|
<div className="flex items-center justify-center gap-2">
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
toast,
|
|
10
10
|
useHasMounted,
|
|
11
11
|
useModalStore,
|
|
12
|
-
|
|
12
|
+
usePortfolioBalance,
|
|
13
13
|
useUnifiedChainSwitchAndExecute,
|
|
14
14
|
} from "@b3dotfun/sdk/global-account/react";
|
|
15
15
|
import { PUBLIC_BASE_RPC_URL } from "@b3dotfun/sdk/shared/constants";
|
|
@@ -82,12 +82,32 @@ export function AnySpendStakeB3ExactIn({
|
|
|
82
82
|
const { address } = useAccount();
|
|
83
83
|
const { switchChainAndExecute, isSwitchingOrExecuting } = useUnifiedChainSwitchAndExecute();
|
|
84
84
|
|
|
85
|
-
// Fetch B3 token balance
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
// Fetch B3 token balance. `isBalanceUnknown` must gate every use of `b3RawBalance`: a failed read
|
|
86
|
+
// yields the same 0 as an empty wallet, and acting on it pushes a holder into the swap flow to
|
|
87
|
+
// buy a token they already have.
|
|
88
|
+
const {
|
|
89
|
+
data: balances,
|
|
90
|
+
isLoading: isBalanceLoading,
|
|
91
|
+
isError: isBalanceError,
|
|
92
|
+
refetch: refetchBalance,
|
|
93
|
+
} = usePortfolioBalance(address, [base.id]);
|
|
94
|
+
// Guarded on `address`: with no wallet connected the query never runs, and a query that was
|
|
95
|
+
// never asked is not a query that failed. Without this the screen tells a visitor their
|
|
96
|
+
// balance is unavailable and refuses to continue, when they simply have not connected yet.
|
|
97
|
+
const isBalanceUnknown = Boolean(address) && (isBalanceError || (!isBalanceLoading && balances === undefined));
|
|
98
|
+
const b3RawBalanceStr = balances?.find(b => eqci(b.address, B3_TOKEN.address))?.amount || "0";
|
|
88
99
|
const b3RawBalance = BigInt(b3RawBalanceStr);
|
|
89
100
|
const b3Balance = formatTokenAmount(b3RawBalance, B3_TOKEN.decimals);
|
|
90
101
|
|
|
102
|
+
/**
|
|
103
|
+
* Whether the wallet demonstrably holds enough B3 to stake `amountRaw` directly.
|
|
104
|
+
*
|
|
105
|
+
* False while the balance is unknown — but callers must not read that as a shortfall. An unknown
|
|
106
|
+
* balance is neither enough nor short, and the two need different UI: a shortfall offers the swap
|
|
107
|
+
* flow, an unknown offers a retry. Check `isBalanceUnknown` first.
|
|
108
|
+
*/
|
|
109
|
+
const hasEnoughB3 = (amountRaw: string) => !isBalanceUnknown && BigInt(amountRaw || "0") <= b3RawBalance;
|
|
110
|
+
|
|
91
111
|
// State for direct staking flow
|
|
92
112
|
const [isStaking, setIsStaking] = useState(false);
|
|
93
113
|
const [stakingTxHash, setStakingTxHash] = useState<string>("");
|
|
@@ -283,9 +303,12 @@ export function AnySpendStakeB3ExactIn({
|
|
|
283
303
|
}
|
|
284
304
|
|
|
285
305
|
// Check if user has sufficient B3 balance for direct staking
|
|
286
|
-
|
|
306
|
+
if (isBalanceUnknown) {
|
|
307
|
+
toast.error("Can't read your B3 balance right now. Please try again.");
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
287
310
|
|
|
288
|
-
if (
|
|
311
|
+
if (hasEnoughB3(userStakeAmount)) {
|
|
289
312
|
// User has enough B3, proceed with direct staking
|
|
290
313
|
handleDirectStaking();
|
|
291
314
|
} else {
|
|
@@ -353,8 +376,9 @@ export function AnySpendStakeB3ExactIn({
|
|
|
353
376
|
>
|
|
354
377
|
<h2 className="font-sf-rounded font-neue-montreal-medium mb-1 text-center text-2xl font-semibold">
|
|
355
378
|
{(() => {
|
|
356
|
-
|
|
357
|
-
|
|
379
|
+
return isBalanceUnknown || !debouncedAmount || hasEnoughB3(debouncedUserStakeAmount)
|
|
380
|
+
? "Stake B3"
|
|
381
|
+
: "Swap & Stake B3";
|
|
358
382
|
})()}
|
|
359
383
|
</h2>
|
|
360
384
|
</motion.div>
|
|
@@ -374,7 +398,14 @@ export function AnySpendStakeB3ExactIn({
|
|
|
374
398
|
<div className="flex items-center justify-between">
|
|
375
399
|
<p className="text-as-primary/70 text-sm font-medium">I want to stake</p>
|
|
376
400
|
<span className="text-as-primary/50 flex items-center gap-1 text-sm">
|
|
377
|
-
Available:
|
|
401
|
+
Available:{" "}
|
|
402
|
+
{isBalanceLoading ? (
|
|
403
|
+
<Loader2 className="h-3 w-3 animate-spin" />
|
|
404
|
+
) : isBalanceUnknown ? (
|
|
405
|
+
"unavailable"
|
|
406
|
+
) : (
|
|
407
|
+
`${b3Balance} B3`
|
|
408
|
+
)}
|
|
378
409
|
</span>
|
|
379
410
|
</div>
|
|
380
411
|
</div>
|
|
@@ -397,9 +428,22 @@ export function AnySpendStakeB3ExactIn({
|
|
|
397
428
|
|
|
398
429
|
<div className="mt-4">
|
|
399
430
|
{(() => {
|
|
400
|
-
|
|
431
|
+
// An unreadable balance is not a shortfall, so it must not open the swap upsell —
|
|
432
|
+
// that would sell a swap to someone who may already hold the tokens.
|
|
433
|
+
if (isBalanceUnknown) {
|
|
434
|
+
return (
|
|
435
|
+
<div className="bg-as-brand/10 flex flex-col items-center gap-2 rounded-lg p-4 pb-5">
|
|
436
|
+
<p className="text-as-primary/70 text-sm font-medium">
|
|
437
|
+
We couldn't read your B3 balance just now.
|
|
438
|
+
</p>
|
|
439
|
+
<Button variant="ghost" onClick={() => refetchBalance()} className="text-as-primary text-sm">
|
|
440
|
+
Try again
|
|
441
|
+
</Button>
|
|
442
|
+
</div>
|
|
443
|
+
);
|
|
444
|
+
}
|
|
401
445
|
|
|
402
|
-
if (!
|
|
446
|
+
if (!hasEnoughB3(debouncedUserStakeAmount) || !debouncedAmount) {
|
|
403
447
|
return (
|
|
404
448
|
<div className="bg-as-brand/10 flex flex-col items-center gap-2 rounded-lg p-4 pb-5">
|
|
405
449
|
<div className="flex items-center justify-center gap-2">
|
|
@@ -89,10 +89,9 @@ vi.mock("@b3dotfun/sdk/global-account/react/hooks/useAccountWallet", () => ({
|
|
|
89
89
|
useAccountWallet: () => ({ connectedEOAWallet: undefined }),
|
|
90
90
|
}));
|
|
91
91
|
|
|
92
|
-
vi.mock("@b3dotfun/sdk/global-account/react/hooks/
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
useSimTokenBalance: () => ({ data: undefined, isLoading: false }),
|
|
92
|
+
vi.mock("@b3dotfun/sdk/global-account/react/hooks/usePortfolioBalance", () => ({
|
|
93
|
+
usePortfolioBalance: () => ({ data: undefined, isLoading: false, isError: false }),
|
|
94
|
+
usePortfolioTokenBalance: () => ({ data: undefined, isLoading: false, isError: false }),
|
|
96
95
|
}));
|
|
97
96
|
|
|
98
97
|
vi.mock("@b3dotfun/sdk/global-account/react/hooks/useTokenData", () => ({
|
|
@@ -7,12 +7,12 @@ import { useAnyspendOrderAndTransactions } from "@b3dotfun/sdk/anyspend/react/ho
|
|
|
7
7
|
import { useCreateDepositFirstOrder } from "@b3dotfun/sdk/anyspend/react/hooks/useCreateDepositFirstOrder";
|
|
8
8
|
import { useOnOrderSuccess } from "@b3dotfun/sdk/anyspend/react/hooks/useOnOrderSuccess";
|
|
9
9
|
import { ALL_CHAINS, RELAY_SOLANA_MAINNET_CHAIN_ID, getAvailableChainIds } from "@b3dotfun/sdk/anyspend";
|
|
10
|
-
import { getPaymentUrl } from "@b3dotfun/sdk/anyspend/utils/chain";
|
|
10
|
+
import { getPaymentUrl, toRegistryChainId } from "@b3dotfun/sdk/anyspend/utils/chain";
|
|
11
11
|
import { isNativeToken } from "@b3dotfun/sdk/anyspend/utils/token";
|
|
12
12
|
import {
|
|
13
13
|
useAccountWallet,
|
|
14
14
|
useIsMobile,
|
|
15
|
-
|
|
15
|
+
usePortfolioTokenBalance,
|
|
16
16
|
useTokenData,
|
|
17
17
|
useUnifiedChainSwitchAndExecute,
|
|
18
18
|
} from "@b3dotfun/sdk/global-account/react";
|
|
@@ -116,13 +116,21 @@ export function CryptoPayPanel({
|
|
|
116
116
|
? "native"
|
|
117
117
|
: selectedSrcToken.address
|
|
118
118
|
: undefined;
|
|
119
|
-
|
|
119
|
+
// `selectedSrcChainId` is Relay-numbered; balance rows are keyed by the chain registry's id.
|
|
120
|
+
const { data: balanceRow, isError: isBalanceError } = usePortfolioTokenBalance(
|
|
121
|
+
effectiveAddress,
|
|
122
|
+
tokenAddress,
|
|
123
|
+
toRegistryChainId(selectedSrcChainId),
|
|
124
|
+
);
|
|
120
125
|
|
|
121
126
|
const balance = useMemo(() => {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
127
|
+
if (!balanceRow?.amount) return { raw: BigInt(0), formatted: "0", decimals: 18 };
|
|
128
|
+
return {
|
|
129
|
+
raw: BigInt(balanceRow.amount),
|
|
130
|
+
formatted: formatTokenAmount(BigInt(balanceRow.amount), balanceRow.decimals),
|
|
131
|
+
decimals: balanceRow.decimals,
|
|
132
|
+
};
|
|
133
|
+
}, [balanceRow]);
|
|
126
134
|
|
|
127
135
|
const srcAmount = useMemo(() => {
|
|
128
136
|
if (isSameToken) return totalAmount;
|
|
@@ -134,7 +142,9 @@ export function CryptoPayPanel({
|
|
|
134
142
|
return formatTokenAmount(BigInt(srcAmount || "0"), selectedSrcToken.decimals || 18);
|
|
135
143
|
}, [srcAmount, selectedSrcToken]);
|
|
136
144
|
|
|
137
|
-
|
|
145
|
+
// A failed balance read must not masquerade as a shortfall: it would disable Pay and tell a
|
|
146
|
+
// funded user they are short. Unknown blocks auto-pay but leaves the manual path open.
|
|
147
|
+
const hasEnoughBalance = !isBalanceError && balance.raw >= BigInt(srcAmount || "0");
|
|
138
148
|
|
|
139
149
|
/* ------------------------------------------------------------------ */
|
|
140
150
|
/* Destination token object (shared by both flows) */
|
|
@@ -385,7 +395,8 @@ export function CryptoPayPanel({
|
|
|
385
395
|
|
|
386
396
|
const isLoading = isLoadingAnyspendQuote;
|
|
387
397
|
const isPending = isCreatingSwapOrder || isSendingDeposit || isWaitingForExecution;
|
|
388
|
-
const canPay =
|
|
398
|
+
const canPay =
|
|
399
|
+
connectedAddress && selectedSrcToken && (hasEnoughBalance || isBalanceError) && !isLoading && !isPending;
|
|
389
400
|
|
|
390
401
|
const chainName = ALL_CHAINS[selectedSrcChainId]?.name || "the specified chain";
|
|
391
402
|
const chainLogoUrl = ALL_CHAINS[selectedSrcChainId]?.logoUrl;
|
|
@@ -494,7 +505,7 @@ export function CryptoPayPanel({
|
|
|
494
505
|
</div>
|
|
495
506
|
</motion.div>
|
|
496
507
|
|
|
497
|
-
{/* ----
|
|
508
|
+
{/* ---- Balance warning ---- */}
|
|
498
509
|
<AnimatePresence>
|
|
499
510
|
{connectedAddress && selectedSrcToken && !hasEnoughBalance && !isLoading && (
|
|
500
511
|
<motion.p
|
|
@@ -503,9 +514,11 @@ export function CryptoPayPanel({
|
|
|
503
514
|
animate={{ opacity: 1, height: "auto" }}
|
|
504
515
|
exit={{ opacity: 0, height: 0 }}
|
|
505
516
|
transition={{ duration: 0.2, ease: "easeOut" }}
|
|
506
|
-
className=
|
|
517
|
+
className={`text-center text-sm ${isBalanceError ? "text-as-primary/50" : "text-red-500"}`}
|
|
507
518
|
>
|
|
508
|
-
|
|
519
|
+
{isBalanceError
|
|
520
|
+
? `Couldn't check your ${selectedSrcToken.symbol} balance`
|
|
521
|
+
: `Insufficient ${selectedSrcToken.symbol} balance`}
|
|
509
522
|
</motion.p>
|
|
510
523
|
)}
|
|
511
524
|
</AnimatePresence>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { components } from "@b3dotfun/sdk/anyspend/types/api";
|
|
2
|
-
import { getNativeRequired } from "@b3dotfun/sdk/anyspend/utils/chain";
|
|
2
|
+
import { getNativeRequired, toRegistryChainId } from "@b3dotfun/sdk/anyspend/utils/chain";
|
|
3
3
|
import { isNativeToken } from "@b3dotfun/sdk/anyspend/utils/token";
|
|
4
|
-
import {
|
|
4
|
+
import { usePortfolioTokenBalance } from "@b3dotfun/sdk/global-account/react";
|
|
5
5
|
import { formatTokenAmount } from "@b3dotfun/sdk/shared/utils/number";
|
|
6
6
|
import { useMemo } from "react";
|
|
7
7
|
import { formatUnits } from "viem";
|
|
@@ -15,11 +15,14 @@ export function TokenBalance({
|
|
|
15
15
|
walletAddress: string | undefined;
|
|
16
16
|
onChangeInput: (value: string) => void;
|
|
17
17
|
}) {
|
|
18
|
-
|
|
19
|
-
const {
|
|
18
|
+
// `token.chainId` is Relay-numbered; balance rows are keyed by the chain registry's id.
|
|
19
|
+
const {
|
|
20
|
+
data: balance,
|
|
21
|
+
isLoading,
|
|
22
|
+
isError,
|
|
23
|
+
} = usePortfolioTokenBalance(walletAddress, token.address, toRegistryChainId(token.chainId));
|
|
20
24
|
|
|
21
25
|
const { rawBalance, formattedBalance } = useMemo(() => {
|
|
22
|
-
const balance = data?.balances?.[0];
|
|
23
26
|
if (!balance?.amount) {
|
|
24
27
|
return { rawBalance: null, formattedBalance: "0" };
|
|
25
28
|
}
|
|
@@ -28,7 +31,7 @@ export function TokenBalance({
|
|
|
28
31
|
rawBalance: raw,
|
|
29
32
|
formattedBalance: formatTokenAmount(raw, balance.decimals),
|
|
30
33
|
};
|
|
31
|
-
}, [
|
|
34
|
+
}, [balance]);
|
|
32
35
|
|
|
33
36
|
const handlePercentageClick = (percentage: number) => {
|
|
34
37
|
if (!rawBalance) return;
|
|
@@ -59,7 +62,7 @@ export function TokenBalance({
|
|
|
59
62
|
{!isLoading && (
|
|
60
63
|
<>
|
|
61
64
|
<div className="text-as-primary/50 inline-flex rounded-lg text-sm">
|
|
62
|
-
{rawBalance ? `Balance: ${formattedBalance}` : `Balance: 0`}
|
|
65
|
+
{isError ? "Balance: —" : rawBalance ? `Balance: ${formattedBalance}` : `Balance: 0`}
|
|
63
66
|
</div>
|
|
64
67
|
|
|
65
68
|
{!!rawBalance && (
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deprecated chains must disappear from the chain picker but stay in ALL_CHAINS.
|
|
3
|
+
*
|
|
4
|
+
* Those are two different questions. ALL_CHAINS answers "what is this chain" and is needed to
|
|
5
|
+
* render every order that ever existed — anyspend has ~1,400 historical orders on B3 and Plume, and
|
|
6
|
+
* getChainName throws on an unknown id. getAvailableChainIds answers "can a new order use this",
|
|
7
|
+
* which is what the deprecation actually changes.
|
|
8
|
+
*/
|
|
9
|
+
import { describe, expect, it } from "vitest";
|
|
10
|
+
|
|
11
|
+
import { ALL_CHAINS, DEPRECATED_CHAIN_IDS, getAvailableChainIds, isDeprecatedChain } from "../chain";
|
|
12
|
+
|
|
13
|
+
describe("deprecated chains", () => {
|
|
14
|
+
it("covers B3 and Plume", () => {
|
|
15
|
+
expect(DEPRECATED_CHAIN_IDS).toContain(8333);
|
|
16
|
+
expect(DEPRECATED_CHAIN_IDS).toContain(98866);
|
|
17
|
+
expect(isDeprecatedChain(8333)).toBe(true);
|
|
18
|
+
expect(isDeprecatedChain(98866)).toBe(true);
|
|
19
|
+
expect(isDeprecatedChain(8453)).toBe(false);
|
|
20
|
+
expect(isDeprecatedChain(undefined)).toBe(false);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Offering a chain the API rejects lets a user pick something that then fails at order creation.
|
|
24
|
+
it("are absent from the picker in both directions", () => {
|
|
25
|
+
for (const context of ["from", "to"] as const) {
|
|
26
|
+
const available = getAvailableChainIds(context);
|
|
27
|
+
for (const chainId of DEPRECATED_CHAIN_IDS) {
|
|
28
|
+
expect(available).not.toContain(chainId);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("still leaves the picker with the chains that do work", () => {
|
|
34
|
+
expect(getAvailableChainIds("to")).toContain(8453);
|
|
35
|
+
expect(getAvailableChainIds("from")).toContain(1);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Removing the entry would make getChainName and friends throw while rendering old orders.
|
|
39
|
+
it("remain in ALL_CHAINS so historical orders still render", () => {
|
|
40
|
+
for (const chainId of DEPRECATED_CHAIN_IDS) {
|
|
41
|
+
expect(ALL_CHAINS[chainId]).toBeDefined();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { RELAY_SOLANA_MAINNET_CHAIN_ID } from "@b3dotfun/sdk/anyspend/constants";
|
|
3
|
+
import { toRegistryChainId } from "../chain";
|
|
4
|
+
import { SOLANA_CHAIN_ID } from "@b3dotfun/sdk/shared/utils/zerionPositions";
|
|
5
|
+
|
|
6
|
+
describe("toRegistryChainId", () => {
|
|
7
|
+
it("translates Relay's Solana id to the registry's", () => {
|
|
8
|
+
expect(RELAY_SOLANA_MAINNET_CHAIN_ID).not.toBe(SOLANA_CHAIN_ID);
|
|
9
|
+
expect(toRegistryChainId(RELAY_SOLANA_MAINNET_CHAIN_ID)).toBe(SOLANA_CHAIN_ID);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("leaves EVM chain ids alone — those are universal", () => {
|
|
13
|
+
for (const chainId of [1, 8453, 42161, 137, 999]) {
|
|
14
|
+
expect(toRegistryChainId(chainId)).toBe(chainId);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RELAY_SOLANA_MAINNET_CHAIN_ID } from "@b3dotfun/sdk/anyspend/constants";
|
|
2
|
+
import { SOLANA_CHAIN_ID } from "@b3dotfun/sdk/shared/utils/zerionPositions";
|
|
2
3
|
import {
|
|
3
4
|
ABSTRACT_PUBLIC_RPC,
|
|
4
5
|
ARBITRUM_PUBLIC_RPC,
|
|
@@ -10,6 +11,7 @@ import {
|
|
|
10
11
|
OPTIMISM_PUBLIC_RPC,
|
|
11
12
|
PLUME_PUBLIC_RPC,
|
|
12
13
|
POLYGON_PUBLIC_RPC,
|
|
14
|
+
ROBINHOOD_PUBLIC_RPC,
|
|
13
15
|
} from "@b3dotfun/sdk/anyspend/constants/rpc";
|
|
14
16
|
import { components } from "@b3dotfun/sdk/anyspend/types/api";
|
|
15
17
|
import { b3Viem } from "@b3dotfun/sdk/shared/constants/chains/b3Viem";
|
|
@@ -26,7 +28,7 @@ import {
|
|
|
26
28
|
Transport,
|
|
27
29
|
WalletClient,
|
|
28
30
|
} from "viem";
|
|
29
|
-
import { abstract, arbitrum, avalanche, base, bsc, mainnet, optimism, polygon } from "viem/chains";
|
|
31
|
+
import { abstract, arbitrum, avalanche, base, bsc, mainnet, optimism, polygon, robinhood } from "viem/chains";
|
|
30
32
|
import { ChainType, IBaseChain, IEVMChain, IHyperliquidChain, ISolanaChain } from "../types/chain";
|
|
31
33
|
import {
|
|
32
34
|
getAvaxToken,
|
|
@@ -272,6 +274,20 @@ export const EVM_MAINNET: Record<number, IEVMChain> = {
|
|
|
272
274
|
coingeckoName: "plume-network",
|
|
273
275
|
wethAddress: "0xea237441c92cae6fc17caaf9a7acb3f953be4bd1", // WPLUME (wrapped native)
|
|
274
276
|
},
|
|
277
|
+
[robinhood.id]: {
|
|
278
|
+
id: robinhood.id,
|
|
279
|
+
name: robinhood.name,
|
|
280
|
+
logoUrl: "https://assets.relay.link/icons/square/4663/light.png",
|
|
281
|
+
type: ChainType.EVM,
|
|
282
|
+
nativeRequired: parseEther("0.0001"),
|
|
283
|
+
canDepositNative: true,
|
|
284
|
+
defaultToken: getEthToken(robinhood.id),
|
|
285
|
+
nativeToken: getEthToken(robinhood.id),
|
|
286
|
+
viem: getCustomEvmChain(robinhood, ROBINHOOD_PUBLIC_RPC),
|
|
287
|
+
pollingInterval: 1000, // 1 second for Robinhood Chain (Arbitrum Orbit fast blocks)
|
|
288
|
+
coingeckoName: "robinhood",
|
|
289
|
+
wethAddress: "0x0bd7d308f8e1639fab988df18a8011f41eacad73", // wrapped native ETH (registry wrappedNative)
|
|
290
|
+
},
|
|
275
291
|
};
|
|
276
292
|
|
|
277
293
|
export const EVM_TESTNET: Record<number, IEVMChain> = {
|
|
@@ -356,6 +372,17 @@ export const EVM_CHAINS: Record<number, IEVMChain> = { ...EVM_MAINNET, ...EVM_TE
|
|
|
356
372
|
|
|
357
373
|
export const SOLANA_CHAINS: Record<number, ISolanaChain> = { [RELAY_SOLANA_MAINNET_CHAIN_ID]: SOLANA_MAINNET };
|
|
358
374
|
|
|
375
|
+
/**
|
|
376
|
+
* Translate a Relay-numbered chain id into the id the chain registry uses.
|
|
377
|
+
*
|
|
378
|
+
* Relay numbers Solana 792703809; every other chain shares the universal EVM id. Balance rows are
|
|
379
|
+
* keyed by the registry's id, so handing Relay's number to a balance lookup matches nothing at all
|
|
380
|
+
* — and a funded Solana wallet then reads as empty rather than as unreadable.
|
|
381
|
+
*/
|
|
382
|
+
export function toRegistryChainId(chainId: number): number {
|
|
383
|
+
return chainId === RELAY_SOLANA_MAINNET_CHAIN_ID ? SOLANA_CHAIN_ID : chainId;
|
|
384
|
+
}
|
|
385
|
+
|
|
359
386
|
export const HYPERLIQUID_CHAINS: Record<number, IHyperliquidChain> = {
|
|
360
387
|
[HYPERLIQUID_CHAIN_ID]: HYPERLIQUID_MAINNET,
|
|
361
388
|
};
|
|
@@ -680,6 +707,26 @@ export function getHyperliquidChain(chainId: number): IHyperliquidChain {
|
|
|
680
707
|
return HYPERLIQUID_CHAINS[chainId];
|
|
681
708
|
}
|
|
682
709
|
|
|
710
|
+
/**
|
|
711
|
+
* Chains AnySpend no longer accepts orders on, as either source or destination.
|
|
712
|
+
*
|
|
713
|
+
* They stay in ALL_CHAINS on purpose. That map answers "what is this chain" — name, logo, token,
|
|
714
|
+
* decimals — which every order that ever existed still needs in order to render; removing an entry
|
|
715
|
+
* would make getChainName and friends throw on historical rows. Whether new orders are accepted is
|
|
716
|
+
* this separate question.
|
|
717
|
+
*
|
|
718
|
+
* anyspend-service imports this list rather than keeping its own, so the API and the chain picker
|
|
719
|
+
* can never disagree about what is on offer.
|
|
720
|
+
*/
|
|
721
|
+
export const DEPRECATED_CHAIN_IDS: readonly number[] = [
|
|
722
|
+
8333, // B3
|
|
723
|
+
98866, // Plume
|
|
724
|
+
];
|
|
725
|
+
|
|
726
|
+
export function isDeprecatedChain(chainId?: number): boolean {
|
|
727
|
+
return chainId !== undefined && DEPRECATED_CHAIN_IDS.includes(chainId);
|
|
728
|
+
}
|
|
729
|
+
|
|
683
730
|
/**
|
|
684
731
|
* Get available chain IDs for AnySpend based on context (source or destination).
|
|
685
732
|
* Filters out chains that shouldn't be available for the given context.
|
|
@@ -695,7 +742,11 @@ export function getHyperliquidChain(chainId: number): IHyperliquidChain {
|
|
|
695
742
|
* const destChains = getAvailableChainIds("to") // [1, 8453, 137, ..., 1337]
|
|
696
743
|
*/
|
|
697
744
|
export function getAvailableChainIds(context: "from" | "to"): number[] {
|
|
698
|
-
|
|
745
|
+
// Deprecated chains are excluded from both directions: the API rejects them, so offering them in
|
|
746
|
+
// a picker would let a user select something that then fails at order creation.
|
|
747
|
+
const allChainIds = Object.values(ALL_CHAINS)
|
|
748
|
+
.map(chain => chain.id)
|
|
749
|
+
.filter(chainId => !isDeprecatedChain(chainId));
|
|
699
750
|
|
|
700
751
|
if (context === "from") {
|
|
701
752
|
// Hyperliquid is only supported as destination chain, not source chain
|
|
@@ -37,7 +37,6 @@ export function B3Provider({
|
|
|
37
37
|
environment,
|
|
38
38
|
automaticallySetFirstEoa,
|
|
39
39
|
defaultEoaProvider,
|
|
40
|
-
simDuneApiKey,
|
|
41
40
|
// deprecated since v0.0.87
|
|
42
41
|
toaster: _toaster,
|
|
43
42
|
clientType = "rest",
|
|
@@ -63,7 +62,6 @@ export function B3Provider({
|
|
|
63
62
|
automaticallySetFirstEoa?: boolean;
|
|
64
63
|
/** EIP-1193 provider to auto-connect as the default EOA wallet (e.g., Farcaster frame wallet) */
|
|
65
64
|
defaultEoaProvider?: EIP1193.EIP1193Provider;
|
|
66
|
-
simDuneApiKey?: string;
|
|
67
65
|
toaster?: {
|
|
68
66
|
position?: "top-center" | "top-right" | "bottom-center" | "bottom-right";
|
|
69
67
|
style?: React.CSSProperties;
|
|
@@ -150,7 +148,7 @@ export function B3Provider({
|
|
|
150
148
|
authStrategy={authStrategy}
|
|
151
149
|
>
|
|
152
150
|
<ToastContextConnector />
|
|
153
|
-
<RelayKitProviderWrapper
|
|
151
|
+
<RelayKitProviderWrapper>
|
|
154
152
|
{children}
|
|
155
153
|
{/* For the modal https://github.com/b3-fun/b3/blob/main/packages/sdk/src/global-account/react/components/ui/dialog.tsx#L46 */}
|
|
156
154
|
<StyleRoot id="b3-root" />
|
|
@@ -2,13 +2,7 @@ import { RelayKitProvider } from "@relayprotocol/relay-kit-ui";
|
|
|
2
2
|
import { fetchChainConfigs, MAINNET_RELAY_API, RelayChain } from "@relayprotocol/relay-sdk";
|
|
3
3
|
import { useEffect, useState } from "react";
|
|
4
4
|
|
|
5
|
-
export function RelayKitProviderWrapper({
|
|
6
|
-
children,
|
|
7
|
-
simDuneApiKey,
|
|
8
|
-
}: {
|
|
9
|
-
children: React.ReactNode;
|
|
10
|
-
simDuneApiKey?: string;
|
|
11
|
-
}) {
|
|
5
|
+
export function RelayKitProviderWrapper({ children }: { children: React.ReactNode }) {
|
|
12
6
|
const [relayChains, setRelayChains] = useState<RelayChain[]>([]);
|
|
13
7
|
|
|
14
8
|
useEffect(() => {
|
|
@@ -19,15 +13,14 @@ export function RelayKitProviderWrapper({
|
|
|
19
13
|
fetchChains();
|
|
20
14
|
}, []);
|
|
21
15
|
|
|
16
|
+
// No balance provider is configured for Relay's own token selector. Relay reads balances through
|
|
17
|
+
// its Dune integration, which we no longer hold a key for, and it accepts no substitute — so the
|
|
18
|
+
// selector lists tokens without balances rather than showing figures nothing can refresh.
|
|
22
19
|
return (
|
|
23
20
|
<RelayKitProvider
|
|
24
21
|
options={{
|
|
25
22
|
baseApiUrl: MAINNET_RELAY_API,
|
|
26
23
|
source: "anyspend",
|
|
27
|
-
duneConfig: {
|
|
28
|
-
apiKey: simDuneApiKey,
|
|
29
|
-
apiBaseUrl: "https://api.sim.dune.com",
|
|
30
|
-
},
|
|
31
24
|
chains: relayChains,
|
|
32
25
|
privateChainIds: undefined,
|
|
33
26
|
appName: "AnySpend",
|