@sodax/dapp-kit 2.0.0-rc.17 → 2.0.0-rc.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 +12 -3
- package/dist/index.d.ts +440 -46
- package/dist/index.mjs +471 -46
- package/package.json +2 -2
- package/src/hooks/_mutationContract.test.ts +8 -1
- package/src/hooks/backend/index.ts +1 -5
- package/src/hooks/bitcoin/index.ts +1 -0
- package/src/hooks/bitcoin/useBitcoinTradingSetup.ts +45 -0
- package/src/hooks/index.ts +1 -0
- 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/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/hooks/backend/useBackendSubmitSwapTxStatus.ts +0 -59
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// packages/dapp-kit/src/hooks/partner/useFeeClaimWithdraw.ts
|
|
2
|
+
import {
|
|
3
|
+
ChainKeys,
|
|
4
|
+
type Address,
|
|
5
|
+
type BridgeParams,
|
|
6
|
+
type GetWalletProviderType,
|
|
7
|
+
type HubChainKey,
|
|
8
|
+
type SpokeChainKey,
|
|
9
|
+
type TxHashPair,
|
|
10
|
+
} from '@sodax/sdk';
|
|
11
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
12
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
13
|
+
import type { MutationHookParams } from '../shared/types.js';
|
|
14
|
+
import { useSafeMutation, type SafeUseMutationResult } from '../shared/useSafeMutation.js';
|
|
15
|
+
import { unwrapResult } from '../shared/unwrapResult.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Mutation variables for {@link useFeeClaimWithdraw}. Maps a partner fee balance to a
|
|
19
|
+
* Sonic-sourced bridge: `feeToken` is the wrapped hub-asset address on Sonic
|
|
20
|
+
* (`PartnerFeeClaimAssetBalance.address`); `dstToken` is the original token address on
|
|
21
|
+
* `dstChainKey` (`PartnerFeeClaimAssetBalance.originalAddress`, or `feeToken` for same-chain
|
|
22
|
+
* delivery to a Sonic address).
|
|
23
|
+
*/
|
|
24
|
+
export type UseFeeClaimWithdrawVars = {
|
|
25
|
+
params: {
|
|
26
|
+
srcAddress: string;
|
|
27
|
+
feeToken: Address;
|
|
28
|
+
amount: bigint;
|
|
29
|
+
dstChainKey: SpokeChainKey;
|
|
30
|
+
dstToken: string;
|
|
31
|
+
recipient: string;
|
|
32
|
+
};
|
|
33
|
+
walletProvider: GetWalletProviderType<HubChainKey>;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* React hook to withdraw a partner fee token directly to the partner's wallet **without a swap**.
|
|
38
|
+
*
|
|
39
|
+
* For fees the partner wants to keep as-is (the desired output equals the fee token, e.g. BTC→BTC),
|
|
40
|
+
* an auto-swap is impossible — the solver rejects a same-token swap. This bridges the wrapped fee
|
|
41
|
+
* token from Sonic to its native chain (or transfers it on Sonic when `dstChainKey` is Sonic),
|
|
42
|
+
* bypassing the solver entirely.
|
|
43
|
+
*
|
|
44
|
+
* Bridging from Sonic pulls the token via the partner's hub-wallet router, which requires a prior
|
|
45
|
+
* allowance to that spender — a different approval than the ProtocolIntents one used by the swap
|
|
46
|
+
* claim. Use `useBridgeAllowance` / `useBridgeApprove` (with the same mapped bridge params) first.
|
|
47
|
+
*
|
|
48
|
+
* Throws on SDK failure so React Query's native error model engages. Returns the `TxHashPair`.
|
|
49
|
+
*/
|
|
50
|
+
export function useFeeClaimWithdraw({
|
|
51
|
+
mutationOptions,
|
|
52
|
+
}: MutationHookParams<TxHashPair, UseFeeClaimWithdrawVars> = {}): SafeUseMutationResult<
|
|
53
|
+
TxHashPair,
|
|
54
|
+
Error,
|
|
55
|
+
UseFeeClaimWithdrawVars
|
|
56
|
+
> {
|
|
57
|
+
const { sodax } = useSodaxContext();
|
|
58
|
+
const queryClient = useQueryClient();
|
|
59
|
+
|
|
60
|
+
return useSafeMutation<TxHashPair, Error, UseFeeClaimWithdrawVars>({
|
|
61
|
+
mutationKey: ['partner', 'feeClaimWithdraw'],
|
|
62
|
+
...mutationOptions,
|
|
63
|
+
mutationFn: async ({ params, walletProvider }) => {
|
|
64
|
+
const bridgeParams = {
|
|
65
|
+
params: {
|
|
66
|
+
srcChainKey: ChainKeys.SONIC_MAINNET,
|
|
67
|
+
srcAddress: params.srcAddress,
|
|
68
|
+
srcToken: params.feeToken,
|
|
69
|
+
amount: params.amount,
|
|
70
|
+
dstChainKey: params.dstChainKey,
|
|
71
|
+
dstToken: params.dstToken,
|
|
72
|
+
recipient: params.recipient,
|
|
73
|
+
},
|
|
74
|
+
raw: false,
|
|
75
|
+
walletProvider,
|
|
76
|
+
} satisfies BridgeParams<HubChainKey, false>;
|
|
77
|
+
|
|
78
|
+
return unwrapResult(await sodax.bridge.bridge(bridgeParams));
|
|
79
|
+
},
|
|
80
|
+
onSuccess: async (data, vars, ctx) => {
|
|
81
|
+
queryClient.invalidateQueries({
|
|
82
|
+
queryKey: ['partner', 'feeClaim', 'assetsBalances', vars.params.srcAddress],
|
|
83
|
+
});
|
|
84
|
+
queryClient.invalidateQueries({ queryKey: ['shared', 'xBalances', vars.params.dstChainKey] });
|
|
85
|
+
await mutationOptions?.onSuccess?.(data, vars, ctx);
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// packages/dapp-kit/src/hooks/partner/useGetIntentDetails.ts
|
|
2
|
+
import type { Hex, Intent } from '@sodax/sdk';
|
|
3
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
4
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
5
|
+
import type { ReadHookParams } from '../shared/types.js';
|
|
6
|
+
|
|
7
|
+
const ZERO_HASH = '0x0000000000000000000000000000000000000000000000000000000000000000';
|
|
8
|
+
|
|
9
|
+
export type UseGetIntentDetailsParams = ReadHookParams<Intent, { intentHash: Hex | undefined }>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* React hook to fetch the full {@link Intent} details for a ProtocolIntents intent hash.
|
|
13
|
+
*
|
|
14
|
+
* Pair with {@link useGetUserIntent} to display a stuck intent (e.g. its locked `inputAmount`)
|
|
15
|
+
* before recovering it. Disabled when the hash is missing or the zero hash (no intent). Throws
|
|
16
|
+
* on `!ok`.
|
|
17
|
+
*/
|
|
18
|
+
export function useGetIntentDetails({
|
|
19
|
+
params,
|
|
20
|
+
queryOptions,
|
|
21
|
+
}: UseGetIntentDetailsParams = {}): UseQueryResult<Intent, Error> {
|
|
22
|
+
const { sodax } = useSodaxContext();
|
|
23
|
+
const intentHash = params?.intentHash;
|
|
24
|
+
const hasIntent = !!intentHash && intentHash !== ZERO_HASH;
|
|
25
|
+
|
|
26
|
+
return useQuery<Intent, Error>({
|
|
27
|
+
queryKey: ['partner', 'feeClaim', 'intentDetails', intentHash],
|
|
28
|
+
queryFn: async () => {
|
|
29
|
+
if (!intentHash) {
|
|
30
|
+
throw new Error('intentHash is required');
|
|
31
|
+
}
|
|
32
|
+
const result = await sodax.partners.feeClaim.getIntentDetails(intentHash);
|
|
33
|
+
if (!result.ok) throw result.error;
|
|
34
|
+
return result.value;
|
|
35
|
+
},
|
|
36
|
+
enabled: hasIntent,
|
|
37
|
+
...queryOptions,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// packages/dapp-kit/src/hooks/partner/useGetUserIntent.ts
|
|
2
|
+
import type { GetUserIntentParams, Hex } from '@sodax/sdk';
|
|
3
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
4
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
5
|
+
import type { ReadHookParams } from '../shared/types.js';
|
|
6
|
+
|
|
7
|
+
export type UseGetUserIntentParams = ReadHookParams<Hex, Partial<GetUserIntentParams>>;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* React hook to look up the stored intent hash for a partner's `(user, fromToken, toToken)` pair.
|
|
11
|
+
*
|
|
12
|
+
* A non-zero hash means an open auto-swap intent exists for that token pair (e.g. an unfilled
|
|
13
|
+
* same-token claim) and can be recovered via {@link usePartnerCancelIntent}. Disabled until all
|
|
14
|
+
* three inputs are present. Throws on `!ok`.
|
|
15
|
+
*/
|
|
16
|
+
export function useGetUserIntent({ params, queryOptions }: UseGetUserIntentParams = {}): UseQueryResult<Hex, Error> {
|
|
17
|
+
const { sodax } = useSodaxContext();
|
|
18
|
+
const user = params?.user;
|
|
19
|
+
const fromToken = params?.fromToken;
|
|
20
|
+
const toToken = params?.toToken;
|
|
21
|
+
|
|
22
|
+
return useQuery<Hex, Error>({
|
|
23
|
+
queryKey: ['partner', 'feeClaim', 'userIntent', user, fromToken, toToken],
|
|
24
|
+
queryFn: async () => {
|
|
25
|
+
if (!user || !fromToken || !toToken) {
|
|
26
|
+
throw new Error('user, fromToken and toToken are required');
|
|
27
|
+
}
|
|
28
|
+
const result = await sodax.partners.feeClaim.getUserIntent({ user, fromToken, toToken });
|
|
29
|
+
if (!result.ok) throw result.error;
|
|
30
|
+
return result.value;
|
|
31
|
+
},
|
|
32
|
+
enabled: !!user && !!fromToken && !!toToken,
|
|
33
|
+
...queryOptions,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// packages/dapp-kit/src/hooks/partner/usePartnerCancelIntent.ts
|
|
2
|
+
import type { HubChainKey, PartnerFeeClaimCancelAction, TxReturnType } from '@sodax/sdk';
|
|
3
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
4
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
5
|
+
import type { MutationHookParams } from '../shared/types.js';
|
|
6
|
+
import { useSafeMutation, type SafeUseMutationResult } from '../shared/useSafeMutation.js';
|
|
7
|
+
import { unwrapResult } from '../shared/unwrapResult.js';
|
|
8
|
+
|
|
9
|
+
export type UsePartnerCancelIntentVars = Omit<PartnerFeeClaimCancelAction<HubChainKey, false>, 'raw'>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* React hook to cancel a stuck partner fee-claim auto-swap intent and recover the locked tokens.
|
|
13
|
+
*
|
|
14
|
+
* Calls `ProtocolIntents.cancelIntent(fromToken, toToken)` — the only authorized cancel path for
|
|
15
|
+
* partner auto-swap intents (the generic swap-cancel reverts because ProtocolIntents, not the
|
|
16
|
+
* partner, is the intent creator). The contract cancels the intent and refunds the input amount to
|
|
17
|
+
* the partner. Use this to recover funds from an unfillable same-token claim.
|
|
18
|
+
*
|
|
19
|
+
* Throws on SDK failure so React Query's native error model engages. Returns the transaction hash.
|
|
20
|
+
*/
|
|
21
|
+
export function usePartnerCancelIntent({
|
|
22
|
+
mutationOptions,
|
|
23
|
+
}: MutationHookParams<TxReturnType<HubChainKey, false>, UsePartnerCancelIntentVars> = {}): SafeUseMutationResult<
|
|
24
|
+
TxReturnType<HubChainKey, false>,
|
|
25
|
+
Error,
|
|
26
|
+
UsePartnerCancelIntentVars
|
|
27
|
+
> {
|
|
28
|
+
const { sodax } = useSodaxContext();
|
|
29
|
+
const queryClient = useQueryClient();
|
|
30
|
+
|
|
31
|
+
return useSafeMutation<TxReturnType<HubChainKey, false>, Error, UsePartnerCancelIntentVars>({
|
|
32
|
+
mutationKey: ['partner', 'cancelIntent'],
|
|
33
|
+
...mutationOptions,
|
|
34
|
+
mutationFn: async vars => unwrapResult(await sodax.partners.feeClaim.cancelIntent<false>({ ...vars, raw: false })),
|
|
35
|
+
onSuccess: async (data, vars, ctx) => {
|
|
36
|
+
queryClient.invalidateQueries({
|
|
37
|
+
queryKey: ['partner', 'feeClaim', 'assetsBalances', vars.params.srcAddress],
|
|
38
|
+
});
|
|
39
|
+
queryClient.invalidateQueries({
|
|
40
|
+
queryKey: [
|
|
41
|
+
'partner',
|
|
42
|
+
'feeClaim',
|
|
43
|
+
'userIntent',
|
|
44
|
+
vars.params.srcAddress,
|
|
45
|
+
vars.params.fromToken,
|
|
46
|
+
vars.params.toToken,
|
|
47
|
+
],
|
|
48
|
+
});
|
|
49
|
+
await mutationOptions?.onSuccess?.(data, vars, ctx);
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Swaps API v2 hooks — typed React Query wrappers over `sodax.api.swaps.*` (the SwapsApiService
|
|
3
|
+
* HTTP client). One hook per endpoint of the backend Swaps API v2.
|
|
4
|
+
*
|
|
5
|
+
* Distinct from the on-chain `swap/` hooks (`useQuote`/`useStatus`/`useSwap`/…), which drive the
|
|
6
|
+
* `SwapService` path (wallet → hub chain). These hooks call the backend HTTP API instead.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// Tokens
|
|
10
|
+
export * from './useSwapsApiTokens.js';
|
|
11
|
+
export * from './useSwapsApiTokensByChain.js';
|
|
12
|
+
|
|
13
|
+
// Quote · deadline
|
|
14
|
+
export * from './useSwapsApiQuote.js';
|
|
15
|
+
export * from './useSwapsApiDeadline.js';
|
|
16
|
+
|
|
17
|
+
// Allowance · approve · create intent
|
|
18
|
+
export * from './useSwapsApiAllowance.js';
|
|
19
|
+
export * from './useSwapsApiApprove.js';
|
|
20
|
+
export * from './useSwapsApiCreateIntent.js';
|
|
21
|
+
|
|
22
|
+
// Intent lifecycle: submit · status · cancel · hash · packet · extra-data · lookup
|
|
23
|
+
export * from './useSwapsApiSubmitIntent.js';
|
|
24
|
+
export * from './useSwapsApiStatus.js';
|
|
25
|
+
export * from './isTerminalSwapIntentStatus.js'; // terminal-status predicate (drives the status hook's polling)
|
|
26
|
+
export * from './useSwapsApiCancelIntent.js';
|
|
27
|
+
export * from './useSwapsApiIntentHash.js';
|
|
28
|
+
export * from './useSwapsApiIntentPacket.js';
|
|
29
|
+
export * from './useSwapsApiIntentExtraData.js';
|
|
30
|
+
export * from './useSwapsApiFilledIntent.js';
|
|
31
|
+
export * from './useSwapsApiIntent.js';
|
|
32
|
+
|
|
33
|
+
// Limit orders · gas · fees
|
|
34
|
+
export * from './useSwapsApiCreateLimitOrder.js';
|
|
35
|
+
export * from './useSwapsApiEstimateGas.js';
|
|
36
|
+
export * from './useSwapsApiPartnerFee.js';
|
|
37
|
+
export * from './useSwapsApiSolverFee.js';
|
|
38
|
+
|
|
39
|
+
// Submit-tx state machine
|
|
40
|
+
export * from './useSwapsApiSubmitTx.js';
|
|
41
|
+
export * from './useSwapsApiSubmitTxStatus.js';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { isTerminalSwapIntentStatus } from './isTerminalSwapIntentStatus.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Guards the polling-stop invariant for `useSwapsApiStatus.refetchInterval`: the hook keeps polling
|
|
6
|
+
* (1s) until the solver reports a terminal status, then stops. Tested as a pure predicate because
|
|
7
|
+
* dapp-kit's vitest runs in the `node` environment (no hook rendering) — see nearStorageGate.test.ts.
|
|
8
|
+
*/
|
|
9
|
+
describe('isTerminalSwapIntentStatus', () => {
|
|
10
|
+
it('is terminal for SOLVED (3) and FAILED (4)', () => {
|
|
11
|
+
expect(isTerminalSwapIntentStatus(3)).toBe(true);
|
|
12
|
+
expect(isTerminalSwapIntentStatus(4)).toBe(true);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('is non-terminal for NOT_FOUND (-1), NOT_STARTED_YET (1), and STARTED_NOT_FINISHED (2)', () => {
|
|
16
|
+
expect(isTerminalSwapIntentStatus(-1)).toBe(false);
|
|
17
|
+
expect(isTerminalSwapIntentStatus(1)).toBe(false);
|
|
18
|
+
expect(isTerminalSwapIntentStatus(2)).toBe(false);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('is non-terminal when no status has arrived yet (undefined) — keeps polling', () => {
|
|
22
|
+
expect(isTerminalSwapIntentStatus(undefined)).toBe(false);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SwapIntentStatusCodeV2 } from '@sodax/sdk';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Terminal solver intent states: once reached, the intent is resolved and polling stops.
|
|
5
|
+
* `3` = SOLVED, `4` = FAILED (per `SwapIntentStatusCodeV2`); `-1` / `1` / `2` are non-terminal.
|
|
6
|
+
*
|
|
7
|
+
* Kept in its own pure module (no React/context imports) so it is unit-testable in dapp-kit's
|
|
8
|
+
* `node` test environment — importing the hook itself pulls in `useSodaxContext`.
|
|
9
|
+
*/
|
|
10
|
+
export const isTerminalSwapIntentStatus = (status: SwapIntentStatusCodeV2 | undefined): boolean =>
|
|
11
|
+
status === 3 || status === 4;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type { AllowanceCheckResponseV2, CreateIntentParamsV2, 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 UseSwapsApiAllowanceParams = ReadHookParams<
|
|
8
|
+
AllowanceCheckResponseV2 | undefined,
|
|
9
|
+
{
|
|
10
|
+
body: CreateIntentParamsV2 | undefined;
|
|
11
|
+
apiConfig?: RequestOverrideConfig;
|
|
12
|
+
}
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* React hook to check whether the source-token allowance is already sufficient for an intent via
|
|
17
|
+
* the swaps API — `sodax.api.swaps.checkAllowance`. Returns `{ valid }`.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* const { data: allowance } = useSwapsApiAllowance({ params: { body: createIntentParams } });
|
|
21
|
+
*/
|
|
22
|
+
export const useSwapsApiAllowance = ({
|
|
23
|
+
params,
|
|
24
|
+
queryOptions,
|
|
25
|
+
}: UseSwapsApiAllowanceParams = {}): UseQueryResult<AllowanceCheckResponseV2 | undefined, Error> => {
|
|
26
|
+
const { sodax } = useSodaxContext();
|
|
27
|
+
const body = params?.body;
|
|
28
|
+
const apiConfig = params?.apiConfig;
|
|
29
|
+
|
|
30
|
+
return useQuery({
|
|
31
|
+
queryKey: ['swapsApi', 'allowance', body?.srcChainKey, body?.inputToken, body?.inputAmount, body?.srcAddress],
|
|
32
|
+
queryFn: async (): Promise<AllowanceCheckResponseV2 | undefined> => {
|
|
33
|
+
if (!body) return undefined;
|
|
34
|
+
return unwrapResult(await sodax.api.swaps.checkAllowance(body, apiConfig));
|
|
35
|
+
},
|
|
36
|
+
enabled: !!body,
|
|
37
|
+
retry: 3,
|
|
38
|
+
...queryOptions,
|
|
39
|
+
});
|
|
40
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ApproveResponseV2, CreateIntentParamsV2, RequestOverrideConfig } 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 useSwapsApiApprove}. The per-request `apiConfig` override belongs
|
|
9
|
+
* here rather than at the hook level — different calls in the same component can target different
|
|
10
|
+
* endpoints without re-rendering.
|
|
11
|
+
*/
|
|
12
|
+
export type UseSwapsApiApproveVars = {
|
|
13
|
+
body: CreateIntentParamsV2;
|
|
14
|
+
apiConfig?: RequestOverrideConfig;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* React hook to build an unsigned token-approval transaction for the source token via the swaps
|
|
19
|
+
* API — `sodax.api.swaps.approve`. Returns `{ tx }` (chain-specific unsigned tx) to sign and
|
|
20
|
+
* broadcast yourself; it does not change state, so no queries are invalidated.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* const { mutateAsync: approve } = useSwapsApiApprove();
|
|
24
|
+
* const { tx } = await approve({ body: createIntentParams });
|
|
25
|
+
*/
|
|
26
|
+
export const useSwapsApiApprove = ({
|
|
27
|
+
mutationOptions,
|
|
28
|
+
}: MutationHookParams<ApproveResponseV2, UseSwapsApiApproveVars> = {}): SafeUseMutationResult<
|
|
29
|
+
ApproveResponseV2,
|
|
30
|
+
Error,
|
|
31
|
+
UseSwapsApiApproveVars
|
|
32
|
+
> => {
|
|
33
|
+
const { sodax } = useSodaxContext();
|
|
34
|
+
|
|
35
|
+
return useSafeMutation<ApproveResponseV2, Error, UseSwapsApiApproveVars>({
|
|
36
|
+
mutationKey: ['swapsApi', 'approve'],
|
|
37
|
+
retry: 3,
|
|
38
|
+
...mutationOptions,
|
|
39
|
+
mutationFn: async ({ body, apiConfig }): Promise<ApproveResponseV2> =>
|
|
40
|
+
unwrapResult(await sodax.api.swaps.approve(body, apiConfig)),
|
|
41
|
+
});
|
|
42
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { CancelIntentRequestV2, CancelIntentResponseV2, RequestOverrideConfig } 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 useSwapsApiCancelIntent}. The per-request `apiConfig` override
|
|
9
|
+
* belongs here rather than at the hook level.
|
|
10
|
+
*/
|
|
11
|
+
export type UseSwapsApiCancelIntentVars = {
|
|
12
|
+
body: CancelIntentRequestV2;
|
|
13
|
+
apiConfig?: RequestOverrideConfig;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* React hook to build an unsigned cancel-intent transaction via the swaps API —
|
|
18
|
+
* `sodax.api.swaps.cancelIntent`. The `intent` carries `bigint` numerics. Returns `{ tx }` to sign
|
|
19
|
+
* and broadcast yourself; it does not change state, so no queries are invalidated.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const { mutateAsync: cancelIntent } = useSwapsApiCancelIntent();
|
|
23
|
+
* const { tx } = await cancelIntent({ body: { srcChainKey: 'sonic', intent } });
|
|
24
|
+
*/
|
|
25
|
+
export const useSwapsApiCancelIntent = ({
|
|
26
|
+
mutationOptions,
|
|
27
|
+
}: MutationHookParams<CancelIntentResponseV2, UseSwapsApiCancelIntentVars> = {}): SafeUseMutationResult<
|
|
28
|
+
CancelIntentResponseV2,
|
|
29
|
+
Error,
|
|
30
|
+
UseSwapsApiCancelIntentVars
|
|
31
|
+
> => {
|
|
32
|
+
const { sodax } = useSodaxContext();
|
|
33
|
+
|
|
34
|
+
return useSafeMutation<CancelIntentResponseV2, Error, UseSwapsApiCancelIntentVars>({
|
|
35
|
+
mutationKey: ['swapsApi', 'cancelIntent'],
|
|
36
|
+
retry: 3,
|
|
37
|
+
...mutationOptions,
|
|
38
|
+
mutationFn: async ({ body, apiConfig }): Promise<CancelIntentResponseV2> =>
|
|
39
|
+
unwrapResult(await sodax.api.swaps.cancelIntent(body, apiConfig)),
|
|
40
|
+
});
|
|
41
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { CreateIntentParamsV2, CreateIntentResponseV2, RequestOverrideConfig } 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 useSwapsApiCreateIntent}. The per-request `apiConfig` override
|
|
9
|
+
* belongs here rather than at the hook level.
|
|
10
|
+
*/
|
|
11
|
+
export type UseSwapsApiCreateIntentVars = {
|
|
12
|
+
body: CreateIntentParamsV2;
|
|
13
|
+
apiConfig?: RequestOverrideConfig;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* React hook to build an unsigned create-intent transaction via the swaps API —
|
|
18
|
+
* `sodax.api.swaps.createIntent`. Returns `{ tx, intent, relayData }` to sign and broadcast
|
|
19
|
+
* yourself; it does not change state, so no queries are invalidated.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const { mutateAsync: createIntent } = useSwapsApiCreateIntent();
|
|
23
|
+
* const { tx, intent, relayData } = await createIntent({ body: createIntentParams });
|
|
24
|
+
*/
|
|
25
|
+
export const useSwapsApiCreateIntent = ({
|
|
26
|
+
mutationOptions,
|
|
27
|
+
}: MutationHookParams<CreateIntentResponseV2, UseSwapsApiCreateIntentVars> = {}): SafeUseMutationResult<
|
|
28
|
+
CreateIntentResponseV2,
|
|
29
|
+
Error,
|
|
30
|
+
UseSwapsApiCreateIntentVars
|
|
31
|
+
> => {
|
|
32
|
+
const { sodax } = useSodaxContext();
|
|
33
|
+
|
|
34
|
+
return useSafeMutation<CreateIntentResponseV2, Error, UseSwapsApiCreateIntentVars>({
|
|
35
|
+
mutationKey: ['swapsApi', 'createIntent'],
|
|
36
|
+
retry: 3,
|
|
37
|
+
...mutationOptions,
|
|
38
|
+
mutationFn: async ({ body, apiConfig }): Promise<CreateIntentResponseV2> =>
|
|
39
|
+
unwrapResult(await sodax.api.swaps.createIntent(body, apiConfig)),
|
|
40
|
+
});
|
|
41
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { CreateLimitOrderParamsV2, CreateLimitOrderResponseV2, RequestOverrideConfig } 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 useSwapsApiCreateLimitOrder}. The per-request `apiConfig` override
|
|
9
|
+
* belongs here rather than at the hook level.
|
|
10
|
+
*/
|
|
11
|
+
export type UseSwapsApiCreateLimitOrderVars = {
|
|
12
|
+
body: CreateLimitOrderParamsV2;
|
|
13
|
+
apiConfig?: RequestOverrideConfig;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* React hook to build an unsigned create-limit-order-intent transaction via the swaps API —
|
|
18
|
+
* `sodax.api.swaps.createLimitOrderIntent` (same as create-intent but `deadline` is optional).
|
|
19
|
+
* Returns `{ tx, intent, relayData }`; it does not change state, so no queries are invalidated.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const { mutateAsync: createLimitOrder } = useSwapsApiCreateLimitOrder();
|
|
23
|
+
* const { tx, intent, relayData } = await createLimitOrder({ body: createLimitOrderParams });
|
|
24
|
+
*/
|
|
25
|
+
export const useSwapsApiCreateLimitOrder = ({
|
|
26
|
+
mutationOptions,
|
|
27
|
+
}: MutationHookParams<CreateLimitOrderResponseV2, UseSwapsApiCreateLimitOrderVars> = {}): SafeUseMutationResult<
|
|
28
|
+
CreateLimitOrderResponseV2,
|
|
29
|
+
Error,
|
|
30
|
+
UseSwapsApiCreateLimitOrderVars
|
|
31
|
+
> => {
|
|
32
|
+
const { sodax } = useSodaxContext();
|
|
33
|
+
|
|
34
|
+
return useSafeMutation<CreateLimitOrderResponseV2, Error, UseSwapsApiCreateLimitOrderVars>({
|
|
35
|
+
mutationKey: ['swapsApi', 'createLimitOrder'],
|
|
36
|
+
retry: 3,
|
|
37
|
+
...mutationOptions,
|
|
38
|
+
mutationFn: async ({ body, apiConfig }): Promise<CreateLimitOrderResponseV2> =>
|
|
39
|
+
unwrapResult(await sodax.api.swaps.createLimitOrderIntent(body, apiConfig)),
|
|
40
|
+
});
|
|
41
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type { DeadlineQueryV2, DeadlineResponseV2, 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 UseSwapsApiDeadlineParams = ReadHookParams<
|
|
8
|
+
DeadlineResponseV2,
|
|
9
|
+
{
|
|
10
|
+
query?: DeadlineQueryV2;
|
|
11
|
+
apiConfig?: RequestOverrideConfig;
|
|
12
|
+
}
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* React hook to compute a swap deadline (hub timestamp + `offsetSeconds`, default 300s) via the
|
|
17
|
+
* swaps API — `sodax.api.swaps.getDeadline`.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* const { data: deadline } = useSwapsApiDeadline({ params: { query: { offsetSeconds: 600 } } });
|
|
21
|
+
*/
|
|
22
|
+
export const useSwapsApiDeadline = ({
|
|
23
|
+
params,
|
|
24
|
+
queryOptions,
|
|
25
|
+
}: UseSwapsApiDeadlineParams = {}): UseQueryResult<DeadlineResponseV2, Error> => {
|
|
26
|
+
const { sodax } = useSodaxContext();
|
|
27
|
+
const query = params?.query;
|
|
28
|
+
const apiConfig = params?.apiConfig;
|
|
29
|
+
|
|
30
|
+
return useQuery<DeadlineResponseV2, Error>({
|
|
31
|
+
queryKey: ['swapsApi', 'deadline', query?.offsetSeconds ?? null],
|
|
32
|
+
queryFn: async (): Promise<DeadlineResponseV2> => unwrapResult(await sodax.api.swaps.getDeadline(query, apiConfig)),
|
|
33
|
+
retry: 3,
|
|
34
|
+
...queryOptions,
|
|
35
|
+
});
|
|
36
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type { GasEstimateRequestV2, GasEstimateResponseV2, 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 UseSwapsApiEstimateGasParams = ReadHookParams<
|
|
8
|
+
GasEstimateResponseV2 | undefined,
|
|
9
|
+
{
|
|
10
|
+
body: GasEstimateRequestV2 | undefined;
|
|
11
|
+
apiConfig?: RequestOverrideConfig;
|
|
12
|
+
}
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* React hook to estimate gas for a raw transaction on a spoke chain via the swaps API —
|
|
17
|
+
* `sodax.api.swaps.estimateGas`. Returns `{ gas }` (chain-specific shape).
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* const { data } = useSwapsApiEstimateGas({ params: { body: { chainKey: 'sonic', tx } } });
|
|
21
|
+
*/
|
|
22
|
+
export const useSwapsApiEstimateGas = ({
|
|
23
|
+
params,
|
|
24
|
+
queryOptions,
|
|
25
|
+
}: UseSwapsApiEstimateGasParams = {}): UseQueryResult<GasEstimateResponseV2 | undefined, Error> => {
|
|
26
|
+
const { sodax } = useSodaxContext();
|
|
27
|
+
const body = params?.body;
|
|
28
|
+
const apiConfig = params?.apiConfig;
|
|
29
|
+
|
|
30
|
+
return useQuery({
|
|
31
|
+
queryKey: ['swapsApi', 'estimateGas', body?.chainKey, body?.tx],
|
|
32
|
+
queryFn: async (): Promise<GasEstimateResponseV2 | undefined> => {
|
|
33
|
+
if (!body) return undefined;
|
|
34
|
+
return unwrapResult(await sodax.api.swaps.estimateGas(body, apiConfig));
|
|
35
|
+
},
|
|
36
|
+
enabled: !!body,
|
|
37
|
+
retry: 3,
|
|
38
|
+
...queryOptions,
|
|
39
|
+
});
|
|
40
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type { IntentStateV2, 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 UseSwapsApiFilledIntentParams = ReadHookParams<
|
|
8
|
+
IntentStateV2 | undefined,
|
|
9
|
+
{
|
|
10
|
+
txHash: string | undefined;
|
|
11
|
+
apiConfig?: RequestOverrideConfig;
|
|
12
|
+
}
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* React hook to get the on-chain fill state for an intent by its hub-chain tx hash via the swaps
|
|
17
|
+
* API — `sodax.api.swaps.getFilledIntent`. Returns
|
|
18
|
+
* `{ exists, remainingInput, receivedOutput, pendingPayment }`.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* const { data: fill } = useSwapsApiFilledIntent({ params: { txHash: '0x123...' } });
|
|
22
|
+
*/
|
|
23
|
+
export const useSwapsApiFilledIntent = ({
|
|
24
|
+
params,
|
|
25
|
+
queryOptions,
|
|
26
|
+
}: UseSwapsApiFilledIntentParams = {}): UseQueryResult<IntentStateV2 | undefined, Error> => {
|
|
27
|
+
const { sodax } = useSodaxContext();
|
|
28
|
+
const txHash = params?.txHash;
|
|
29
|
+
const apiConfig = params?.apiConfig;
|
|
30
|
+
|
|
31
|
+
return useQuery({
|
|
32
|
+
queryKey: ['swapsApi', 'filledIntent', txHash],
|
|
33
|
+
queryFn: async (): Promise<IntentStateV2 | undefined> => {
|
|
34
|
+
if (!txHash) return undefined;
|
|
35
|
+
return unwrapResult(await sodax.api.swaps.getFilledIntent(txHash, apiConfig));
|
|
36
|
+
},
|
|
37
|
+
enabled: !!txHash && txHash.length > 0,
|
|
38
|
+
retry: 3,
|
|
39
|
+
...queryOptions,
|
|
40
|
+
});
|
|
41
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type { GetIntentResponseV2, 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 UseSwapsApiIntentParams = ReadHookParams<
|
|
8
|
+
GetIntentResponseV2 | undefined,
|
|
9
|
+
{
|
|
10
|
+
txHash: string | undefined;
|
|
11
|
+
apiConfig?: RequestOverrideConfig;
|
|
12
|
+
}
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* React hook to look up an Intent struct by its hub-chain creation tx hash via the swaps API —
|
|
17
|
+
* `sodax.api.swaps.getIntent`. The decoded intent's bigint fields are returned as decimal strings.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* const { data: intent } = useSwapsApiIntent({ params: { txHash: '0x123...' } });
|
|
21
|
+
*/
|
|
22
|
+
export const useSwapsApiIntent = ({
|
|
23
|
+
params,
|
|
24
|
+
queryOptions,
|
|
25
|
+
}: UseSwapsApiIntentParams = {}): UseQueryResult<GetIntentResponseV2 | undefined, Error> => {
|
|
26
|
+
const { sodax } = useSodaxContext();
|
|
27
|
+
const txHash = params?.txHash;
|
|
28
|
+
const apiConfig = params?.apiConfig;
|
|
29
|
+
|
|
30
|
+
return useQuery({
|
|
31
|
+
queryKey: ['swapsApi', 'intent', txHash],
|
|
32
|
+
queryFn: async (): Promise<GetIntentResponseV2 | undefined> => {
|
|
33
|
+
if (!txHash) return undefined;
|
|
34
|
+
return unwrapResult(await sodax.api.swaps.getIntent(txHash, apiConfig));
|
|
35
|
+
},
|
|
36
|
+
enabled: !!txHash && txHash.length > 0,
|
|
37
|
+
retry: 3,
|
|
38
|
+
...queryOptions,
|
|
39
|
+
});
|
|
40
|
+
};
|