@tbookdev/vault-react-sui 0.1.0

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 ADDED
@@ -0,0 +1,85 @@
1
+ # @tbookdev/vault-react-sui
2
+
3
+ Headless React hooks and provider for TBook Sui vault integrations.
4
+
5
+ This package assumes your app already provides:
6
+
7
+ - `QueryClientProvider` from `@tanstack/react-query`
8
+ - `SuiClientProvider` and `WalletProvider` from `@mysten/dapp-kit`
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ pnpm add @tbookdev/vault-react-sui @tbookdev/vault-sdk-sui
14
+ ```
15
+
16
+ ## Provider
17
+
18
+ ```tsx
19
+ import { TBookSuiVaultProvider } from "@tbookdev/vault-react-sui";
20
+
21
+ export function AppProviders({ children }: { children: React.ReactNode }) {
22
+ return (
23
+ <TBookSuiVaultProvider network="testnet" vaultId="rcusdp-sui">
24
+ {children}
25
+ </TBookSuiVaultProvider>
26
+ );
27
+ }
28
+ ```
29
+
30
+ ## Hooks
31
+
32
+ ```tsx
33
+ import {
34
+ useSuiDeposit,
35
+ useSuiTransactionHistory,
36
+ useSuiUsdcBalance,
37
+ useSuiVaultBalances,
38
+ useSuiVaultInfo,
39
+ } from "@tbookdev/vault-react-sui";
40
+
41
+ function VaultPanel() {
42
+ const vaultInfo = useSuiVaultInfo();
43
+ const balances = useSuiVaultBalances();
44
+ const usdc = useSuiUsdcBalance();
45
+ const history = useSuiTransactionHistory();
46
+ const deposit = useSuiDeposit();
47
+
48
+ return (
49
+ <button onClick={() => deposit.mutate({ amount: 100_000_000n })}>
50
+ Deposit 100 USDC
51
+ </button>
52
+ );
53
+ }
54
+ ```
55
+
56
+ ## Transaction Builders
57
+
58
+ `local-sdk` builds Sui transaction bytes in the browser through
59
+ `@tbookdev/vault-sdk-sui`. It is the default on every network.
60
+
61
+ The API server base URL is selected from `network`, independent of
62
+ `txBuilderMode`: `testnet` points at the deployed sandbox Gateway API, while
63
+ `mainnet` stays empty until the production Gateway API is deployed.
64
+ If `gateway-api` is selected on a network without a configured Gateway API,
65
+ the write hook reports a configuration error only when it tries to build the
66
+ transaction through the API.
67
+
68
+ ```tsx
69
+ <TBookSuiVaultProvider network="testnet" txBuilderMode="local-sdk">
70
+ {children}
71
+ </TBookSuiVaultProvider>
72
+ ```
73
+
74
+ `gateway-api` calls the selected TBook Gateway API to build unsigned transaction
75
+ bytes, then signs and executes them with the connected Sui wallet. Select it
76
+ explicitly when you want API-built transactions.
77
+
78
+ ```tsx
79
+ <TBookSuiVaultProvider
80
+ network="testnet"
81
+ txBuilderMode="gateway-api"
82
+ >
83
+ {children}
84
+ </TBookSuiVaultProvider>
85
+ ```
package/dist/index.cjs ADDED
@@ -0,0 +1,511 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var vaultSdkSui = require('@tbookdev/vault-sdk-sui');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+ var dappKit = require('@mysten/dapp-kit');
7
+ var reactQuery = require('@tanstack/react-query');
8
+
9
+ // src/provider.tsx
10
+ var DEFAULT_STALE_TIMES = {
11
+ vaultInfo: 3e4,
12
+ balances: 1e4,
13
+ history: 1e4,
14
+ usdcBalance: 1e4
15
+ };
16
+ var DEFAULT_REFETCH_INTERVALS = {
17
+ vaultInfo: 6e4,
18
+ balances: 3e4,
19
+ history: 3e4,
20
+ usdcBalance: 3e4
21
+ };
22
+ var DEFAULT_SUI_VAULT_ID = "rcusdp-sui";
23
+ var SUI_TESTNET_GATEWAY_API_BASE_URL = "https://1cm2fjkq6k.execute-api.ap-southeast-1.amazonaws.com/v1";
24
+ function defaultGatewayApiBaseUrl(network) {
25
+ return network === "testnet" ? SUI_TESTNET_GATEWAY_API_BASE_URL : void 0;
26
+ }
27
+ function stripTrailingSlash(url) {
28
+ return url.replace(/\/+$/, "");
29
+ }
30
+ function createSuiVaultConfig(input) {
31
+ const vaultId = input.vaultId ?? DEFAULT_SUI_VAULT_ID;
32
+ const txBuilderMode = input.txBuilderMode ?? "local-sdk";
33
+ const gatewayApiBaseUrl = input.gatewayApiBaseUrl ?? defaultGatewayApiBaseUrl(input.network);
34
+ if (txBuilderMode === "custom" && !input.customTxBuilder) {
35
+ throw new Error("customTxBuilder is required when txBuilderMode is custom");
36
+ }
37
+ return {
38
+ network: input.network,
39
+ vaultId,
40
+ vault: vaultSdkSui.getSuiVaultConfig(vaultId, input.network),
41
+ txBuilderMode,
42
+ gatewayApiBaseUrl: gatewayApiBaseUrl ? stripTrailingSlash(gatewayApiBaseUrl) : void 0,
43
+ publishableKey: input.publishableKey,
44
+ customTxBuilder: input.customTxBuilder,
45
+ staleTimes: { ...DEFAULT_STALE_TIMES, ...input.staleTimes },
46
+ refetchIntervals: { ...DEFAULT_REFETCH_INTERVALS, ...input.refetchIntervals },
47
+ preflightChecks: input.preflightChecks ?? true
48
+ };
49
+ }
50
+ var TBookSuiVaultContext = react.createContext(null);
51
+ function TBookSuiVaultProvider({ children, ...input }) {
52
+ const value = react.useMemo(
53
+ () => createSuiVaultConfig(input),
54
+ [
55
+ input.network,
56
+ input.vaultId,
57
+ input.txBuilderMode,
58
+ input.gatewayApiBaseUrl,
59
+ input.publishableKey,
60
+ input.customTxBuilder,
61
+ input.preflightChecks,
62
+ input.staleTimes,
63
+ input.refetchIntervals
64
+ ]
65
+ );
66
+ return /* @__PURE__ */ jsxRuntime.jsx(TBookSuiVaultContext.Provider, { value, children });
67
+ }
68
+ function useTBookSuiVault() {
69
+ const ctx = react.useContext(TBookSuiVaultContext);
70
+ if (!ctx) {
71
+ throw new Error(
72
+ "useTBookSuiVault must be used within a <TBookSuiVaultProvider>."
73
+ );
74
+ }
75
+ return ctx;
76
+ }
77
+ function parseDecimalAmount(value, decimals = vaultSdkSui.USDC_DECIMALS) {
78
+ const input = String(value).trim();
79
+ if (!/^\d+(\.\d+)?$/.test(input)) {
80
+ throw new Error(`Invalid decimal amount: ${value}`);
81
+ }
82
+ const [whole, fraction = ""] = input.split(".");
83
+ if (fraction.length > decimals) {
84
+ throw new Error(`Amount has more than ${decimals} decimal places: ${value}`);
85
+ }
86
+ const scale = 10n ** BigInt(decimals);
87
+ return BigInt(whole) * scale + BigInt(fraction.padEnd(decimals, "0") || "0");
88
+ }
89
+ function formatRawAmount(value, decimals = vaultSdkSui.USDC_DECIMALS) {
90
+ const raw = BigInt(value);
91
+ const scale = 10n ** BigInt(decimals);
92
+ const whole = raw / scale;
93
+ const fraction = (raw % scale).toString().padStart(decimals, "0").replace(/0+$/, "");
94
+ return fraction ? `${whole}.${fraction}` : whole.toString();
95
+ }
96
+ function toRawAmount(value, decimals = vaultSdkSui.USDC_DECIMALS) {
97
+ return typeof value === "bigint" ? value : parseDecimalAmount(value, decimals);
98
+ }
99
+
100
+ // src/query-keys.ts
101
+ var ROOT = "tbook-sui";
102
+ var suiVaultQueryKeys = {
103
+ all: [ROOT],
104
+ vault: (network, vaultId) => [ROOT, "vault", network, vaultId],
105
+ vaultInfo: (network, vaultId) => [ROOT, "vault", network, vaultId, "info"],
106
+ balances: (network, vaultId, address) => [ROOT, "vault", network, vaultId, "balances", address],
107
+ history: (network, vaultId, address) => [ROOT, "vault", network, vaultId, "history", address],
108
+ usdcBalance: (network, address, coinType) => [ROOT, "wallet", network, address, "usdc", coinType]
109
+ };
110
+
111
+ // src/errors.ts
112
+ var TBookSuiVaultReactError = class extends Error {
113
+ constructor(code, message) {
114
+ super(message);
115
+ this.code = code;
116
+ this.name = "TBookSuiVaultReactError";
117
+ }
118
+ };
119
+ function walletNotConnected() {
120
+ return new TBookSuiVaultReactError("WALLET_NOT_CONNECTED", "Wallet not connected");
121
+ }
122
+
123
+ // src/gateway-api.ts
124
+ var TBookSuiGatewayApiClient = class {
125
+ baseUrl;
126
+ apiKey;
127
+ fetcher;
128
+ constructor(options) {
129
+ this.baseUrl = options.baseUrl.replace(/\/+$/, "");
130
+ this.apiKey = options.apiKey;
131
+ this.fetcher = options.fetcher ?? ((input, init) => globalThis.fetch(input, init));
132
+ }
133
+ buildDepositTx(vaultId, body) {
134
+ return this.post(`/vaults/${vaultId}/tx/deposit`, body);
135
+ }
136
+ buildRedeemTx(vaultId, body) {
137
+ return this.post(`/vaults/${vaultId}/tx/redeem`, body);
138
+ }
139
+ buildClaimTx(vaultId, body) {
140
+ return this.post(`/vaults/${vaultId}/tx/claim`, body);
141
+ }
142
+ buildCancelDepositTx(vaultId, body) {
143
+ return this.post(`/vaults/${vaultId}/tx/cancel-deposit`, body);
144
+ }
145
+ async confirmIntent(intentId, digest) {
146
+ return this.post(`/transactions/${intentId}/confirm`, { digest });
147
+ }
148
+ async post(endpoint, body) {
149
+ const response = await this.fetcher(`${this.baseUrl}${endpoint}`, {
150
+ method: "POST",
151
+ headers: this.headers(),
152
+ body: JSON.stringify(body)
153
+ });
154
+ if (!response.ok) {
155
+ const error = await response.json().catch(() => void 0);
156
+ const message = error?.error?.message ?? error?.message ?? response.statusText ?? `HTTP ${response.status}`;
157
+ throw new TBookSuiVaultReactError("API_ERROR", message);
158
+ }
159
+ return response.json();
160
+ }
161
+ headers() {
162
+ return {
163
+ "Content-Type": "application/json",
164
+ ...this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {}
165
+ };
166
+ }
167
+ };
168
+
169
+ // src/vault-info.ts
170
+ function balanceValue(value) {
171
+ return BigInt(value?.value ?? value ?? "0");
172
+ }
173
+ function boolValue(value) {
174
+ return value === true || value === "true";
175
+ }
176
+ function fieldsFromMoveObject(obj, label) {
177
+ const content = obj.data?.content;
178
+ if (!content || content.dataType !== "moveObject") {
179
+ throw new Error(`Invalid ${label} object`);
180
+ }
181
+ return content.fields;
182
+ }
183
+ async function getSuiVaultInfo(client, cfg) {
184
+ const [vaultObj, depositStateObj] = await Promise.all([
185
+ client.getObject({ id: cfg.vaultObjectId, options: { showContent: true } }),
186
+ client.getObject({ id: cfg.depositSettlementStateId, options: { showContent: true } })
187
+ ]);
188
+ const fields = fieldsFromMoveObject(vaultObj, "vault");
189
+ let depositSettlementActive = false;
190
+ try {
191
+ const depositStateFields = fieldsFromMoveObject(depositStateObj, "deposit settlement state");
192
+ depositSettlementActive = boolValue(depositStateFields.active);
193
+ } catch {
194
+ depositSettlementActive = false;
195
+ }
196
+ return {
197
+ totalShares: BigInt(fields.total_shares ?? "0"),
198
+ pendingDeposit: balanceValue(fields.pending_deposit),
199
+ claimReserve: balanceValue(fields.claim_reserve),
200
+ rcusdpCustody: balanceValue(fields.rcusdp_custody),
201
+ pendingRedeemRcusdp: balanceValue(fields.pending_redeem_rcusdp),
202
+ reserveFund: balanceValue(fields.reserve_fund),
203
+ depositFeeBps: BigInt(fields.deposit_fee_bps ?? "0"),
204
+ mgmtFeeBps: BigInt(fields.mgmt_fee_bps ?? "0"),
205
+ redeemFeeBps: BigInt(fields.redeem_fee_bps ?? "0"),
206
+ withdrawFeeBps: BigInt(fields.withdraw_fee_bps ?? "0"),
207
+ cancelDepositFeeBps: BigInt(fields.cancel_deposit_fee_bps ?? "0"),
208
+ instantRedeemFeeBps: BigInt(fields.instant_redeem_fee_bps ?? "0"),
209
+ paused: boolValue(fields.paused),
210
+ version: BigInt(fields.version ?? "1"),
211
+ depositEnabled: !depositSettlementActive,
212
+ instantRedeemEnabled: boolValue(fields.instant_redeem_enabled),
213
+ withdrawRcusdpEnabled: boolValue(fields.withdraw_rcusdp_enabled),
214
+ cancelDepositEnabled: boolValue(fields.cancel_deposit_enabled),
215
+ redeemSettled: boolValue(fields.redeem_settled),
216
+ raw: fields
217
+ };
218
+ }
219
+
220
+ // src/hooks/use-vault-config.ts
221
+ var useSuiVaultConfig = useTBookSuiVault;
222
+ function useSuiVaultInfo(options) {
223
+ const client = dappKit.useSuiClient();
224
+ const config = useTBookSuiVault();
225
+ return reactQuery.useQuery({
226
+ queryKey: suiVaultQueryKeys.vaultInfo(config.network, config.vaultId),
227
+ queryFn: () => getSuiVaultInfo(client, config.vault),
228
+ staleTime: config.staleTimes.vaultInfo,
229
+ refetchInterval: config.refetchIntervals.vaultInfo,
230
+ enabled: Boolean(config.vault.vaultObjectId) && (options?.enabled ?? true),
231
+ ...options
232
+ });
233
+ }
234
+ function useSuiVaultBalances(options) {
235
+ const account = dappKit.useCurrentAccount();
236
+ const client = dappKit.useSuiClient();
237
+ const config = useTBookSuiVault();
238
+ return reactQuery.useQuery({
239
+ queryKey: suiVaultQueryKeys.balances(config.network, config.vaultId, account?.address ?? ""),
240
+ queryFn: async () => {
241
+ if (!account?.address) {
242
+ throw new Error("Wallet not connected");
243
+ }
244
+ return vaultSdkSui.getUserPosition(client, config.vault, account.address);
245
+ },
246
+ enabled: Boolean(account?.address) && (options?.enabled ?? true),
247
+ staleTime: config.staleTimes.balances,
248
+ refetchInterval: config.refetchIntervals.balances,
249
+ ...options
250
+ });
251
+ }
252
+ function useSuiTransactionHistory(options) {
253
+ const account = dappKit.useCurrentAccount();
254
+ const client = dappKit.useSuiClient();
255
+ const config = useTBookSuiVault();
256
+ return reactQuery.useQuery({
257
+ queryKey: suiVaultQueryKeys.history(config.network, config.vaultId, account?.address ?? ""),
258
+ queryFn: async () => {
259
+ if (!account?.address) return [];
260
+ return vaultSdkSui.getUserRecords(client, config.vault, account.address);
261
+ },
262
+ enabled: Boolean(account?.address) && (options?.enabled ?? true),
263
+ staleTime: config.staleTimes.history,
264
+ refetchInterval: config.refetchIntervals.history,
265
+ ...options
266
+ });
267
+ }
268
+ function useSuiUsdcBalance(options) {
269
+ const account = dappKit.useCurrentAccount();
270
+ const client = dappKit.useSuiClient();
271
+ const config = useTBookSuiVault();
272
+ const query = reactQuery.useQuery({
273
+ queryKey: suiVaultQueryKeys.usdcBalance(
274
+ config.network,
275
+ account?.address ?? "",
276
+ config.vault.usdcType
277
+ ),
278
+ queryFn: async () => {
279
+ if (!account?.address) {
280
+ throw new Error("Wallet not connected");
281
+ }
282
+ return client.getBalance({ owner: account.address, coinType: config.vault.usdcType });
283
+ },
284
+ enabled: Boolean(account?.address) && (options?.enabled ?? true),
285
+ staleTime: config.staleTimes.usdcBalance,
286
+ refetchInterval: config.refetchIntervals.usdcBalance,
287
+ ...options
288
+ });
289
+ const balance = BigInt(query.data?.totalBalance ?? "0");
290
+ return {
291
+ ...query,
292
+ balance,
293
+ decimals: vaultSdkSui.USDC_DECIMALS,
294
+ formatted: formatRawAmount(balance, vaultSdkSui.USDC_DECIMALS)
295
+ };
296
+ }
297
+ function useRefreshSuiVaultData() {
298
+ const account = dappKit.useCurrentAccount();
299
+ const queryClient = reactQuery.useQueryClient();
300
+ const config = useTBookSuiVault();
301
+ return async () => {
302
+ await Promise.all([
303
+ queryClient.invalidateQueries({
304
+ queryKey: suiVaultQueryKeys.vault(config.network, config.vaultId)
305
+ }),
306
+ account?.address ? queryClient.invalidateQueries({
307
+ queryKey: suiVaultQueryKeys.balances(config.network, config.vaultId, account.address)
308
+ }) : Promise.resolve(),
309
+ account?.address ? queryClient.invalidateQueries({
310
+ queryKey: suiVaultQueryKeys.history(config.network, config.vaultId, account.address)
311
+ }) : Promise.resolve(),
312
+ account?.address ? queryClient.invalidateQueries({
313
+ queryKey: suiVaultQueryKeys.usdcBalance(
314
+ config.network,
315
+ account.address,
316
+ config.vault.usdcType
317
+ )
318
+ }) : Promise.resolve()
319
+ ]);
320
+ };
321
+ }
322
+ function redeemMode(params) {
323
+ if (params.mode) return params.mode;
324
+ return params.tokenType === "RCUSDP" ? "instant" : "queued";
325
+ }
326
+ async function executeTx(signAndExecuteTransaction, result) {
327
+ return signAndExecuteTransaction({ transaction: result.txBytesBase64 });
328
+ }
329
+ function gatewayClient(config) {
330
+ if (!config.gatewayApiBaseUrl) {
331
+ throw new TBookSuiVaultReactError(
332
+ "CONFIGURATION_ERROR",
333
+ "gatewayApiBaseUrl is required for gateway-api transaction building"
334
+ );
335
+ }
336
+ return new TBookSuiGatewayApiClient({
337
+ baseUrl: config.gatewayApiBaseUrl,
338
+ apiKey: config.publishableKey
339
+ });
340
+ }
341
+ function assertVaultCanDeposit(info) {
342
+ if (!info) return;
343
+ if (info.paused) throw new TBookSuiVaultReactError("VAULT_PAUSED", "Vault is paused");
344
+ if (!info.depositEnabled) {
345
+ throw new TBookSuiVaultReactError("SETTLEMENT_ACTIVE", "Deposits are temporarily unavailable");
346
+ }
347
+ }
348
+ function assertVaultCanRedeem(info) {
349
+ if (!info) return;
350
+ if (info.paused) throw new TBookSuiVaultReactError("VAULT_PAUSED", "Vault is paused");
351
+ }
352
+ function assertVaultCanCancel(info) {
353
+ if (!info) return;
354
+ if (info.paused) throw new TBookSuiVaultReactError("VAULT_PAUSED", "Vault is paused");
355
+ if (!info.cancelDepositEnabled) {
356
+ throw new TBookSuiVaultReactError("SETTLEMENT_ACTIVE", "Cancel deposit is unavailable");
357
+ }
358
+ }
359
+ function useSuiDeposit() {
360
+ const account = dappKit.useCurrentAccount();
361
+ const client = dappKit.useSuiClient();
362
+ const config = useTBookSuiVault();
363
+ const { mutateAsync: signAndExecuteTransaction } = dappKit.useSignAndExecuteTransaction();
364
+ const refresh = useRefreshSuiVaultData();
365
+ const { data: vaultInfo } = useSuiVaultInfo({ enabled: config.preflightChecks });
366
+ return reactQuery.useMutation({
367
+ mutationFn: async ({ amount }) => {
368
+ if (!account?.address) throw walletNotConnected();
369
+ if (config.preflightChecks) assertVaultCanDeposit(vaultInfo);
370
+ const raw = toRawAmount(amount);
371
+ if (config.txBuilderMode === "gateway-api") {
372
+ const api = gatewayClient(config);
373
+ const response = await api.buildDepositTx(config.vaultId, {
374
+ user: account.address,
375
+ amount: formatRawAmount(raw)
376
+ });
377
+ const tx = await signAndExecuteTransaction({ transaction: response.transaction.data });
378
+ if (response.intentId && tx.digest) {
379
+ await api.confirmIntent(response.intentId, tx.digest);
380
+ }
381
+ return tx;
382
+ }
383
+ const result = config.txBuilderMode === "custom" ? await config.customTxBuilder?.buildDepositTx?.({ sender: account.address, amount: raw }) : await vaultSdkSui.buildDepositTx(client, config.vault, { sender: account.address, amount: raw });
384
+ if (!result) {
385
+ throw new TBookSuiVaultReactError("UNSUPPORTED_TX_BUILDER", "Deposit builder is not configured");
386
+ }
387
+ return executeTx(signAndExecuteTransaction, result);
388
+ },
389
+ onSuccess: refresh
390
+ });
391
+ }
392
+ function useSuiRedeem() {
393
+ const account = dappKit.useCurrentAccount();
394
+ const client = dappKit.useSuiClient();
395
+ const config = useTBookSuiVault();
396
+ const { mutateAsync: signAndExecuteTransaction } = dappKit.useSignAndExecuteTransaction();
397
+ const refresh = useRefreshSuiVaultData();
398
+ const { data: vaultInfo } = useSuiVaultInfo({ enabled: config.preflightChecks });
399
+ return reactQuery.useMutation({
400
+ mutationFn: async (params) => {
401
+ if (!account?.address) throw walletNotConnected();
402
+ if (config.preflightChecks) assertVaultCanRedeem(vaultInfo);
403
+ const mode = redeemMode(params);
404
+ const shares = toRawAmount(params.shares);
405
+ if (config.txBuilderMode === "gateway-api") {
406
+ const api = gatewayClient(config);
407
+ const response = await api.buildRedeemTx(config.vaultId, {
408
+ user: account.address,
409
+ shares: formatRawAmount(shares),
410
+ mode
411
+ });
412
+ const tx = await signAndExecuteTransaction({ transaction: response.transaction.data });
413
+ if (response.intentId && tx.digest) {
414
+ await api.confirmIntent(response.intentId, tx.digest);
415
+ }
416
+ return tx;
417
+ }
418
+ const result = config.txBuilderMode === "custom" ? mode === "instant" ? await config.customTxBuilder?.buildInstantRedeemTx?.({ sender: account.address, shares }) : await config.customTxBuilder?.buildQueueRedeemTx?.({ sender: account.address, shares }) : mode === "instant" ? await vaultSdkSui.buildInstantRedeemTx(client, config.vault, { sender: account.address, shares }) : await vaultSdkSui.buildQueueRedeemTx(client, config.vault, { sender: account.address, shares });
419
+ if (!result) {
420
+ throw new TBookSuiVaultReactError("UNSUPPORTED_TX_BUILDER", "Redeem builder is not configured");
421
+ }
422
+ return executeTx(signAndExecuteTransaction, result);
423
+ },
424
+ onSuccess: refresh
425
+ });
426
+ }
427
+ function useSuiClaim() {
428
+ const account = dappKit.useCurrentAccount();
429
+ const client = dappKit.useSuiClient();
430
+ const config = useTBookSuiVault();
431
+ const { mutateAsync: signAndExecuteTransaction } = dappKit.useSignAndExecuteTransaction();
432
+ const refresh = useRefreshSuiVaultData();
433
+ return reactQuery.useMutation({
434
+ mutationFn: async (params) => {
435
+ if (!account?.address) throw walletNotConnected();
436
+ const amount = params?.amount === void 0 ? void 0 : toRawAmount(params.amount);
437
+ if (config.txBuilderMode === "gateway-api") {
438
+ const api = gatewayClient(config);
439
+ const response = await api.buildClaimTx(config.vaultId, { user: account.address });
440
+ const tx = await signAndExecuteTransaction({ transaction: response.transaction.data });
441
+ if (response.intentId && tx.digest) {
442
+ await api.confirmIntent(response.intentId, tx.digest);
443
+ }
444
+ return tx;
445
+ }
446
+ const result = config.txBuilderMode === "custom" ? await config.customTxBuilder?.buildClaimTx?.({ sender: account.address, amount }) : await vaultSdkSui.buildClaimTx(client, config.vault, { sender: account.address, amount });
447
+ if (!result) {
448
+ throw new TBookSuiVaultReactError("UNSUPPORTED_TX_BUILDER", "Claim builder is not configured");
449
+ }
450
+ return executeTx(signAndExecuteTransaction, result);
451
+ },
452
+ onSuccess: refresh
453
+ });
454
+ }
455
+ function useSuiCancelDeposit() {
456
+ const account = dappKit.useCurrentAccount();
457
+ const client = dappKit.useSuiClient();
458
+ const config = useTBookSuiVault();
459
+ const { mutateAsync: signAndExecuteTransaction } = dappKit.useSignAndExecuteTransaction();
460
+ const refresh = useRefreshSuiVaultData();
461
+ const { data: vaultInfo } = useSuiVaultInfo({ enabled: config.preflightChecks });
462
+ return reactQuery.useMutation({
463
+ mutationFn: async ({ recordId }) => {
464
+ if (!account?.address) throw walletNotConnected();
465
+ if (config.preflightChecks) assertVaultCanCancel(vaultInfo);
466
+ if (config.txBuilderMode === "gateway-api") {
467
+ const api = gatewayClient(config);
468
+ const response = await api.buildCancelDepositTx(config.vaultId, {
469
+ user: account.address,
470
+ recordId: String(recordId)
471
+ });
472
+ const tx = await signAndExecuteTransaction({ transaction: response.transaction.data });
473
+ if (response.intentId && tx.digest) {
474
+ await api.confirmIntent(response.intentId, tx.digest);
475
+ }
476
+ return tx;
477
+ }
478
+ const result = config.txBuilderMode === "custom" ? await config.customTxBuilder?.buildCancelDepositTx?.({ sender: account.address, recordId }) : await vaultSdkSui.buildCancelDepositTx(client, config.vault, { sender: account.address, recordId });
479
+ if (!result) {
480
+ throw new TBookSuiVaultReactError("UNSUPPORTED_TX_BUILDER", "Cancel deposit builder is not configured");
481
+ }
482
+ return executeTx(signAndExecuteTransaction, result);
483
+ },
484
+ onSuccess: refresh
485
+ });
486
+ }
487
+
488
+ exports.DEFAULT_SUI_VAULT_ID = DEFAULT_SUI_VAULT_ID;
489
+ exports.SUI_TESTNET_GATEWAY_API_BASE_URL = SUI_TESTNET_GATEWAY_API_BASE_URL;
490
+ exports.TBookSuiGatewayApiClient = TBookSuiGatewayApiClient;
491
+ exports.TBookSuiVaultProvider = TBookSuiVaultProvider;
492
+ exports.TBookSuiVaultReactError = TBookSuiVaultReactError;
493
+ exports.createSuiVaultConfig = createSuiVaultConfig;
494
+ exports.formatRawAmount = formatRawAmount;
495
+ exports.getSuiVaultInfo = getSuiVaultInfo;
496
+ exports.parseDecimalAmount = parseDecimalAmount;
497
+ exports.suiVaultQueryKeys = suiVaultQueryKeys;
498
+ exports.toRawAmount = toRawAmount;
499
+ exports.useRefreshSuiVaultData = useRefreshSuiVaultData;
500
+ exports.useSuiCancelDeposit = useSuiCancelDeposit;
501
+ exports.useSuiClaim = useSuiClaim;
502
+ exports.useSuiDeposit = useSuiDeposit;
503
+ exports.useSuiRedeem = useSuiRedeem;
504
+ exports.useSuiTransactionHistory = useSuiTransactionHistory;
505
+ exports.useSuiUsdcBalance = useSuiUsdcBalance;
506
+ exports.useSuiVaultBalances = useSuiVaultBalances;
507
+ exports.useSuiVaultConfig = useSuiVaultConfig;
508
+ exports.useSuiVaultInfo = useSuiVaultInfo;
509
+ exports.useTBookSuiVault = useTBookSuiVault;
510
+ //# sourceMappingURL=index.cjs.map
511
+ //# sourceMappingURL=index.cjs.map