@goodaofi/bonds-sdk 3.0.176 → 3.0.178

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/main.js +14 -537
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { forwardRef, useContext, useState, useEffect, useCallback, useMemo, useLayoutEffect, createContext as createContext$1, useRef, useId, useInsertionEffect as useInsertionEffect$1, Children, isValidElement, Fragment as Fragment$1, createElement as createElement$1, Component } from 'react';
3
3
  import { useAccount, useWaitForTransactionReceipt, useChainId, useSwitchChain, useWriteContract, useSendTransaction } from 'wagmi';
4
- import { useQueryClient, useQuery, useMutation } from '@tanstack/react-query';
4
+ import { useQueryClient, useQuery } from '@tanstack/react-query';
5
5
  import axios from 'axios';
6
6
  import { ConnectButton as ConnectButton$1 } from '@rainbow-me/rainbowkit';
7
7
 
@@ -59469,8 +59469,6 @@ const QUERY_KEYS = {
59469
59469
  USER_INFO: 'Goomoney-SDK-userInfo',
59470
59470
  USER_GOO_DATA: 'Goomoney-SDK-userGooData',
59471
59471
  PRIVATE_PARTNER_INFO: 'Goomoney-SDK-privatePartnerInfo',
59472
- GOO_ELIGIBILITY: 'Goomoney-SDK-gooEligibility',
59473
- CBBTC_BALANCE: 'Goomoney-SDK-cbBTCBalance',
59474
59472
  // used values on SDK
59475
59473
  BOND_API_STATS: 'Goomoney-SDK-bondApiStats',
59476
59474
  SDK_CONFIG: 'Goomoney-SDK-sdkConfig',
@@ -59494,9 +59492,7 @@ const QUERY_KEYS = {
59494
59492
  ACTIVE_VIEW: 'Goomoney-SDK-activeView',
59495
59493
  PRE_TGE_LIST: 'Goomoney-SDK-preTGEList',
59496
59494
  PRE_TGE_USER_BONDS: 'Goomoney-SDK-preTGEUserBonds',
59497
- USER_TOKENS_BALANCES: 'Goomoney-SDK-userTokensBalances',
59498
- REFUND_DATA: 'Goomoney-SDK-refundData',
59499
- };
59495
+ USER_TOKENS_BALANCES: 'Goomoney-SDK-userTokensBalances'};
59500
59496
 
59501
59497
  // Prod URLS. Do not make changes here
59502
59498
  const defaultUrls = {
@@ -66563,7 +66559,7 @@ const YourBondsMenu = ({ handleSort, }) => {
66563
66559
  return (jsx$2("div", { className: "bonds-menu", children: jsxs("div", { className: "table-header-container", children: [jsx$2("div", { className: "search-container", children: jsx$2(Flex$1, { sx: { width: '100%', maxWidth: '300px' } }) }), jsxs("div", { className: "headers-container", sx: { pr: ['0', '0', '0', '20px'] }, children: [jsxs("div", { className: "your-bonds-table-headers", onClick: () => handleSort('claimable'), children: ["CLAIMABLE", jsx$2(Flex$1, { sx: { ml: '5px' }, children: jsx$2(Svg, { icon: "sort", width: "12px", color: "textDisabledButton" }) })] }), jsxs("div", { className: "your-bonds-table-headers", onClick: () => handleSort('pending'), children: ["PENDING", jsx$2(Flex$1, { sx: { ml: '5px' }, children: jsx$2(Svg, { icon: "sort", width: "12px", color: "textDisabledButton" }) })] }), jsxs("div", { className: "your-bonds-table-headers", onClick: () => handleSort('terms'), children: ["TERMS", jsx$2(Flex$1, { sx: { ml: '5px' }, children: jsx$2(Svg, { icon: "sort", width: "12px", color: "textDisabledButton" }) })] }), jsx$2(Flex$1, { className: "claim-all-button-container", children: SDKConfig.referenceId === 'apebond' && jsx$2(ClaimAll, {}) })] })] }) }));
66564
66560
  };
66565
66561
 
66566
- var launchBondsABI = [
66562
+ var launchBondsABI_V2_2_0 = [
66567
66563
  {
66568
66564
  anonymous: false,
66569
66565
  inputs: [
@@ -68993,7 +68989,7 @@ const fetchPreTGEUserBonds = async (chains, tokenPrices, preTGEList, account, ap
68993
68989
  name: 'trueBillPrice',
68994
68990
  },
68995
68991
  ];
68996
- const res = await multicall(bond.chainId, launchBondsABI, calls);
68992
+ const res = await multicall(bond.chainId, launchBondsABI_V2_2_0, calls);
68997
68993
  const billId = res[0][0][0]?.toString();
68998
68994
  let userOwnedBillsData;
68999
68995
  if (billId) {
@@ -69013,7 +69009,7 @@ const fetchPreTGEUserBonds = async (chains, tokenPrices, preTGEList, account, ap
69013
69009
  params: [billId],
69014
69010
  },
69015
69011
  ];
69016
- const billData = await multicall(bond.chainId, launchBondsABI, billDataCalls);
69012
+ const billData = await multicall(bond.chainId, launchBondsABI_V2_2_0, billDataCalls);
69017
69013
  userOwnedBillsData = {
69018
69014
  address: bond.contractAddress[bond.chainId] ?? '',
69019
69015
  id: billId,
@@ -69096,7 +69092,7 @@ const PreTgeActions = ({ userBond }) => {
69096
69092
  setLoading(true);
69097
69093
  writeContractAsync({
69098
69094
  address: userBond.contractAddress[userBond.chainId],
69099
- abi: launchBondsABI,
69095
+ abi: launchBondsABI_V2_2_0,
69100
69096
  functionName: 'redeem',
69101
69097
  chain: userBond.chainId,
69102
69098
  account,
@@ -69124,7 +69120,7 @@ const PreTgeActions = ({ userBond }) => {
69124
69120
  return;
69125
69121
  writeContractAsync({
69126
69122
  address: userBond.contractAddress[userBond.chainId],
69127
- abi: launchBondsABI,
69123
+ abi: launchBondsABI_V2_2_0,
69128
69124
  functionName: 'claim',
69129
69125
  args: [userBond?.userOwnedBillsData?.id],
69130
69126
  chain: userBond.chainId,
@@ -69389,7 +69385,7 @@ const fetchGooPreTGEUserBonds = async (chains, tokenPrices, gooContracts, accoun
69389
69385
  name: 'trueBillPrice',
69390
69386
  },
69391
69387
  ];
69392
- const res = await multicall(contract.chainId, launchBondsABI, calls);
69388
+ const res = await multicall(contract.chainId, launchBondsABI_V2_2_0, calls);
69393
69389
  const billId = res[0][0][0]?.toString();
69394
69390
  let userOwnedBillsData;
69395
69391
  if (billId) {
@@ -69409,7 +69405,7 @@ const fetchGooPreTGEUserBonds = async (chains, tokenPrices, gooContracts, accoun
69409
69405
  params: [billId],
69410
69406
  },
69411
69407
  ];
69412
- const billData = await multicall(contract.chainId, launchBondsABI, billDataCalls);
69408
+ const billData = await multicall(contract.chainId, launchBondsABI_V2_2_0, billDataCalls);
69413
69409
  userOwnedBillsData = {
69414
69410
  address: contract.address,
69415
69411
  id: billId,
@@ -72521,7 +72517,7 @@ const getPreTGEBondsData = async (chain, tokenPrices, preTGEBonds, apiUrl) => {
72521
72517
  },
72522
72518
  ];
72523
72519
  });
72524
- const vals = await multicall(chainId, launchBondsABI, launchBondsCalls);
72520
+ const vals = await multicall(chainId, launchBondsABI_V2_2_0, launchBondsCalls);
72525
72521
  const chunkSize = vals.length / preTGEBonds.length;
72526
72522
  const chunkedBills = lodashExports.chunk(vals, chunkSize);
72527
72523
  const returnedBills = chunkedBills?.map((chunk, index) => {
@@ -75709,7 +75705,7 @@ const PreTGEBuyComponent = ({ bondAddress, bondChain, onDismiss, handlePurchased
75709
75705
  const args = [amount, maxPrice, address];
75710
75706
  await writeContractAsync({
75711
75707
  address: bond?.contractAddress?.[bond.chainId],
75712
- abi: launchBondsABI,
75708
+ abi: launchBondsABI_V2_2_0,
75713
75709
  functionName: 'deposit',
75714
75710
  args: args,
75715
75711
  chain: bond.chainId,
@@ -100173,7 +100169,7 @@ const YourGoo = ({ yourGoo, isLoading, isFetching, }) => {
100173
100169
  textAlign: 'center',
100174
100170
  fontWeight: 'bold',
100175
100171
  fontSize: ['12px', '12px', '14px', '14px'],
100176
- }, children: `${depositBtcTotal.toFixed(3)} BTC` })] }), jsx$2(Flex, { sx: { justifyContent: 'center', mt: '20px' }, children: jsx$2(Button, { onClick: () => (window.location.href = '/bonds?yourBonds'), children: "Claim Here" }) })] })] }, key)) : (jsx$2(Flex, { sx: {
100172
+ }, children: `${depositBtcTotal.toFixed(3)} BTC` })] }), jsx$2(Flex, { sx: { justifyContent: 'center', mt: '20px' }, children: jsx$2(Button, { onClick: () => (window.location.href = 'https://app.goo.money/bonds?yourBonds'), children: "Claim Here" }) })] })] }, key)) : (jsx$2(Flex, { sx: {
100177
100173
  flexDirection: 'column',
100178
100174
  width: '100%',
100179
100175
  background: 'white2',
@@ -100191,159 +100187,6 @@ const YourGoo = ({ yourGoo, isLoading, isFetching, }) => {
100191
100187
  }) }))] }));
100192
100188
  };
100193
100189
 
100194
- const checkEligibility = async (address) => {
100195
- if (!address)
100196
- return null;
100197
- const response = await axios.get('https://strapi-api.ape.bond/goomoney-whitelist');
100198
- if (response.data) {
100199
- // map through the tier mapping and return the tier for the address, if no address return undefined
100200
- const userTier = response.data
100201
- .filter((data) => data.wallets.map((w) => w.toLowerCase()).includes(address.toLowerCase()))
100202
- .sort((a, b) => a.tier - b.tier)[0];
100203
- return userTier?.tier ?? null;
100204
- }
100205
- else {
100206
- return null;
100207
- }
100208
- };
100209
- const addToWhitelist = async (address) => {
100210
- try {
100211
- // First, get the current tier 2 collection to get its ID and existing wallets
100212
- const response = await axios.get('https://strapi-api.ape.bond/goomoney-whitelist');
100213
- const tier2Collection = response.data.find((item) => item.tier === 2);
100214
- if (!tier2Collection) {
100215
- console.error('Tier 2 collection not found');
100216
- return false;
100217
- }
100218
- // Check if wallet is already in the list
100219
- if (tier2Collection.wallets.some((w) => w.toLowerCase() === address.toLowerCase())) {
100220
- return true;
100221
- }
100222
- // Add the new wallet to the existing wallets array
100223
- const updatedWallets = [...tier2Collection.wallets, address];
100224
- // PUT request to update the tier 2 collection with the new wallets array
100225
- await axios.put(`https://strapi-api.ape.bond/goomoney-whitelist/${tier2Collection.id}`, {
100226
- wallets: updatedWallets,
100227
- });
100228
- return true;
100229
- }
100230
- catch (error) {
100231
- console.error('Failed to add to whitelist:', error);
100232
- return false;
100233
- }
100234
- };
100235
- // Helper function to get chain name
100236
- const getChainName = (chainId) => {
100237
- const chainNames = {
100238
- [main.ChainId.BASE]: 'Base',
100239
- [main.ChainId.ARBITRUM]: 'Arbitrum',
100240
- [main.ChainId.BSC]: 'BSC',
100241
- [main.ChainId.MAINNET]: 'Ethereum',
100242
- };
100243
- return chainNames[chainId] || `Chain ${chainId}`;
100244
- };
100245
- function useGooEligibility() {
100246
- const { address } = useAccount();
100247
- const queryClient = useQueryClient();
100248
- const [cbBTCBalanceChecked, setCbBTCBalanceChecked] = useState(false);
100249
- const SDKConfig = useSDKConfig();
100250
- const isFake = SDKConfig?.isFakeBTC ?? false;
100251
- // Get BTC tokens for all chains
100252
- const btcTokensSource = isFake ? FAKE_BTC_TOKENS : BTC_TOKENS;
100253
- const chainsToCheck = [main.ChainId.BASE, main.ChainId.ARBITRUM, main.ChainId.BSC, main.ChainId.MAINNET];
100254
- // Fetch balances for all chains - call hooks at top level
100255
- const baseToken = btcTokensSource[main.ChainId.BASE];
100256
- const arbitrumToken = btcTokensSource[main.ChainId.ARBITRUM];
100257
- const bscToken = btcTokensSource[main.ChainId.BSC];
100258
- const mainnetToken = btcTokensSource[main.ChainId.MAINNET];
100259
- const baseBalanceQuery = useUserTokensBalance(baseToken ? [baseToken] : [], main.ChainId.BASE);
100260
- const arbitrumBalanceQuery = useUserTokensBalance(arbitrumToken ? [arbitrumToken] : [], main.ChainId.ARBITRUM);
100261
- const bscBalanceQuery = useUserTokensBalance(bscToken ? [bscToken] : [], main.ChainId.BSC);
100262
- const mainnetBalanceQuery = useUserTokensBalance(mainnetToken ? [mainnetToken] : [], main.ChainId.MAINNET);
100263
- // Collect balance queries and data
100264
- const balanceQueries = [baseBalanceQuery, arbitrumBalanceQuery, bscBalanceQuery, mainnetBalanceQuery];
100265
- const balancesData = balanceQueries.map((q) => q.data);
100266
- const refetchAllBalances = async () => {
100267
- await Promise.all(balanceQueries.map((q) => q.refetch()));
100268
- };
100269
- // Check BTC balance across all chains
100270
- const cbBTCBalanceInfo = useQuery({
100271
- queryKey: [QUERY_KEYS.CBBTC_BALANCE, address, balancesData, cbBTCBalanceChecked],
100272
- queryFn: () => {
100273
- // Check if we have any balance data
100274
- const hasData = balancesData.some((data) => data && data.length > 0);
100275
- if (!hasData) {
100276
- return null;
100277
- }
100278
- // Collect all BTC balances from all chains
100279
- const allBalances = chainsToCheck.map((chainId, index) => {
100280
- const chainBalances = balancesData[index];
100281
- const token = btcTokensSource[chainId];
100282
- const tokenAddress = token?.address[chainId];
100283
- if (!chainBalances || !tokenAddress) {
100284
- return { chainId, balance: 0, symbol: token?.symbol || 'BTC' };
100285
- }
100286
- // Find the balance for this token
100287
- const tokenBalance = chainBalances.find((b) => b.address?.toLowerCase() === tokenAddress.toLowerCase());
100288
- const balance = tokenBalance ? parseFloat(tokenBalance.balance) : 0;
100289
- return {
100290
- chainId,
100291
- chainName: getChainName(chainId),
100292
- balance,
100293
- symbol: token?.symbol || 'BTC',
100294
- };
100295
- });
100296
- // Calculate total balance and check eligibility
100297
- const totalBalance = allBalances.reduce((sum, item) => sum + item.balance, 0);
100298
- const isEligible = totalBalance >= 0.001;
100299
- // Find which chains have balance
100300
- const chainsWithBalance = allBalances.filter((item) => item.balance > 0);
100301
- const result = {
100302
- balance: totalBalance,
100303
- isEligible,
100304
- balancesByChain: allBalances,
100305
- chainsWithBalance,
100306
- };
100307
- return result;
100308
- },
100309
- enabled: cbBTCBalanceChecked && balancesData.some((data) => data && data.length > 0),
100310
- staleTime: 0,
100311
- gcTime: 0,
100312
- });
100313
- // Mutation to add user to whitelist
100314
- const addToWhitelistMutation = useMutation({
100315
- mutationFn: () => addToWhitelist(address),
100316
- onSuccess: () => {
100317
- // Refetch eligibility after successful addition
100318
- queryClient.invalidateQueries({ queryKey: [QUERY_KEYS.GOO_ELIGIBILITY, address] });
100319
- },
100320
- });
100321
- const eligibilityQuery = useQuery({
100322
- queryKey: [QUERY_KEYS.GOO_ELIGIBILITY, address],
100323
- queryFn: () => checkEligibility(address),
100324
- refetchInterval: 600000,
100325
- refetchOnWindowFocus: false,
100326
- refetchOnMount: false,
100327
- refetchOnReconnect: false,
100328
- });
100329
- // Function to check BTC balance across all chains
100330
- const checkCbBTCBalance = async () => {
100331
- await refetchAllBalances();
100332
- setCbBTCBalanceChecked(true);
100333
- };
100334
- return {
100335
- ...eligibilityQuery,
100336
- cbBTCBalance: cbBTCBalanceInfo.data,
100337
- isCbBTCBalanceLoading: cbBTCBalanceInfo.isLoading || cbBTCBalanceInfo.isFetching,
100338
- cbBTCBalanceChecked,
100339
- checkCbBTCBalance,
100340
- addToWhitelist: addToWhitelistMutation.mutate,
100341
- isAddingToWhitelist: addToWhitelistMutation.isPending,
100342
- addToWhitelistSuccess: addToWhitelistMutation.isSuccess,
100343
- addToWhitelistError: addToWhitelistMutation.isError,
100344
- };
100345
- }
100346
-
100347
100190
  function useYourGoo(userAddress) {
100348
100191
  const SDKConfig = useSDKConfig();
100349
100192
  const apiAddress = SDKConfig?.urls?.apiV2;
@@ -100407,283 +100250,6 @@ const getUserGooData = async (userAddress, apiAddress) => {
100407
100250
  }
100408
100251
  };
100409
100252
 
100410
- // eslint-disable-next-line react/prop-types
100411
- const CounterCard = ({ digit, text }) => {
100412
- return (jsxs(Flex, { sx: { flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }, children: [jsx$2(Flex, { sx: {
100413
- background: 'linear-gradient(-45deg, #251c22 0%, #3a2327 100%)',
100414
- borderRadius: 'normal',
100415
- border: '1px solid #FE9E0450',
100416
- justifyContent: 'center',
100417
- alignItems: 'center',
100418
- p: '20px',
100419
- fontSize: ['24px', '24px', '26px', '36px'],
100420
- width: ['55px', '55px', '65px', '85px'],
100421
- height: ['60px', '60px', '70px', '90px'],
100422
- fontWeight: 700,
100423
- }, children: digit.toString().padStart(2, '0') }), jsx$2(Text, { color: "textNavbar", sx: {
100424
- fontSize: ['12px', '12px', '12px', '14px'],
100425
- fontWeight: 400,
100426
- mt: '10px',
100427
- }, children: text })] }));
100428
- };
100429
- const Colon = () => {
100430
- return (jsxs(Flex, { sx: { flexDirection: 'column', alignItems: 'center' }, children: [jsx$2(Text, { sx: {
100431
- fontSize: '34px',
100432
- fontWeight: 700,
100433
- lineHeight: '90px',
100434
- background: 'linear-gradient(to bottom, #fe9e0420 40%, #FE9E04 60%)',
100435
- WebkitBackgroundClip: 'text',
100436
- WebkitTextFillColor: 'transparent',
100437
- backgroundClip: 'text',
100438
- }, children: ":" }), jsx$2(Text, { color: "transparent", sx: { fontSize: '14px', fontWeight: 400, mt: '10px' }, children: "t" })] }));
100439
- };
100440
- const interval = 1000; // 1 sec
100441
- const getCountdownObject = (targetIsoTime) => {
100442
- // Detect if timestamp is in seconds or milliseconds
100443
- // Timestamps in seconds are typically < 10^10, milliseconds are > 10^12
100444
- const isSeconds = targetIsoTime < 10000000000;
100445
- const targetTimeMs = isSeconds ? targetIsoTime * 1000 : targetIsoTime;
100446
- const targetTime = new Date(targetTimeMs);
100447
- const now = new Date();
100448
- let delta = (targetTime.getTime() - now.getTime()) / 1000; // difference in seconds
100449
- // If the target time has passed, return zero countdown
100450
- if (delta <= 0)
100451
- return {
100452
- days: 0,
100453
- hours: 0,
100454
- minutes: 0,
100455
- seconds: 0,
100456
- };
100457
- const days = Math.floor(delta / 86400);
100458
- delta -= days * 86400;
100459
- const hours = Math.floor(delta / 3600) % 24;
100460
- delta -= hours * 3600;
100461
- const minutes = Math.floor(delta / 60) % 60;
100462
- const seconds = Math.floor(delta % 60);
100463
- return {
100464
- days,
100465
- hours,
100466
- minutes,
100467
- seconds,
100468
- };
100469
- };
100470
- const CountdownTimer = ({ targetTime }) => {
100471
- const [show, setShow] = useState(false);
100472
- const [countdown, setCountdown] = useState(getCountdownObject(targetTime));
100473
- useEffect(() => {
100474
- if (!show)
100475
- setShow(true);
100476
- const intervalId = setInterval(() => {
100477
- setCountdown(getCountdownObject(targetTime));
100478
- }, interval);
100479
- return () => {
100480
- clearInterval(intervalId);
100481
- };
100482
- /* eslint-disable react-hooks/exhaustive-deps */
100483
- }, [targetTime]);
100484
- // Render a countdown
100485
- return (show && (jsxs(Flex, { sx: {
100486
- flexDirection: 'row',
100487
- justifyContent: 'center',
100488
- alignItems: 'center',
100489
- gap: ['10px', '10px', '20px', '20px'],
100490
- }, children: [jsx$2(CounterCard, { digit: countdown?.days || 0, text: "Days" }), jsx$2(Colon, {}), jsx$2(CounterCard, { digit: countdown?.hours || 0, text: "Hours" }), jsx$2(Colon, {}), jsx$2(CounterCard, { digit: countdown?.minutes || 0, text: "Minutes" }), jsx$2(Colon, {}), jsx$2(CounterCard, { digit: countdown?.seconds || 0, text: "Seconds" })] })));
100491
- };
100492
-
100493
- function useRefundData() {
100494
- const { address } = useAccount();
100495
- const { chains } = useSDKConfig();
100496
- const apiUrl = useSDKConfig()?.urls?.apiV2;
100497
- const { data: saleInfo, isLoading: isSaleInfoLoading } = useSaleInfo();
100498
- // Get stage 1 and stage 2 contracts (refundable stages)
100499
- // Check by stageNumber since key naming may vary
100500
- const refundableStages = saleInfo?.stages?.filter((stage) => stage.stageNumber === 1 || stage.stageNumber === 2);
100501
- console.log('Refundable stages:', refundableStages);
100502
- console.log('All stages from saleInfo:', saleInfo?.stages);
100503
- // Flatten ALL contracts from refundable stages across ALL chains
100504
- const allContracts = [];
100505
- refundableStages?.forEach((stage) => {
100506
- console.log(`Stage ${stage.stageNumber} (${stage.key}) contractsByChain:`, stage.contractsByChain);
100507
- Object.entries(stage.contractsByChain).forEach(([chainId, contracts]) => {
100508
- contracts.forEach((contract) => {
100509
- console.log(`Adding contract: ${contract.address} on chain ${chainId} for stage ${stage.stageNumber}`);
100510
- allContracts.push({
100511
- ...contract,
100512
- chainId: parseInt(chainId),
100513
- stageKey: stage.key,
100514
- stageNumber: stage.stageNumber,
100515
- });
100516
- });
100517
- });
100518
- });
100519
- console.log('All contracts to check for refund:', allContracts);
100520
- return useQuery({
100521
- queryKey: [QUERY_KEYS.REFUND_DATA, address, allContracts?.length],
100522
- queryFn: () => fetchRefundData(chains, allContracts, address, apiUrl),
100523
- refetchInterval: 30000,
100524
- refetchOnWindowFocus: true,
100525
- enabled: !isSaleInfoLoading && allContracts.length > 0 && !!address,
100526
- });
100527
- }
100528
- const fetchRefundData = async (chains, contracts, account, apiUrl) => {
100529
- try {
100530
- console.log('fetchRefundData called with:', { chains, contractCount: contracts.length, account });
100531
- // Filter out invalid contracts
100532
- const validContracts = contracts.filter((contract) => contract.address !== '0x0000000000000000000000000000000000000000' && contract.address !== '');
100533
- console.log('Valid contracts after filtering:', validContracts.length, validContracts);
100534
- const results = await Promise.all(validContracts.map(async (contract) => {
100535
- try {
100536
- const calls = [
100537
- {
100538
- address: contract.address,
100539
- name: 'accountInfo',
100540
- params: [account],
100541
- },
100542
- {
100543
- address: contract.address,
100544
- name: 'accountStatus',
100545
- params: [account],
100546
- },
100547
- ];
100548
- console.log(`Calling multicall for ${contract.address} on chain ${contract.chainId}`);
100549
- const res = await multicall(contract.chainId, launchBondsABI, calls);
100550
- console.log(`Multicall result for ${contract.address}:`, res);
100551
- const depositAmount = res[0].depositAmount.toString();
100552
- const hasRefunded = res[1].hasRefunded;
100553
- console.log(`Contract ${contract.address}: depositAmount=${depositAmount}, hasRefunded=${hasRefunded}`);
100554
- return {
100555
- address: contract.address,
100556
- chainId: contract.chainId,
100557
- type: contract.type,
100558
- stageKey: contract.stageKey,
100559
- stageNumber: contract.stageNumber,
100560
- depositAmount,
100561
- depositAmountBTC: Number(depositAmount) / 100000000,
100562
- hasRefunded,
100563
- principalToken: contract.principalToken,
100564
- };
100565
- }
100566
- catch (error) {
100567
- console.error(`Error fetching refund data for ${contract.address} on chain ${contract.chainId}:`, error);
100568
- return null;
100569
- }
100570
- }));
100571
- const validResults = results.filter((r) => r !== null);
100572
- // Filter to only show contracts with deposits
100573
- const contractsWithDeposits = validResults.filter((r) => r.depositAmountBTC > 0.00000001);
100574
- const totalDepositBTC = contractsWithDeposits.reduce((sum, c) => sum + c.depositAmountBTC, 0);
100575
- return {
100576
- contracts: contractsWithDeposits,
100577
- totalDepositBTC,
100578
- };
100579
- }
100580
- catch (e) {
100581
- console.error('fetchRefundData error:', e);
100582
- reportError$1({
100583
- apiUrl,
100584
- error: e,
100585
- extraInfo: { type: 'fetchRefundData', contracts, e },
100586
- account,
100587
- });
100588
- return {
100589
- contracts: [],
100590
- totalDepositBTC: 0,
100591
- };
100592
- }
100593
- };
100594
-
100595
- const RefundRow = ({ contract, onRefundSuccess }) => {
100596
- const { address: account } = useAccount();
100597
- const chainId = useChainId();
100598
- const { switchChain } = useSwitchChain();
100599
- const { writeContractAsync } = useWriteContract();
100600
- const { addToastError, addToastSuccess } = usePopups();
100601
- const [txHash, setTxHash] = useState();
100602
- const [isLoading, setIsLoading] = useState(false);
100603
- const { isLoading: isConfirming, isSuccess: isConfirmed } = useMonitorTxHash(txHash, contract.chainId);
100604
- const needsChainSwitch = chainId !== contract.chainId;
100605
- const chainName = NETWORK_LABEL[contract.chainId] || `Chain ${contract.chainId}`;
100606
- const tokenSymbol = contract.type === 'goo' ? 'GOO' : 'sGOO';
100607
- const handleRefund = async () => {
100608
- if (needsChainSwitch) {
100609
- switchChain?.({ chainId: contract.chainId });
100610
- return;
100611
- }
100612
- setIsLoading(true);
100613
- try {
100614
- const hash = await writeContractAsync({
100615
- address: contract.address,
100616
- abi: launchBondsABI,
100617
- functionName: 'redeemRefund',
100618
- args: [],
100619
- chain: contract.chainId,
100620
- account,
100621
- });
100622
- if (hash) {
100623
- setTxHash(hash);
100624
- addToastSuccess('Refund transaction submitted!');
100625
- onRefundSuccess();
100626
- }
100627
- }
100628
- catch (error) {
100629
- console.error('Refund error:', error);
100630
- addToastError(error?.shortMessage || 'Failed to process refund');
100631
- }
100632
- finally {
100633
- setIsLoading(false);
100634
- }
100635
- };
100636
- const loading = isLoading || (isConfirming && !isConfirmed);
100637
- if (contract.hasRefunded) {
100638
- return (jsxs(Flex, { sx: {
100639
- width: '100%',
100640
- background: 'white2',
100641
- p: '20px',
100642
- borderRadius: 'normal',
100643
- mb: '10px',
100644
- alignItems: 'center',
100645
- justifyContent: 'space-between',
100646
- opacity: 0.6,
100647
- }, children: [jsxs(Flex, { sx: { alignItems: 'center', gap: '15px' }, children: [jsx$2(TokenImage, { symbol: tokenSymbol, size: 40, chain: contract.chainId }), jsxs(Flex, { sx: { flexDirection: 'column' }, children: [jsx$2(Text, { sx: { fontSize: '16px', fontWeight: 'bold' }, children: tokenSymbol }), jsxs(Text, { sx: { fontSize: '12px', opacity: 0.7 }, children: ["Stage ", contract.stageNumber, " \u2022 ", chainName] })] })] }), jsxs(Flex, { sx: { alignItems: 'center', gap: '20px' }, children: [jsxs(Text, { sx: { fontSize: '14px', fontWeight: 500 }, children: [contract.depositAmountBTC.toFixed(8), " BTC"] }), jsx$2(Button, { disabled: true, sx: { minWidth: '120px' }, children: "REFUNDED" })] })] }));
100648
- }
100649
- return (jsxs(Flex, { sx: {
100650
- width: '100%',
100651
- background: 'white2',
100652
- p: '20px',
100653
- borderRadius: 'normal',
100654
- mb: '10px',
100655
- alignItems: 'center',
100656
- justifyContent: 'space-between',
100657
- flexDirection: ['column', 'column', 'row', 'row'],
100658
- gap: ['15px', '15px', '0', '0'],
100659
- }, children: [jsxs(Flex, { sx: { alignItems: 'center', gap: '15px' }, children: [jsx$2(TokenImage, { symbol: tokenSymbol, size: 40, chain: contract.chainId }), jsxs(Flex, { sx: { flexDirection: 'column' }, children: [jsx$2(Text, { sx: { fontSize: '16px', fontWeight: 'bold' }, children: tokenSymbol }), jsxs(Text, { sx: { fontSize: '12px', opacity: 0.7 }, children: ["Stage ", contract.stageNumber, " \u2022 ", chainName] })] })] }), jsxs(Flex, { sx: { alignItems: 'center', gap: '20px', flexDirection: ['column', 'column', 'row', 'row'] }, children: [jsxs(Flex, { sx: { flexDirection: 'column', alignItems: ['center', 'center', 'flex-end', 'flex-end'] }, children: [jsxs(Text, { sx: { fontSize: '16px', fontWeight: 'bold' }, children: [contract.depositAmountBTC.toFixed(8), " BTC"] }), jsx$2(Text, { sx: { fontSize: '12px', opacity: 0.7 }, children: "Deposited" })] }), jsx$2(Button, { onClick: handleRefund, disabled: loading, load: loading, sx: { minWidth: '140px' }, variant: needsChainSwitch ? 'secondary' : 'primary', children: loading ? 'PROCESSING...' : needsChainSwitch ? `SWITCH CHAIN` : 'REFUND' })] })] }));
100660
- };
100661
- const RefundView = () => {
100662
- const { address } = useAccount();
100663
- const { data: refundData, isLoading, refetch } = useRefundData();
100664
- const handleRefundSuccess = () => {
100665
- // Refetch data after successful refund
100666
- setTimeout(() => refetch(), 2000);
100667
- };
100668
- if (!address) {
100669
- return (jsxs(Flex, { sx: { width: '100%', flexDirection: 'column', alignItems: 'center', p: '40px' }, children: [jsx$2(Text, { sx: { fontSize: '18px', fontWeight: 'bold', mb: '20px' }, children: "Connect wallet to view your refundable deposits" }), jsx$2(ConnectButton, {})] }));
100670
- }
100671
- if (isLoading) {
100672
- return (jsx$2(Flex, { sx: { justifyContent: 'center', alignItems: 'center', p: '60px', width: '100%' }, children: jsx$2(Spinner, {}) }));
100673
- }
100674
- const contracts = refundData?.contracts || [];
100675
- const hasDeposits = contracts.length > 0;
100676
- return (jsx$2(Flex, { sx: { width: '100%', flexDirection: 'column', p: ['10px', '20px', '20px', '40px'] }, children: !hasDeposits ? (jsxs(Flex, { sx: {
100677
- width: '100%',
100678
- background: 'white2',
100679
- p: '40px',
100680
- borderRadius: 'normal',
100681
- alignItems: 'center',
100682
- justifyContent: 'center',
100683
- flexDirection: 'column',
100684
- }, children: [jsx$2(Text, { sx: { fontSize: '16px', fontWeight: 500, opacity: 0.7 }, children: "No refundable deposits found" }), jsx$2(Text, { sx: { fontSize: '14px', opacity: 0.5, mt: '10px' }, children: "You have not participated in Stage 1 or Stage 2 on the selected chain." })] })) : (jsx$2(Fragment$1, { children: contracts.map((contract) => (jsx$2(RefundRow, { contract: contract, onRefundSuccess: handleRefundSuccess }, `${contract.address}-${contract.chainId}`))) })) }));
100685
- };
100686
-
100687
100253
  var BondsViewOptions;
100688
100254
  (function (BondsViewOptions) {
100689
100255
  BondsViewOptions["BONDSMARKET"] = "Bonds Market";
@@ -100692,41 +100258,11 @@ var BondsViewOptions;
100692
100258
  const GooSale = () => {
100693
100259
  // Fetch data
100694
100260
  const { data: chainFilterOption, setChainFilterOption } = useChainFilterOption();
100695
- const { data: saleInfo, isLoading: isLoadingSaleInfo } = useSaleInfo();
100696
100261
  const SDKConfig = useSDKConfig();
100697
- const currentStageNumber = saleInfo?.isInBreakPeriod
100698
- ? saleInfo?.nextStage?.stageNumber || 1
100699
- : saleInfo?.currentStage?.stageNumber || 1;
100700
100262
  const { address } = useAccount();
100701
100263
  const { data: yourGoo, isLoading, isFetching } = useYourGoo(address);
100702
100264
  const userParticipated = address && !isLoading && !isFetching && (yourGoo?.depositToGooBond !== '0' || yourGoo?.depositToSGooBond !== '0');
100703
100265
  const chainId = useChainId();
100704
- const { data: elegibleForSale, cbBTCBalance, isCbBTCBalanceLoading, cbBTCBalanceChecked, checkCbBTCBalance, addToWhitelist, isAddingToWhitelist, addToWhitelistSuccess, addToWhitelistError, } = useGooEligibility();
100705
- const [checkButtonPushed, setCheckButtonPushed] = useState(false);
100706
- const whitelisted = checkButtonPushed ? elegibleForSale : undefined;
100707
- // Handle check eligibility button click
100708
- const handleCheckEligibility = async () => {
100709
- setCheckButtonPushed(true);
100710
- if (elegibleForSale === null || elegibleForSale === undefined) {
100711
- // If not eligible, check cbBTC balance
100712
- await checkCbBTCBalance();
100713
- }
100714
- };
100715
- const currentStageSoldOut = saleInfo?.currentStage?.progressPercentage === 100;
100716
- // // Wrapper function that sets chain filter AND switches wallet chain
100717
- // const handleChainFilterChange = useCallback(
100718
- // (newChainFilter: string[]) => {
100719
- // setChainFilterOption(newChainFilter)
100720
- // // Switch wallet to the selected chain if it's different from current
100721
- // if (newChainFilter.length > 0 && switchChain) {
100722
- // const targetChainId = parseInt(newChainFilter[0])
100723
- // if (targetChainId !== chainId) {
100724
- // switchChain({ chainId: targetChainId })
100725
- // }
100726
- // }
100727
- // },
100728
- // [setChainFilterOption, switchChain, chainId],
100729
- // )
100730
100266
  // Sync chain filter with connected chain
100731
100267
  useEffect(() => {
100732
100268
  if (chainId) {
@@ -100737,73 +100273,14 @@ const GooSale = () => {
100737
100273
  }
100738
100274
  }
100739
100275
  }, [chainId, chainFilterOption, setChainFilterOption]);
100740
- // // Filter contracts by chain
100741
- // const filteredContractsByChain = useMemo(() => {
100742
- // const contractsByChain = saleInfo?.currentStage?.contractsByChain
100743
- // if (!contractsByChain) return undefined
100744
- // // Filter by selected chains
100745
- // const filtered: Record<number, GooSaleContractData[]> = {}
100746
- // Object.entries(contractsByChain).forEach(([chainId, contracts]) => {
100747
- // if (chainFilterOption?.includes(chainId)) {
100748
- // filtered[parseInt(chainId)] = contracts
100749
- // }
100750
- // })
100751
- // return filtered
100752
- // }, [saleInfo?.currentStage?.contractsByChain, chainFilterOption])
100753
- // Dynamic title based on current period (hidden during refund period)
100754
- const pageTitle = useMemo(() => {
100755
- if (saleInfo?.isRefundPeriod)
100756
- return null;
100757
- if (saleInfo?.currentStage?.key === 'TGE')
100758
- return 'GOO Token Generation Event';
100759
- return 'Buy GOO at a discount';
100760
- }, [saleInfo?.isRefundPeriod, saleInfo?.currentStage?.key]);
100761
- return (jsxs(Flex, { className: "bonds-container", children: [jsx$2(CheckUrl, {}), !SDKConfig.bondsComingSoon && pageTitle && (jsx$2(Flex, { sx: { justifyContent: 'center', alignItems: 'center', width: '100%' }, children: jsx$2(Text, { sx: { fontSize: '24px', fontWeight: 700, opacity: '0.9' }, children: pageTitle }) })), (saleInfo?.isInBreakPeriod || currentStageSoldOut) &&
100762
- saleInfo?.nextStage &&
100763
- !isLoadingSaleInfo &&
100764
- !saleInfo?.isSaleEnded && (jsxs(Flex, { sx: { width: '100%', justifyContent: 'center', mt: '40px', flexDirection: 'column', alignItems: 'center' }, children: [jsxs(Text, { sx: { fontSize: '20px', fontWeight: 'bold', mb: '20px' }, children: [saleInfo?.nextStage?.key === 'refund'
100765
- ? 'Refund Period '
100766
- : saleInfo?.nextStage?.key === 'TGE'
100767
- ? 'TGE '
100768
- : 'Stage ' + saleInfo?.nextStage?.stageNumber + ' ', "starts in:"] }), jsx$2(CountdownTimer, { targetTime: saleInfo?.nextStage?.startTime || 0 }), !(saleInfo?.nextStage?.key === 'refund' || saleInfo?.nextStage?.key === 'TGE') ? (jsxs(Fragment$1, { children: [jsxs(Flex, { sx: { flexDirection: 'column', alignItems: 'center' }, children: [jsxs(Flex, { sx: { flexDirection: 'row', alignItems: 'center', mt: '30px' }, children: [address && (jsxs(Flex, { sx: {
100769
- mr: '1rem',
100770
- p: '10px',
100771
- borderRadius: 'normal',
100772
- background: 'white3',
100773
- alignItems: 'center',
100774
- }, children: [jsx$2(Flex, { sx: { mr: '10px' }, children: jsx$2(Svg, { icon: "wallet" }) }), jsxs(Text, { sx: { fontSize: '14px', fontWeight: 400 }, children: [address?.slice(0, 4), "...", address?.slice(address?.length - 4, address?.length)] })] })), jsx$2(Flex, { sx: { fontSize: '18px', fontWeight: 500 }, children: "Are You Eligible?" })] }), !address ? (jsx$2(Flex, { sx: { my: '20px', width: '100%' }, children: jsx$2(ConnectButton, {}) })) : (whitelisted === null ||
100775
- (whitelisted === undefined && !cbBTCBalanceChecked && (jsx$2(Button, { sx: { m: '20px', width: '100%' }, onClick: handleCheckEligibility, children: "CHECK ELIGIBILITY" }))))] }), whitelisted !== null && whitelisted !== undefined && (jsxs(Flex, { sx: {
100776
- flexDirection: 'row',
100777
- alignItems: 'center',
100778
- mt: '20px',
100779
- background: 'white2',
100780
- p: '20px',
100781
- m: '20px',
100782
- borderRadius: 'normal',
100783
- }, children: [jsxs(Text, { sx: { fontSize: '12px', fontWeight: 400 }, children: ["You are whitelisted for Stage ", whitelisted, " and beyond!"] }), jsxs(Text, { color: "primaryButton", sx: { fontSize: '12px', fontWeight: 400, pl: '1rem' }, children: ["Tier ", whitelisted, " Access"] })] })), whitelisted === null && (jsx$2(Flex, { sx: {
100784
- flexDirection: 'column',
100785
- alignItems: 'center',
100786
- gap: '10px',
100787
- background: 'white2',
100788
- p: '20px',
100789
- m: '20px',
100790
- borderRadius: 'normal',
100791
- }, children: cbBTCBalanceChecked && (jsx$2(Flex, { sx: { flexDirection: 'column', alignItems: 'center', gap: '10px', mt: '10px' }, children: isCbBTCBalanceLoading ? (jsx$2(Text, { sx: { fontSize: '12px', fontWeight: 400 }, children: "Checking BTC balance across all chains..." })) : cbBTCBalance ? (jsxs(Fragment$1, { children: [cbBTCBalance.isEligible ? (addToWhitelistSuccess ? (jsx$2(Text, { color: "primaryButton", sx: { fontSize: '12px', fontWeight: 700 }, children: "\u2713 Successfully added to whitelist! Please refresh to see your tier." })) : addToWhitelistError ? (jsx$2(Text, { sx: { fontSize: '12px', fontWeight: 400, color: 'error' }, children: "Failed to add to whitelist. Please try again." })) : (jsx$2(Fragment$1, { children: jsx$2(Flex, { sx: { flexDirection: 'row', alignItems: 'center' }, children: jsxs(Text, { sx: { fontSize: '12px', fontWeight: 400 }, children: ["You ", jsx$2("span", { sx: { fontWeight: 700 }, children: "ARE" }), " eligible for the sale"] }) }) }))) : (jsxs(Flex, { sx: { flexDirection: 'column', alignItems: 'center', gap: '10px' }, children: [jsxs(Text, { sx: { fontSize: '12px', fontWeight: 400 }, children: ["You are ", jsx$2("span", { sx: { fontWeight: 700 }, children: "NOT" }), " eligible for the sale"] }), jsx$2(Text, { sx: { fontSize: '12px', fontWeight: 400, color: 'error' }, children: "You need at least 0.001 BTC to be whitelisted" })] })), jsxs(Text, { sx: { fontSize: '12px', fontWeight: 400 }, children: ["Total BTC Balance: ", cbBTCBalance.balance] }), cbBTCBalance.chainsWithBalance && cbBTCBalance.chainsWithBalance.length > 0 && (jsx$2(Flex, { sx: { flexDirection: 'column', gap: '5px', mt: '5px' }, children: cbBTCBalance.chainsWithBalance.map((chain) => (jsxs(Flex, { sx: { flexDirection: 'row', alignItems: 'center', gap: '10px' }, children: [jsx$2(TokenImage, { symbol: chain.symbol, size: 25, chain: chain.chainId }), jsxs(Text, { sx: { fontSize: '10px', fontWeight: 400, opacity: 0.7 }, children: [chain.balance, " ", chain.symbol] })] }, chain.chainId))) })), cbBTCBalance.isEligible && (jsx$2(Button, { sx: { width: '100%' }, onClick: () => addToWhitelist(), disabled: isAddingToWhitelist, children: isAddingToWhitelist ? 'ADDING TO WHITELIST...' : 'ADD ME TO WHITELIST' }))] })) : (jsx$2(Text, { sx: { fontSize: '12px', fontWeight: 400 }, children: "Unable to fetch BTC balance. Please try again." })) })) }))] })) : (jsx$2(Fragment$1, {}))] })), !SDKConfig.bondsComingSoon && (jsx$2(Flex, { sx: {
100276
+ return (jsxs(Flex, { className: "bonds-container", children: [jsx$2(CheckUrl, {}), !SDKConfig.bondsComingSoon && (jsx$2(Flex, { sx: {
100792
100277
  display: 'flex',
100793
100278
  flexDirection: 'column',
100794
100279
  alignItems: 'center',
100795
100280
  justifyContent: 'center',
100796
100281
  width: '100%',
100797
100282
  p: '6%',
100798
- }, children: jsx$2(Button, { sx: { width: '230px' }, onClick: () => (window.location.href = `${window.location.origin}/bonds`), children: "Start Bonding" }) })), jsxs(Flex, { sx: {
100799
- width: '100%',
100800
- alignItems: 'center',
100801
- px: '12%',
100802
- pt: (saleInfo?.isInBreakPeriod || currentStageSoldOut) && saleInfo?.nextStage ? '4rem' : '1rem',
100803
- pb: '4rem',
100804
- }, children: [jsx$2(StepBubble, { number: 1, title: 'STAGE 1', currentStep: currentStageNumber, loading: false }), jsx$2(StepBubble, { number: 2, title: 'STAGE 2', currentStep: currentStageNumber, loading: false }), jsx$2(StepBubble, { number: 3, title: 'REFUND', currentStep: currentStageNumber, loading: false }), jsx$2(StepBubble, { number: 4, title: 'TGE', currentStep: currentStageNumber, loading: false, hideBar: true })] }), jsx$2(Divider, { sx: { width: '100%', height: '2px', backgroundColor: 'white2' } }), saleInfo?.isRefundPeriod ? (
100805
- // Refund period - show refund view for ALL chains
100806
- jsx$2(RefundView, {})) : userParticipated ? (
100283
+ }, children: jsx$2(Button, { sx: { width: '230px' }, onClick: () => (window.location.href = `${window.location.origin}/bonds`), children: "Start Bonding" }) })), userParticipated ? (
100807
100284
  // Break period but user has participated - show their goo
100808
100285
  jsx$2(Fragment$1, { children: jsx$2(YourGoo, { yourGoo: yourGoo, isLoading: isLoading, isFetching: isFetching }) })) : (jsx$2(Fragment$1, {}))] }));
100809
100286
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Goo Money Bond SDK",
4
4
  "author": "Goo Money",
5
5
  "license": "MIT",
6
- "version": "3.0.176",
6
+ "version": "3.0.178",
7
7
  "proxy": "https://realtime-api-pr-99.herokuapp.com",
8
8
  "module": "dist/main.js",
9
9
  "type": "module",