@sodax/dapp-kit 2.0.0-rc.2 → 2.0.0-rc.20
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 +29 -74
- package/dist/index.d.ts +780 -58
- package/dist/index.mjs +841 -143
- package/package.json +31 -19
- package/src/hooks/_mutationContract.test.ts +15 -2
- package/src/hooks/backend/index.ts +1 -5
- package/src/hooks/bitcoin/index.ts +2 -0
- package/src/hooks/bitcoin/resolveBtcReadAddress.test.ts +54 -0
- package/src/hooks/bitcoin/resolveBtcReadAddress.ts +21 -0
- package/src/hooks/bitcoin/useBitcoinTradingSetup.ts +45 -0
- package/src/hooks/bitcoin/useEnsureRadfiAccessToken.ts +57 -0
- package/src/hooks/bitcoin/useFundTradingWallet.ts +1 -1
- package/src/hooks/bitcoin/useRadfiAuth.ts +2 -2
- package/src/hooks/bitcoin/useRadfiWithdraw.ts +2 -2
- package/src/hooks/bitcoin/useRenewUtxos.ts +2 -2
- package/src/hooks/bitcoin/useTradingWallet.ts +1 -1
- package/src/hooks/index.ts +2 -0
- package/src/hooks/leverageYield/index.ts +9 -0
- package/src/hooks/leverageYield/useLeverageYieldDeposit.ts +40 -0
- package/src/hooks/leverageYield/useLeverageYieldEffectiveApr.ts +42 -0
- package/src/hooks/leverageYield/useLeverageYieldNotifySolver.ts +34 -0
- package/src/hooks/leverageYield/useLeverageYieldPosition.ts +40 -0
- package/src/hooks/leverageYield/useLeverageYieldPreviewRedeem.ts +43 -0
- package/src/hooks/leverageYield/useLeverageYieldShareBalances.ts +74 -0
- package/src/hooks/leverageYield/useLeverageYieldTotalAssets.ts +36 -0
- package/src/hooks/leverageYield/useLeverageYieldVaultSwap.ts +50 -0
- package/src/hooks/leverageYield/useLeverageYieldWithdraw.ts +40 -0
- package/src/hooks/mm/useATokensBalances.ts +7 -1
- package/src/hooks/mm/useUserFormattedSummary.ts +5 -1
- package/src/hooks/mm/useUserReservesData.ts +5 -1
- package/src/hooks/partner/index.ts +4 -0
- package/src/hooks/partner/useFeeClaimWithdraw.ts +88 -0
- package/src/hooks/partner/useGetIntentDetails.ts +39 -0
- package/src/hooks/partner/useGetUserIntent.ts +35 -0
- package/src/hooks/partner/usePartnerCancelIntent.ts +52 -0
- package/src/hooks/shared/index.ts +4 -0
- package/src/hooks/shared/isUserRejectedError.test.ts +42 -0
- package/src/hooks/shared/isUserRejectedError.ts +30 -0
- package/src/hooks/shared/useGetUserHubWalletAddress.ts +5 -1
- package/src/hooks/shared/useNearStorageCheck.ts +45 -0
- package/src/hooks/shared/useNearStorageGate.ts +60 -0
- package/src/hooks/shared/useRegisterNearStorage.ts +46 -0
- package/src/hooks/swapsApi/index.ts +41 -0
- package/src/hooks/swapsApi/isTerminalSwapIntentStatus.test.ts +24 -0
- package/src/hooks/swapsApi/isTerminalSwapIntentStatus.ts +11 -0
- package/src/hooks/swapsApi/useSwapsApiAllowance.ts +40 -0
- package/src/hooks/swapsApi/useSwapsApiApprove.ts +42 -0
- package/src/hooks/swapsApi/useSwapsApiCancelIntent.ts +41 -0
- package/src/hooks/swapsApi/useSwapsApiCreateIntent.ts +41 -0
- package/src/hooks/swapsApi/useSwapsApiCreateLimitOrder.ts +41 -0
- package/src/hooks/swapsApi/useSwapsApiDeadline.ts +36 -0
- package/src/hooks/swapsApi/useSwapsApiEstimateGas.ts +40 -0
- package/src/hooks/swapsApi/useSwapsApiFilledIntent.ts +41 -0
- package/src/hooks/swapsApi/useSwapsApiIntent.ts +40 -0
- package/src/hooks/swapsApi/useSwapsApiIntentExtraData.ts +41 -0
- package/src/hooks/swapsApi/useSwapsApiIntentHash.ts +40 -0
- package/src/hooks/swapsApi/useSwapsApiIntentPacket.ts +43 -0
- package/src/hooks/swapsApi/useSwapsApiPartnerFee.ts +40 -0
- package/src/hooks/swapsApi/useSwapsApiQuote.ts +55 -0
- package/src/hooks/swapsApi/useSwapsApiSolverFee.ts +40 -0
- package/src/hooks/swapsApi/useSwapsApiStatus.ts +45 -0
- package/src/hooks/swapsApi/useSwapsApiSubmitIntent.ts +43 -0
- package/src/hooks/{backend/useBackendSubmitSwapTx.ts → swapsApi/useSwapsApiSubmitTx.ts} +16 -17
- package/src/hooks/swapsApi/useSwapsApiSubmitTxStatus.ts +55 -0
- package/src/hooks/swapsApi/useSwapsApiTokens.ts +34 -0
- package/src/hooks/swapsApi/useSwapsApiTokensByChain.ts +40 -0
- package/src/providers/SodaxProvider.tsx +17 -14
- package/src/utils/index.ts +1 -0
- package/src/utils/nearStorageGate.test.ts +46 -0
- package/src/utils/nearStorageGate.ts +39 -0
- package/ai-exported/AGENTS.md +0 -134
- package/ai-exported/integration/README.md +0 -49
- package/ai-exported/integration/ai-rules.md +0 -79
- package/ai-exported/integration/architecture.md +0 -274
- package/ai-exported/integration/features/README.md +0 -29
- package/ai-exported/integration/features/auxiliary-services.md +0 -169
- package/ai-exported/integration/features/bitcoin.md +0 -87
- package/ai-exported/integration/features/bridge.md +0 -91
- package/ai-exported/integration/features/dex.md +0 -152
- package/ai-exported/integration/features/migration.md +0 -118
- package/ai-exported/integration/features/money-market.md +0 -116
- package/ai-exported/integration/features/staking.md +0 -123
- package/ai-exported/integration/features/swap.md +0 -101
- package/ai-exported/integration/quickstart.md +0 -187
- package/ai-exported/integration/recipes/README.md +0 -136
- package/ai-exported/integration/recipes/backend-queries.md +0 -157
- package/ai-exported/integration/recipes/bitcoin.md +0 -193
- package/ai-exported/integration/recipes/bridge.md +0 -174
- package/ai-exported/integration/recipes/dex.md +0 -204
- package/ai-exported/integration/recipes/invalidations.md +0 -115
- package/ai-exported/integration/recipes/migration.md +0 -212
- package/ai-exported/integration/recipes/money-market.md +0 -206
- package/ai-exported/integration/recipes/mutation-error-handling.md +0 -118
- package/ai-exported/integration/recipes/observability.md +0 -93
- package/ai-exported/integration/recipes/setup.md +0 -144
- package/ai-exported/integration/recipes/staking.md +0 -202
- package/ai-exported/integration/recipes/swap.md +0 -272
- package/ai-exported/integration/recipes/wallet-connectivity.md +0 -101
- package/ai-exported/integration/reference/README.md +0 -12
- package/ai-exported/integration/reference/glossary.md +0 -188
- package/ai-exported/integration/reference/hooks-index.md +0 -190
- package/ai-exported/integration/reference/public-api.md +0 -110
- package/ai-exported/integration/reference/querykey-conventions.md +0 -179
- package/ai-exported/migration/README.md +0 -60
- package/ai-exported/migration/ai-rules.md +0 -81
- package/ai-exported/migration/breaking-changes/hook-signatures.md +0 -233
- package/ai-exported/migration/breaking-changes/querykey-conventions.md +0 -108
- package/ai-exported/migration/breaking-changes/result-handling.md +0 -211
- package/ai-exported/migration/breaking-changes/sdk-leakage.md +0 -165
- package/ai-exported/migration/checklist.md +0 -89
- package/ai-exported/migration/features/README.md +0 -34
- package/ai-exported/migration/features/auxiliary-services.md +0 -114
- package/ai-exported/migration/features/bitcoin.md +0 -88
- package/ai-exported/migration/features/bridge.md +0 -123
- package/ai-exported/migration/features/dex.md +0 -101
- package/ai-exported/migration/features/migration.md +0 -120
- package/ai-exported/migration/features/money-market.md +0 -97
- package/ai-exported/migration/features/staking.md +0 -109
- package/ai-exported/migration/features/swap.md +0 -118
- package/ai-exported/migration/recipes.md +0 -188
- package/ai-exported/migration/reference/README.md +0 -15
- package/ai-exported/migration/reference/deleted-hooks.md +0 -110
- package/ai-exported/migration/reference/error-shape-crosswalk.md +0 -144
- package/ai-exported/migration/reference/renamed-hooks.md +0 -66
- package/dist/index.cjs +0 -2642
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -1550
- package/dist/index.mjs.map +0 -1
- package/src/hooks/backend/useBackendSubmitSwapTxStatus.ts +0 -59
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type { IntentHashResponseV2, IntentRequestV2, RequestOverrideConfig } from '@sodax/sdk';
|
|
3
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
4
|
+
import { unwrapResult } from '../shared/unwrapResult.js';
|
|
5
|
+
import type { ReadHookParams } from '../shared/types.js';
|
|
6
|
+
|
|
7
|
+
export type UseSwapsApiIntentHashParams = ReadHookParams<
|
|
8
|
+
IntentHashResponseV2 | undefined,
|
|
9
|
+
{
|
|
10
|
+
intent: IntentRequestV2 | undefined;
|
|
11
|
+
apiConfig?: RequestOverrideConfig;
|
|
12
|
+
}
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* React hook to compute the keccak256 hash of an Intent struct via the swaps API —
|
|
17
|
+
* `sodax.api.swaps.getIntentHash`. The `intent` carries `bigint` numerics. Returns `{ hash }`.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* const { data } = useSwapsApiIntentHash({ params: { intent } });
|
|
21
|
+
*/
|
|
22
|
+
export const useSwapsApiIntentHash = ({
|
|
23
|
+
params,
|
|
24
|
+
queryOptions,
|
|
25
|
+
}: UseSwapsApiIntentHashParams = {}): UseQueryResult<IntentHashResponseV2 | undefined, Error> => {
|
|
26
|
+
const { sodax } = useSodaxContext();
|
|
27
|
+
const intent = params?.intent;
|
|
28
|
+
const apiConfig = params?.apiConfig;
|
|
29
|
+
|
|
30
|
+
return useQuery({
|
|
31
|
+
queryKey: ['swapsApi', 'intentHash', intent?.intentId?.toString()],
|
|
32
|
+
queryFn: async (): Promise<IntentHashResponseV2 | undefined> => {
|
|
33
|
+
if (!intent) return undefined;
|
|
34
|
+
return unwrapResult(await sodax.api.swaps.getIntentHash({ intent }, apiConfig));
|
|
35
|
+
},
|
|
36
|
+
enabled: !!intent,
|
|
37
|
+
retry: 3,
|
|
38
|
+
...queryOptions,
|
|
39
|
+
});
|
|
40
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type { IntentPacketRequestV2, IntentPacketResponseV2, RequestOverrideConfig } from '@sodax/sdk';
|
|
3
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
4
|
+
import { unwrapResult } from '../shared/unwrapResult.js';
|
|
5
|
+
import type { ReadHookParams } from '../shared/types.js';
|
|
6
|
+
|
|
7
|
+
export type UseSwapsApiIntentPacketParams = ReadHookParams<
|
|
8
|
+
IntentPacketResponseV2 | undefined,
|
|
9
|
+
{
|
|
10
|
+
body: IntentPacketRequestV2 | undefined;
|
|
11
|
+
apiConfig?: RequestOverrideConfig;
|
|
12
|
+
}
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* React hook to long-poll the relayer until the fill packet lands on the destination chain via the
|
|
17
|
+
* swaps API — `sodax.api.swaps.getSolvedIntentPacket`. The request is held open server-side until
|
|
18
|
+
* the packet arrives (or `body.timeout` ms elapses), so no client-side `refetchInterval` is set.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* const { data: packet } = useSwapsApiIntentPacket({
|
|
22
|
+
* params: { body: { chainId: '146', fillTxHash: '0x123...' } },
|
|
23
|
+
* });
|
|
24
|
+
*/
|
|
25
|
+
export const useSwapsApiIntentPacket = ({
|
|
26
|
+
params,
|
|
27
|
+
queryOptions,
|
|
28
|
+
}: UseSwapsApiIntentPacketParams = {}): UseQueryResult<IntentPacketResponseV2 | undefined, Error> => {
|
|
29
|
+
const { sodax } = useSodaxContext();
|
|
30
|
+
const body = params?.body;
|
|
31
|
+
const apiConfig = params?.apiConfig;
|
|
32
|
+
|
|
33
|
+
return useQuery({
|
|
34
|
+
queryKey: ['swapsApi', 'intentPacket', body?.chainId, body?.fillTxHash],
|
|
35
|
+
queryFn: async (): Promise<IntentPacketResponseV2 | undefined> => {
|
|
36
|
+
if (!body) return undefined;
|
|
37
|
+
return unwrapResult(await sodax.api.swaps.getSolvedIntentPacket(body, apiConfig));
|
|
38
|
+
},
|
|
39
|
+
enabled: !!body,
|
|
40
|
+
retry: 3,
|
|
41
|
+
...queryOptions,
|
|
42
|
+
});
|
|
43
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type { FeeResponseV2, RequestOverrideConfig } from '@sodax/sdk';
|
|
3
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
4
|
+
import { unwrapResult } from '../shared/unwrapResult.js';
|
|
5
|
+
import type { ReadHookParams } from '../shared/types.js';
|
|
6
|
+
|
|
7
|
+
export type UseSwapsApiPartnerFeeParams = ReadHookParams<
|
|
8
|
+
FeeResponseV2 | undefined,
|
|
9
|
+
{
|
|
10
|
+
amount: string | undefined;
|
|
11
|
+
apiConfig?: RequestOverrideConfig;
|
|
12
|
+
}
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* React hook to compute the partner fee for a given input amount via the swaps API —
|
|
17
|
+
* `sodax.api.swaps.getPartnerFee`. Returns `{ fee }` (decimal string).
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* const { data } = useSwapsApiPartnerFee({ params: { amount: '1000000' } });
|
|
21
|
+
*/
|
|
22
|
+
export const useSwapsApiPartnerFee = ({
|
|
23
|
+
params,
|
|
24
|
+
queryOptions,
|
|
25
|
+
}: UseSwapsApiPartnerFeeParams = {}): UseQueryResult<FeeResponseV2 | undefined, Error> => {
|
|
26
|
+
const { sodax } = useSodaxContext();
|
|
27
|
+
const amount = params?.amount;
|
|
28
|
+
const apiConfig = params?.apiConfig;
|
|
29
|
+
|
|
30
|
+
return useQuery({
|
|
31
|
+
queryKey: ['swapsApi', 'partnerFee', amount],
|
|
32
|
+
queryFn: async (): Promise<FeeResponseV2 | undefined> => {
|
|
33
|
+
if (!amount) return undefined;
|
|
34
|
+
return unwrapResult(await sodax.api.swaps.getPartnerFee({ amount }, apiConfig));
|
|
35
|
+
},
|
|
36
|
+
enabled: !!amount && amount.length > 0,
|
|
37
|
+
retry: 3,
|
|
38
|
+
...queryOptions,
|
|
39
|
+
});
|
|
40
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type { QuoteQueryV2, QuoteRequestV2, QuoteResponseV2, RequestOverrideConfig } from '@sodax/sdk';
|
|
3
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
4
|
+
import { unwrapResult } from '../shared/unwrapResult.js';
|
|
5
|
+
import type { ReadHookParams } from '../shared/types.js';
|
|
6
|
+
|
|
7
|
+
export type UseSwapsApiQuoteParams = ReadHookParams<
|
|
8
|
+
QuoteResponseV2 | undefined,
|
|
9
|
+
{
|
|
10
|
+
body: QuoteRequestV2 | undefined;
|
|
11
|
+
query?: QuoteQueryV2;
|
|
12
|
+
apiConfig?: RequestOverrideConfig;
|
|
13
|
+
}
|
|
14
|
+
>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* React hook to get a solver quote for a cross-chain swap via the swaps API —
|
|
18
|
+
* `sodax.api.swaps.getQuote`. Pass `query.includeTxData = true` to also build an unsigned
|
|
19
|
+
* create-intent transaction (`txData`); `srcAddress`/`dstAddress` are then required in the body.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const { data: quote } = useSwapsApiQuote({
|
|
23
|
+
* params: {
|
|
24
|
+
* body: {
|
|
25
|
+
* tokenSrc: '0x...', tokenSrcChainKey: '0xa4b1.arbitrum',
|
|
26
|
+
* tokenDst: '0x...', tokenDstChainKey: 'sonic',
|
|
27
|
+
* amount: '1000000', quoteType: 'exact_input',
|
|
28
|
+
* },
|
|
29
|
+
* },
|
|
30
|
+
* });
|
|
31
|
+
*/
|
|
32
|
+
export const useSwapsApiQuote = ({
|
|
33
|
+
params,
|
|
34
|
+
queryOptions,
|
|
35
|
+
}: UseSwapsApiQuoteParams = {}): UseQueryResult<QuoteResponseV2 | undefined, Error> => {
|
|
36
|
+
const { sodax } = useSodaxContext();
|
|
37
|
+
const body = params?.body;
|
|
38
|
+
const query = params?.query;
|
|
39
|
+
const apiConfig = params?.apiConfig;
|
|
40
|
+
|
|
41
|
+
return useQuery({
|
|
42
|
+
// Hash the whole request body so every quote input — including partnerFee and the other
|
|
43
|
+
// SwapExtrasV2 fields — is a cache dimension; a partnerFee change alters the quote and must
|
|
44
|
+
// miss the cache. QuoteRequestV2 is bigint-free (compile-time guaranteed), so React Query's
|
|
45
|
+
// default key hashing handles the object directly.
|
|
46
|
+
queryKey: ['swapsApi', 'quote', body, query?.includeTxData ?? false],
|
|
47
|
+
queryFn: async (): Promise<QuoteResponseV2 | undefined> => {
|
|
48
|
+
if (!body) return undefined;
|
|
49
|
+
return unwrapResult(await sodax.api.swaps.getQuote(body, query, apiConfig));
|
|
50
|
+
},
|
|
51
|
+
enabled: !!body,
|
|
52
|
+
retry: 3,
|
|
53
|
+
...queryOptions,
|
|
54
|
+
});
|
|
55
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type { FeeResponseV2, RequestOverrideConfig } from '@sodax/sdk';
|
|
3
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
4
|
+
import { unwrapResult } from '../shared/unwrapResult.js';
|
|
5
|
+
import type { ReadHookParams } from '../shared/types.js';
|
|
6
|
+
|
|
7
|
+
export type UseSwapsApiSolverFeeParams = ReadHookParams<
|
|
8
|
+
FeeResponseV2 | undefined,
|
|
9
|
+
{
|
|
10
|
+
amount: string | undefined;
|
|
11
|
+
apiConfig?: RequestOverrideConfig;
|
|
12
|
+
}
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* React hook to compute the protocol (solver) fee for a given input amount via the swaps API —
|
|
17
|
+
* `sodax.api.swaps.getSolverFee`. Returns `{ fee }` (decimal string).
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* const { data } = useSwapsApiSolverFee({ params: { amount: '1000000' } });
|
|
21
|
+
*/
|
|
22
|
+
export const useSwapsApiSolverFee = ({
|
|
23
|
+
params,
|
|
24
|
+
queryOptions,
|
|
25
|
+
}: UseSwapsApiSolverFeeParams = {}): UseQueryResult<FeeResponseV2 | undefined, Error> => {
|
|
26
|
+
const { sodax } = useSodaxContext();
|
|
27
|
+
const amount = params?.amount;
|
|
28
|
+
const apiConfig = params?.apiConfig;
|
|
29
|
+
|
|
30
|
+
return useQuery({
|
|
31
|
+
queryKey: ['swapsApi', 'solverFee', amount],
|
|
32
|
+
queryFn: async (): Promise<FeeResponseV2 | undefined> => {
|
|
33
|
+
if (!amount) return undefined;
|
|
34
|
+
return unwrapResult(await sodax.api.swaps.getSolverFee({ amount }, apiConfig));
|
|
35
|
+
},
|
|
36
|
+
enabled: !!amount && amount.length > 0,
|
|
37
|
+
retry: 3,
|
|
38
|
+
...queryOptions,
|
|
39
|
+
});
|
|
40
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type { RequestOverrideConfig, StatusResponseV2 } from '@sodax/sdk';
|
|
3
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
4
|
+
import { unwrapResult } from '../shared/unwrapResult.js';
|
|
5
|
+
import type { ReadHookParams } from '../shared/types.js';
|
|
6
|
+
import { isTerminalSwapIntentStatus } from './isTerminalSwapIntentStatus.js';
|
|
7
|
+
|
|
8
|
+
export type UseSwapsApiStatusParams = ReadHookParams<
|
|
9
|
+
StatusResponseV2 | undefined,
|
|
10
|
+
{
|
|
11
|
+
intentTxHash: string | undefined;
|
|
12
|
+
apiConfig?: RequestOverrideConfig;
|
|
13
|
+
}
|
|
14
|
+
>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* React hook for polling the solver intent status by hub-chain intent tx hash via the swaps API —
|
|
18
|
+
* `sodax.api.swaps.getStatus`. Returns `{ status, fillTxHash? }` (`fillTxHash` set when `status === 3`).
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* const { data } = useSwapsApiStatus({ params: { intentTxHash: '0x123...' } });
|
|
22
|
+
*
|
|
23
|
+
* @remarks
|
|
24
|
+
* - Default refetch interval is 1 second; stops once `status` is `3` (SOLVED) or `4` (FAILED).
|
|
25
|
+
*/
|
|
26
|
+
export const useSwapsApiStatus = ({
|
|
27
|
+
params,
|
|
28
|
+
queryOptions,
|
|
29
|
+
}: UseSwapsApiStatusParams = {}): UseQueryResult<StatusResponseV2 | undefined, Error> => {
|
|
30
|
+
const { sodax } = useSodaxContext();
|
|
31
|
+
const intentTxHash = params?.intentTxHash;
|
|
32
|
+
const apiConfig = params?.apiConfig;
|
|
33
|
+
|
|
34
|
+
return useQuery({
|
|
35
|
+
queryKey: ['swapsApi', 'status', intentTxHash],
|
|
36
|
+
queryFn: async (): Promise<StatusResponseV2 | undefined> => {
|
|
37
|
+
if (!intentTxHash) return undefined;
|
|
38
|
+
return unwrapResult(await sodax.api.swaps.getStatus({ intentTxHash }, apiConfig));
|
|
39
|
+
},
|
|
40
|
+
enabled: !!intentTxHash && intentTxHash.length > 0,
|
|
41
|
+
retry: 3,
|
|
42
|
+
refetchInterval: query => (isTerminalSwapIntentStatus(query.state.data?.status) ? false : 1000),
|
|
43
|
+
...queryOptions,
|
|
44
|
+
});
|
|
45
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { RequestOverrideConfig, SubmitIntentRequestV2, SubmitIntentResponseV2 } from '@sodax/sdk';
|
|
2
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
3
|
+
import { unwrapResult } from '../shared/unwrapResult.js';
|
|
4
|
+
import type { MutationHookParams } from '../shared/types.js';
|
|
5
|
+
import { useSafeMutation, type SafeUseMutationResult } from '../shared/useSafeMutation.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Mutation variables for {@link useSwapsApiSubmitIntent}. The per-request `apiConfig` override
|
|
9
|
+
* belongs here rather than at the hook level.
|
|
10
|
+
*/
|
|
11
|
+
export type UseSwapsApiSubmitIntentVars = {
|
|
12
|
+
body: SubmitIntentRequestV2;
|
|
13
|
+
apiConfig?: RequestOverrideConfig;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* React hook to submit the broadcast intent tx to the relay via the swaps API —
|
|
18
|
+
* `sodax.api.swaps.submitIntent`. Returns `{ result }` (opaque relay response).
|
|
19
|
+
*
|
|
20
|
+
* No auto-retry (`retry: false`): submitting is non-idempotent — a retry after a lost response
|
|
21
|
+
* could double-submit to the relay. Override via `mutationOptions.retry` if your relay dedupes.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* const { mutateAsync: submitIntent } = useSwapsApiSubmitIntent();
|
|
25
|
+
* const { result } = await submitIntent({ body: { chainId: '146', txHash: '0x123...' } });
|
|
26
|
+
*/
|
|
27
|
+
export const useSwapsApiSubmitIntent = ({
|
|
28
|
+
mutationOptions,
|
|
29
|
+
}: MutationHookParams<SubmitIntentResponseV2, UseSwapsApiSubmitIntentVars> = {}): SafeUseMutationResult<
|
|
30
|
+
SubmitIntentResponseV2,
|
|
31
|
+
Error,
|
|
32
|
+
UseSwapsApiSubmitIntentVars
|
|
33
|
+
> => {
|
|
34
|
+
const { sodax } = useSodaxContext();
|
|
35
|
+
|
|
36
|
+
return useSafeMutation<SubmitIntentResponseV2, Error, UseSwapsApiSubmitIntentVars>({
|
|
37
|
+
mutationKey: ['swapsApi', 'submitIntent'],
|
|
38
|
+
retry: false,
|
|
39
|
+
...mutationOptions,
|
|
40
|
+
mutationFn: async ({ body, apiConfig }): Promise<SubmitIntentResponseV2> =>
|
|
41
|
+
unwrapResult(await sodax.api.swaps.submitIntent(body, apiConfig)),
|
|
42
|
+
});
|
|
43
|
+
};
|
|
@@ -1,49 +1,48 @@
|
|
|
1
|
-
|
|
2
|
-
import type { RequestOverrideConfig, SubmitSwapTxRequest, SubmitSwapTxResponse } from '@sodax/sdk';
|
|
1
|
+
import type { RequestOverrideConfig, SubmitTxRequestV2, SubmitTxResponseV2 } from '@sodax/sdk';
|
|
3
2
|
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
4
|
-
import { unwrapResult } from '
|
|
3
|
+
import { unwrapResult } from '../shared/unwrapResult.js';
|
|
5
4
|
import type { MutationHookParams } from '../shared/types.js';
|
|
6
5
|
import { useSafeMutation, type SafeUseMutationResult } from '../shared/useSafeMutation.js';
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
|
-
* Mutation variables for {@link
|
|
8
|
+
* Mutation variables for {@link useSwapsApiSubmitTx}. The per-request `apiConfig` override
|
|
10
9
|
* (e.g. base URL) belongs here rather than at the hook level — different submissions in the same
|
|
11
10
|
* component can target different endpoints without re-rendering.
|
|
12
11
|
*/
|
|
13
|
-
export type
|
|
14
|
-
request:
|
|
12
|
+
export type UseSwapsApiSubmitTxVars = {
|
|
13
|
+
request: SubmitTxRequestV2;
|
|
15
14
|
apiConfig?: RequestOverrideConfig;
|
|
16
15
|
};
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
|
-
* React hook for submitting a swap transaction to be processed
|
|
20
|
-
*
|
|
18
|
+
* React hook for submitting a swap transaction to be processed (relay, post execution to the
|
|
19
|
+
* solver, etc.) via the swaps API — `sodax.api.swaps.submitTx`.
|
|
21
20
|
*
|
|
22
21
|
* Pure mutation: pass `{ request, apiConfig? }` to `mutate({...})`. Default `retry: 3` is applied
|
|
23
22
|
* at the hook level — consumers can override via `mutationOptions.retry`.
|
|
24
23
|
*
|
|
25
24
|
* @example
|
|
26
|
-
* const { mutateAsync: submitSwapTx, isPending, error } =
|
|
25
|
+
* const { mutateAsync: submitSwapTx, isPending, error } = useSwapsApiSubmitTx();
|
|
27
26
|
*
|
|
28
27
|
* const result = await submitSwapTx({
|
|
29
28
|
* request: { txHash: '0x123...', srcChainKey: 'sonic', walletAddress: '0xabc...', intent: { ... }, relayData: '0x...' },
|
|
30
29
|
* apiConfig: { baseURL: 'https://...' },
|
|
31
30
|
* });
|
|
32
31
|
*/
|
|
33
|
-
export const
|
|
32
|
+
export const useSwapsApiSubmitTx = ({
|
|
34
33
|
mutationOptions,
|
|
35
|
-
}: MutationHookParams<
|
|
36
|
-
|
|
34
|
+
}: MutationHookParams<SubmitTxResponseV2, UseSwapsApiSubmitTxVars> = {}): SafeUseMutationResult<
|
|
35
|
+
SubmitTxResponseV2,
|
|
37
36
|
Error,
|
|
38
|
-
|
|
37
|
+
UseSwapsApiSubmitTxVars
|
|
39
38
|
> => {
|
|
40
39
|
const { sodax } = useSodaxContext();
|
|
41
40
|
|
|
42
|
-
return useSafeMutation<
|
|
43
|
-
mutationKey: ['
|
|
41
|
+
return useSafeMutation<SubmitTxResponseV2, Error, UseSwapsApiSubmitTxVars>({
|
|
42
|
+
mutationKey: ['swapsApi', 'submitTx'],
|
|
44
43
|
retry: 3,
|
|
45
44
|
...mutationOptions,
|
|
46
|
-
mutationFn: async ({ request, apiConfig }): Promise<
|
|
47
|
-
unwrapResult(await sodax.
|
|
45
|
+
mutationFn: async ({ request, apiConfig }): Promise<SubmitTxResponseV2> =>
|
|
46
|
+
unwrapResult(await sodax.api.swaps.submitTx(request, apiConfig)),
|
|
48
47
|
});
|
|
49
48
|
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type { RequestOverrideConfig, SubmitTxStatusResponseV2 } from '@sodax/sdk';
|
|
3
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
4
|
+
import { unwrapResult } from '../shared/unwrapResult.js';
|
|
5
|
+
import type { ReadHookParams } from '../shared/types.js';
|
|
6
|
+
|
|
7
|
+
export type UseSwapsApiSubmitTxStatusParams = ReadHookParams<
|
|
8
|
+
SubmitTxStatusResponseV2 | undefined,
|
|
9
|
+
{
|
|
10
|
+
txHash: string | undefined;
|
|
11
|
+
srcChainKey?: string;
|
|
12
|
+
apiConfig?: RequestOverrideConfig;
|
|
13
|
+
}
|
|
14
|
+
>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* React hook for polling the processing status of a submitted swap transaction via the swaps API —
|
|
18
|
+
* `sodax.api.swaps.getSubmitTxStatus`. Both `txHash` and `srcChainKey` are required for the query
|
|
19
|
+
* to run (the swaps API v2 status query requires the source chain key).
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const { data: status } = useSwapsApiSubmitTxStatus({
|
|
23
|
+
* params: { txHash: '0x123...', srcChainKey: 'sonic' },
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* @remarks
|
|
27
|
+
* - Default refetch interval is 1 second; stops on 'solved' or 'failed' status.
|
|
28
|
+
*/
|
|
29
|
+
export const useSwapsApiSubmitTxStatus = ({
|
|
30
|
+
params,
|
|
31
|
+
queryOptions,
|
|
32
|
+
}: UseSwapsApiSubmitTxStatusParams = {}): UseQueryResult<SubmitTxStatusResponseV2 | undefined, Error> => {
|
|
33
|
+
const { sodax } = useSodaxContext();
|
|
34
|
+
const txHash = params?.txHash;
|
|
35
|
+
const srcChainKey = params?.srcChainKey;
|
|
36
|
+
const apiConfig = params?.apiConfig;
|
|
37
|
+
|
|
38
|
+
return useQuery({
|
|
39
|
+
queryKey: ['swapsApi', 'submitTx', 'status', txHash, srcChainKey],
|
|
40
|
+
queryFn: async (): Promise<SubmitTxStatusResponseV2 | undefined> => {
|
|
41
|
+
// `srcChainKey` is required by the swaps API v2 status query. The `enabled` gate below
|
|
42
|
+
// ensures both are present; this guard also narrows the types for the call.
|
|
43
|
+
if (!txHash || !srcChainKey) return undefined;
|
|
44
|
+
return unwrapResult(await sodax.api.swaps.getSubmitTxStatus({ txHash, srcChainKey }, apiConfig));
|
|
45
|
+
},
|
|
46
|
+
enabled: !!txHash && txHash.length > 0 && !!srcChainKey,
|
|
47
|
+
retry: 3,
|
|
48
|
+
refetchInterval: query => {
|
|
49
|
+
const status = query.state.data?.data?.status;
|
|
50
|
+
if (status === 'solved' || status === 'failed') return false;
|
|
51
|
+
return 1000;
|
|
52
|
+
},
|
|
53
|
+
...queryOptions,
|
|
54
|
+
});
|
|
55
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type { GetSwapTokensResponseV2, RequestOverrideConfig } from '@sodax/sdk';
|
|
3
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
4
|
+
import { unwrapResult } from '../shared/unwrapResult.js';
|
|
5
|
+
import type { ReadHookParams } from '../shared/types.js';
|
|
6
|
+
|
|
7
|
+
export type UseSwapsApiTokensParams = ReadHookParams<
|
|
8
|
+
GetSwapTokensResponseV2,
|
|
9
|
+
{
|
|
10
|
+
apiConfig?: RequestOverrideConfig;
|
|
11
|
+
}
|
|
12
|
+
>;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* React hook to fetch all supported swap tokens grouped by SpokeChainKey via the swaps API —
|
|
16
|
+
* `sodax.api.swaps.getTokens`.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* const { data: tokensByChain } = useSwapsApiTokens();
|
|
20
|
+
*/
|
|
21
|
+
export const useSwapsApiTokens = ({
|
|
22
|
+
params,
|
|
23
|
+
queryOptions,
|
|
24
|
+
}: UseSwapsApiTokensParams = {}): UseQueryResult<GetSwapTokensResponseV2, Error> => {
|
|
25
|
+
const { sodax } = useSodaxContext();
|
|
26
|
+
const apiConfig = params?.apiConfig;
|
|
27
|
+
|
|
28
|
+
return useQuery<GetSwapTokensResponseV2, Error>({
|
|
29
|
+
queryKey: ['swapsApi', 'tokens'],
|
|
30
|
+
queryFn: async (): Promise<GetSwapTokensResponseV2> => unwrapResult(await sodax.api.swaps.getTokens(apiConfig)),
|
|
31
|
+
retry: 3,
|
|
32
|
+
...queryOptions,
|
|
33
|
+
});
|
|
34
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type { GetSwapTokensByChainResponseV2, RequestOverrideConfig } from '@sodax/sdk';
|
|
3
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
4
|
+
import { unwrapResult } from '../shared/unwrapResult.js';
|
|
5
|
+
import type { ReadHookParams } from '../shared/types.js';
|
|
6
|
+
|
|
7
|
+
export type UseSwapsApiTokensByChainParams = ReadHookParams<
|
|
8
|
+
GetSwapTokensByChainResponseV2 | undefined,
|
|
9
|
+
{
|
|
10
|
+
chainKey: string | undefined;
|
|
11
|
+
apiConfig?: RequestOverrideConfig;
|
|
12
|
+
}
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* React hook to fetch supported swap tokens for a single SpokeChainKey via the swaps API —
|
|
17
|
+
* `sodax.api.swaps.getTokensByChain`.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* const { data: tokens } = useSwapsApiTokensByChain({ params: { chainKey: '0xa4b1.arbitrum' } });
|
|
21
|
+
*/
|
|
22
|
+
export const useSwapsApiTokensByChain = ({
|
|
23
|
+
params,
|
|
24
|
+
queryOptions,
|
|
25
|
+
}: UseSwapsApiTokensByChainParams = {}): UseQueryResult<GetSwapTokensByChainResponseV2 | undefined, Error> => {
|
|
26
|
+
const { sodax } = useSodaxContext();
|
|
27
|
+
const chainKey = params?.chainKey;
|
|
28
|
+
const apiConfig = params?.apiConfig;
|
|
29
|
+
|
|
30
|
+
return useQuery({
|
|
31
|
+
queryKey: ['swapsApi', 'tokens', chainKey],
|
|
32
|
+
queryFn: async (): Promise<GetSwapTokensByChainResponseV2 | undefined> => {
|
|
33
|
+
if (!chainKey) return undefined;
|
|
34
|
+
return unwrapResult(await sodax.api.swaps.getTokensByChain(chainKey, apiConfig));
|
|
35
|
+
},
|
|
36
|
+
enabled: !!chainKey && chainKey.length > 0,
|
|
37
|
+
retry: 3,
|
|
38
|
+
...queryOptions,
|
|
39
|
+
});
|
|
40
|
+
};
|
|
@@ -1,25 +1,28 @@
|
|
|
1
|
-
import { useMemo,
|
|
2
|
-
import { Sodax, type
|
|
1
|
+
import { useMemo, type ReactNode, type ReactElement } from 'react';
|
|
2
|
+
import { Sodax, type SodaxOptions } from '@sodax/sdk';
|
|
3
3
|
import { SodaxContext } from '@/contexts/index.js';
|
|
4
|
-
import type { DeepPartial } from '@sodax/sdk';
|
|
5
4
|
|
|
6
5
|
interface SodaxProviderProps {
|
|
7
6
|
children: ReactNode;
|
|
8
7
|
/**
|
|
9
|
-
* Sodax config
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
8
|
+
* Sodax SDK config. Tracked by **reference** - a new identity re-instantiates the
|
|
9
|
+
* SDK. Hoist to a module constant or wrap in `useMemo`; include any value the SDK
|
|
10
|
+
* should react to (e.g. solver env) in the deps. Inline `{...}` re-creates the SDK
|
|
11
|
+
* every parent render and resets every `useSodaxContext` consumer.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* const config = useMemo(() => ({ solver: solverMap[env] }), [env]);
|
|
16
|
+
* <SodaxProvider config={config}>...</SodaxProvider>
|
|
17
|
+
* ```
|
|
13
18
|
*/
|
|
14
|
-
config?:
|
|
19
|
+
config?: SodaxOptions;
|
|
15
20
|
}
|
|
16
21
|
|
|
22
|
+
/** Root provider for `@sodax/dapp-kit`. Must be paired with `QueryClientProvider`. */
|
|
17
23
|
export const SodaxProvider = ({ children, config }: SodaxProviderProps): ReactElement => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const configRef = useRef<DeepPartial<SodaxConfig> | undefined>(config);
|
|
21
|
-
const frozen = configRef.current;
|
|
22
|
-
const sodax = useMemo(() => new Sodax(frozen), [frozen]);
|
|
24
|
+
const sodax = useMemo(() => new Sodax(config), [config]);
|
|
25
|
+
const contextValue = useMemo(() => ({ sodax }), [sodax]);
|
|
23
26
|
|
|
24
|
-
return <SodaxContext.Provider value={
|
|
27
|
+
return <SodaxContext.Provider value={contextValue}>{children}</SodaxContext.Provider>;
|
|
25
28
|
};
|
package/src/utils/index.ts
CHANGED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ChainKeys } from '@sodax/sdk';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { resolveNearStorageGate } from './nearStorageGate.js';
|
|
4
|
+
|
|
5
|
+
describe('resolveNearStorageGate', () => {
|
|
6
|
+
it('destination not NEAR → never gates', () => {
|
|
7
|
+
expect(resolveNearStorageGate(ChainKeys.POLYGON_MAINNET, { isLoading: false, data: false })).toEqual({
|
|
8
|
+
isNear: false,
|
|
9
|
+
needsRegistration: false,
|
|
10
|
+
blocksAction: false,
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('NEAR, check in flight → blocks action but does not yet prompt registration', () => {
|
|
15
|
+
expect(resolveNearStorageGate(ChainKeys.NEAR_MAINNET, { isLoading: true, data: undefined })).toEqual({
|
|
16
|
+
isNear: true,
|
|
17
|
+
needsRegistration: false,
|
|
18
|
+
blocksAction: true,
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('NEAR, check resolved, not registered → prompt registration and block action', () => {
|
|
23
|
+
expect(resolveNearStorageGate(ChainKeys.NEAR_MAINNET, { isLoading: false, data: false })).toEqual({
|
|
24
|
+
isNear: true,
|
|
25
|
+
needsRegistration: true,
|
|
26
|
+
blocksAction: true,
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('NEAR, check resolved, registered → no gate', () => {
|
|
31
|
+
expect(resolveNearStorageGate(ChainKeys.NEAR_MAINNET, { isLoading: false, data: true })).toEqual({
|
|
32
|
+
isNear: true,
|
|
33
|
+
needsRegistration: false,
|
|
34
|
+
blocksAction: false,
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('NEAR, query disabled (unresolved, not checking) → does not block', () => {
|
|
39
|
+
// isLoading is false for a disabled query; data stays undefined → action must not be blocked.
|
|
40
|
+
expect(resolveNearStorageGate(ChainKeys.NEAR_MAINNET, { isLoading: false, data: undefined })).toEqual({
|
|
41
|
+
isNear: true,
|
|
42
|
+
needsRegistration: false,
|
|
43
|
+
blocksAction: false,
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ChainKeys, type SpokeChainKey } from '@sodax/sdk';
|
|
2
|
+
import type { UseQueryResult } from '@tanstack/react-query';
|
|
3
|
+
|
|
4
|
+
/** The subset of a `useNearStorageCheck` result the gate reads. A full `UseQueryResult<boolean>` satisfies it. */
|
|
5
|
+
export type NearStorageCheckResult = Pick<UseQueryResult<boolean>, 'isLoading' | 'data'>;
|
|
6
|
+
|
|
7
|
+
/** UI gate state for NEP-141 storage registration on NEAR. */
|
|
8
|
+
export interface NearStorageGateState {
|
|
9
|
+
/** Destination is NEAR — the only chain with a NEP-141 storage-registration prerequisite. */
|
|
10
|
+
isNear: boolean;
|
|
11
|
+
/** Show the "register storage" action: the check resolved and the recipient is not registered. */
|
|
12
|
+
needsRegistration: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Keep the downstream action (swap/bridge/borrow/withdraw) disabled: the NEAR gate is unresolved
|
|
15
|
+
* (still checking) or unmet (needs registration).
|
|
16
|
+
*/
|
|
17
|
+
blocksAction: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Derives the NEP-141 storage-registration UI gate state for a flow that delivers a token to a user
|
|
22
|
+
* on NEAR — NEAR's analogue of the Stellar trustline gate. Unwrapped (no hook): pass the destination
|
|
23
|
+
* `chainKey` and the `useNearStorageCheck` result; the util owns the `=== NEAR` test and reads
|
|
24
|
+
* `isLoading` (NOT `isPending`, which stays `true` for a disabled query and would block forever).
|
|
25
|
+
*
|
|
26
|
+
* `blocksAction` deliberately also covers the in-flight check window so the action can't be
|
|
27
|
+
* triggered before registration status is known; `needsRegistration` only flips once the check has
|
|
28
|
+
* resolved (so the "register" button isn't shown speculatively while still checking).
|
|
29
|
+
*/
|
|
30
|
+
export function resolveNearStorageGate(chainKey: SpokeChainKey, check: NearStorageCheckResult): NearStorageGateState {
|
|
31
|
+
const isNear = chainKey === ChainKeys.NEAR_MAINNET;
|
|
32
|
+
const isChecking = check.isLoading;
|
|
33
|
+
const isRegistered = check.data;
|
|
34
|
+
return {
|
|
35
|
+
isNear,
|
|
36
|
+
needsRegistration: isNear && !isChecking && isRegistered === false,
|
|
37
|
+
blocksAction: isNear && (isChecking || isRegistered === false),
|
|
38
|
+
};
|
|
39
|
+
}
|