@silentswap/react 0.1.49 → 0.1.51

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.
@@ -1,5 +1,5 @@
1
1
  import { useCallback, useState } from 'react';
2
- import { isSolanaAsset, isBitcoinAsset, parseEvmCaip19, S_CAIP19_USDC_AVALANCHE, getAssetByCaip19, solveOptimalUsdcAmount, N_RELAY_CHAIN_ID_SOLANA, N_RELAY_CHAIN_ID_BITCOIN, SB58_ADDR_SOL_PROGRAM_SYSTEM, isSolanaNativeToken, parseSolanaCaip19, EVM_PHONY_ADDRESS, isValidSolanaAddress, isValidBitcoinAddress, isValidEvmAddress, getAddressFromCaip10, S0X_ADDR_USDC_AVALANCHE, caip19FungibleEvmToken, FacilitatorKeyType, createHdFacilitatorGroupFromEntropy, PublicKeyArgGroups, SB58_CHAIN_ID_SOLANA_MAINNET, caip19SplToken, DeliveryMethod, X_MAX_IMPACT_PERCENT, SBTC_ADDR_BITCOIN_NATIVE, isEvmAsset, } from '@silentswap/sdk';
2
+ import { isSolanaAsset, isBitcoinAsset, isTronAsset, parseEvmCaip19, S_CAIP19_USDC_AVALANCHE, getAssetByCaip19, solveOptimalUsdcAmount, N_RELAY_CHAIN_ID_SOLANA, N_RELAY_CHAIN_ID_BITCOIN, N_RELAY_CHAIN_ID_TRON, SB58_ADDR_SOL_PROGRAM_SYSTEM, isSolanaNativeToken, parseSolanaCaip19, parseTronCaip19, EVM_PHONY_ADDRESS, isValidSolanaAddress, isValidBitcoinAddress, isValidEvmAddress, isValidTronAddress, getAddressFromCaip10, S0X_ADDR_USDC_AVALANCHE, caip19FungibleEvmToken, FacilitatorKeyType, createHdFacilitatorGroupFromEntropy, PublicKeyArgGroups, SB58_CHAIN_ID_SOLANA_MAINNET, caip19SplToken, DeliveryMethod, X_MAX_IMPACT_PERCENT, SBTC_ADDR_BITCOIN_NATIVE, S0X_ADDR_TRON_NATIVE, isEvmAsset, } from '@silentswap/sdk';
3
3
  import { getAddress } from 'viem';
4
4
  import { BigNumber } from 'bignumber.js';
5
5
  /**
@@ -13,7 +13,7 @@ import { BigNumber } from 'bignumber.js';
13
13
  * - Destination amount updates
14
14
  */
15
15
  // TODO: Simplify this hook by removing the useCallback and useState and just returning the calculateQuote function.
16
- export function useQuoteCalculation({ address, evmAddress, wallet, depositorAddress, getQuote, getPrice, setDestinations, proId, forceBridgeProvider, }) {
16
+ export function useQuoteCalculation({ address, evmAddress, wallet, depositorAddress, getQuote, getPrice, setDestinations, proId, tronAddress, forceBridgeProvider, }) {
17
17
  const [loadingAmounts, setLoadingAmounts] = useState(false);
18
18
  const [depositAmountUsdc, setDepositAmountUsdc] = useState(0);
19
19
  const calculateQuote = useCallback(async (debouncedSourceAsset, debouncedSourceAmount, destinations, splits) => {
@@ -30,6 +30,7 @@ export function useQuoteCalculation({ address, evmAddress, wallet, depositorAddr
30
30
  const isSourceUsdcAvalanche = debouncedSourceAsset === S_CAIP19_USDC_AVALANCHE;
31
31
  const isSourceSolana = isSolanaAsset(debouncedSourceAsset);
32
32
  const isSourceBitcoin = isBitcoinAsset(debouncedSourceAsset);
33
+ const isSourceTron = isTronAsset(debouncedSourceAsset);
33
34
  let usdcAmountOut;
34
35
  let sourceAmountInUnitsForQuote;
35
36
  let bridgeProviderResult = 'none';
@@ -40,6 +41,7 @@ export function useQuoteCalculation({ address, evmAddress, wallet, depositorAddr
40
41
  isSourceUsdcAvalanche,
41
42
  isSourceSolana,
42
43
  isSourceBitcoin,
44
+ isSourceTron,
43
45
  destinationsCount: destinations.length,
44
46
  splits,
45
47
  });
@@ -131,6 +133,31 @@ export function useQuoteCalculation({ address, evmAddress, wallet, depositorAddr
131
133
  bridgeProviderResult = solveResult.provider;
132
134
  allowanceTargetResult = solveResult.allowanceTarget;
133
135
  }
136
+ else if (isSourceTron) {
137
+ const assetInfo = getAssetByCaip19(debouncedSourceAsset);
138
+ if (!assetInfo)
139
+ throw new Error(`Tron asset not found`);
140
+ const tronParsed = parseTronCaip19(debouncedSourceAsset);
141
+ if (!tronParsed)
142
+ throw new Error(`Invalid Tron CAIP-19 format: ${debouncedSourceAsset}`);
143
+ const sourceAmountBN = BigNumber(debouncedSourceAmount);
144
+ sourceAmountInUnitsForQuote = sourceAmountBN.shiftedBy(assetInfo.decimals).toFixed(0);
145
+ if (!evmAddress) {
146
+ throw new Error('EVM address required for Tron swaps (needed for deposit calldata and recipient)');
147
+ }
148
+ const tronSenderAddress = typeof address === 'string' && !address.startsWith('0x') ? address : null;
149
+ if (!tronSenderAddress) {
150
+ throw new Error('Tron address required for Tron swaps');
151
+ }
152
+ const solveResult = await solveOptimalUsdcAmount(N_RELAY_CHAIN_ID_TRON, tronParsed.isNative ? S0X_ADDR_TRON_NATIVE : (tronParsed.tokenAddress || S0X_ADDR_TRON_NATIVE), sourceAmountInUnitsForQuote, tronSenderAddress, undefined, X_MAX_IMPACT_PERCENT, depositorAddress, getAddress(evmAddress), forceBridgeProvider);
153
+ if (abortController.signal.aborted) {
154
+ setLoadingAmounts(false);
155
+ return null;
156
+ }
157
+ usdcAmountOut = solveResult.usdcAmountOut.toString();
158
+ bridgeProviderResult = solveResult.provider;
159
+ allowanceTargetResult = solveResult.allowanceTarget;
160
+ }
134
161
  else {
135
162
  // EVM assets
136
163
  const sourceAssetParsed = parseEvmCaip19(debouncedSourceAsset);
@@ -200,8 +227,9 @@ export function useQuoteCalculation({ address, evmAddress, wallet, depositorAddr
200
227
  }
201
228
  const isDestSolana = isSolanaAsset(dest.asset);
202
229
  const isDestBitcoin = isBitcoinAsset(dest.asset);
230
+ const isDestTron = isTronAsset(dest.asset);
203
231
  let asset;
204
- let recipientAddress; // Changed from `0x${string}` to string to support Solana and Bitcoin addresses
232
+ let recipientAddress; // Includes Solana, Bitcoin, Tron, and EVM addresses
205
233
  if (isDestSolana) {
206
234
  // Solana destination
207
235
  const destParsed = parseSolanaCaip19(dest.asset);
@@ -265,6 +293,40 @@ export function useQuoteCalculation({ address, evmAddress, wallet, depositorAddr
265
293
  throw new Error(`Bitcoin destination ${idx} requires a recipient address in the contact field`);
266
294
  }
267
295
  }
296
+ else if (isDestTron) {
297
+ asset = dest.asset;
298
+ if (dest.contact) {
299
+ if (dest.contact.startsWith('caip10:tron:')) {
300
+ recipientAddress = getAddressFromCaip10(dest.contact);
301
+ if (!(isValidTronAddress(recipientAddress) && recipientAddress !== S0X_ADDR_TRON_NATIVE)) {
302
+ throw new Error(`Invalid Tron address extracted from CAIP10: ${dest.contact} -> ${recipientAddress}`);
303
+ }
304
+ }
305
+ else if (isValidTronAddress(dest.contact) && dest.contact !== S0X_ADDR_TRON_NATIVE) {
306
+ recipientAddress = dest.contact;
307
+ }
308
+ else {
309
+ if (tronAddress && isValidTronAddress(tronAddress) && tronAddress !== S0X_ADDR_TRON_NATIVE) {
310
+ console.warn(`[SilentSwap:QuoteCalc] Invalid Tron destination contact for index ${idx}, falling back to connected Tron address`, {
311
+ contact: dest.contact,
312
+ tronAddress,
313
+ });
314
+ recipientAddress = tronAddress;
315
+ }
316
+ else {
317
+ throw new Error(`Invalid Tron recipient address for destination ${idx}: ${dest.contact}. Expected Tron address or caip10:tron:*: format.`);
318
+ }
319
+ }
320
+ }
321
+ else {
322
+ if (tronAddress && isValidTronAddress(tronAddress) && tronAddress !== S0X_ADDR_TRON_NATIVE) {
323
+ recipientAddress = tronAddress;
324
+ }
325
+ else {
326
+ throw new Error(`Tron destination ${idx} requires a recipient address in the contact field`);
327
+ }
328
+ }
329
+ }
268
330
  else {
269
331
  // EVM destination (including XRPL which uses eip155 namespace)
270
332
  const destParsed = parseEvmCaip19(dest.asset);
@@ -345,7 +407,12 @@ export function useQuoteCalculation({ address, evmAddress, wallet, depositorAddr
345
407
  throw new Error(`Invalid recipient address type for Bitcoin destination ${idx}: ${recipientAddress}. Expected Bitcoin address (bc1, 1, or 3 prefix).`);
346
408
  }
347
409
  }
348
- else if (!isDestSolana && !isDestBitcoin) {
410
+ else if (isDestTron) {
411
+ if (!(isValidTronAddress(recipientAddress) && recipientAddress !== S0X_ADDR_TRON_NATIVE)) {
412
+ throw new Error(`Invalid recipient address type for Tron destination ${idx}: ${recipientAddress}. Expected Tron address.`);
413
+ }
414
+ }
415
+ else if (!isDestSolana && !isDestBitcoin && !isDestTron) {
349
416
  // Validate EVM address format
350
417
  if (isEvmAsset(dest.asset) && !isValidEvmAddress(recipientAddress)) {
351
418
  throw new Error(`Invalid recipient address type for EVM destination ${idx}: ${recipientAddress}. Expected 0x-prefixed EVM address.`);
@@ -460,7 +527,7 @@ export function useQuoteCalculation({ address, evmAddress, wallet, depositorAddr
460
527
  // Always ensure loading state is reset (safety net)
461
528
  setLoadingAmounts(false);
462
529
  }
463
- }, [wallet, address, evmAddress, getQuote, getPrice, setDestinations, depositorAddress, proId]);
530
+ }, [wallet, address, evmAddress, getQuote, getPrice, setDestinations, depositorAddress, proId, tronAddress, forceBridgeProvider]);
464
531
  return {
465
532
  calculateQuote,
466
533
  loadingAmounts,
@@ -3,6 +3,7 @@ import type { WalletClient } from 'viem';
3
3
  import type { Connector } from 'wagmi';
4
4
  import type { SolanaWalletConnector, SolanaConnection } from './solana-transaction.js';
5
5
  import type { BitcoinWalletConnector, BitcoinConnection } from './bitcoin-transaction.js';
6
+ import type { TronWalletConnector, TronConnection } from './tron-transaction.js';
6
7
  import { type SwapTransaction } from '../useTransaction.js';
7
8
  import type { SilentSwapWallet } from './useWallet.js';
8
9
  export type { SwapTransaction };
@@ -63,6 +64,12 @@ export interface useSilentQuoteOptions {
63
64
  bitcoinConnector?: BitcoinWalletConnector;
64
65
  /** Bitcoin connection (optional, for consistency) */
65
66
  bitcoinConnection?: BitcoinConnection;
67
+ /** Tron wallet connector (required for Tron swaps) */
68
+ tronConnector?: TronWalletConnector;
69
+ /** Tron connection (optional, for consistency) */
70
+ tronConnection?: TronConnection;
71
+ /** Connected Tron address used for Tron destination recipient fallback. */
72
+ tronAddress?: string;
66
73
  /** Get price function */
67
74
  getPrice: (asset: AssetInfo) => Promise<number>;
68
75
  setDestinations: (updater: Destination[] | ((prev: Destination[]) => Destination[])) => void;
@@ -105,4 +112,4 @@ export interface ExecuteSwapParams {
105
112
  /** Optional integrator ID for tracking */
106
113
  integratorId?: string;
107
114
  }
108
- export declare function useSilentQuote({ client, address, evmAddress, solAddress, walletClient, connector, auth, authenticate, wallet, walletLoading, walletError, generateWallet, requestWalletConnect, onStatus, solanaConnector, solanaConnection, solanaRpcUrl, bitcoinConnector, bitcoinConnection, getPrice, setDestinations, proId, forceBridgeProvider, }: useSilentQuoteOptions): useSilentQuoteReturn;
115
+ export declare function useSilentQuote({ client, address, evmAddress, solAddress, walletClient, connector, auth, authenticate, wallet, walletLoading, walletError, generateWallet, requestWalletConnect, onStatus, solanaConnector, solanaConnection, solanaRpcUrl, bitcoinConnector, bitcoinConnection, tronConnector, tronConnection, tronAddress, getPrice, setDestinations, proId, forceBridgeProvider, }: useSilentQuoteOptions): useSilentQuoteReturn;
@@ -1,12 +1,12 @@
1
1
  import { useCallback, useMemo, useState, useRef, useEffect } from 'react';
2
- import { hexToBase58, isSolanaAsset, isBitcoinAsset, parseEvmCaip19, S_CAIP19_USDC_AVALANCHE, NI_CHAIN_ID_AVALANCHE, } from '@silentswap/sdk';
2
+ import { hexToBase58, isSolanaAsset, isBitcoinAsset, isTronAsset, parseEvmCaip19, S_CAIP19_USDC_AVALANCHE, NI_CHAIN_ID_AVALANCHE, } from '@silentswap/sdk';
3
3
  import { getAddress } from 'viem';
4
4
  import { useQuoteFetching } from './useQuoteFetching.js';
5
5
  import { useOrderSigning } from './useOrderSigning.js';
6
6
  import { APPROVE_POST_DELAY_MS, useBridgeExecution } from './useBridgeExecution.js';
7
7
  import { useTransaction } from '../useTransaction.js';
8
8
  import { useQuoteCalculation } from './useQuoteCalculation.js';
9
- export function useSilentQuote({ client, address, evmAddress, solAddress, walletClient, connector, auth, authenticate, wallet, walletLoading = false, walletError = null, generateWallet, requestWalletConnect, onStatus, solanaConnector, solanaConnection, solanaRpcUrl, bitcoinConnector, bitcoinConnection, getPrice, setDestinations, proId, forceBridgeProvider, }) {
9
+ export function useSilentQuote({ client, address, evmAddress, solAddress, walletClient, connector, auth, authenticate, wallet, walletLoading = false, walletError = null, generateWallet, requestWalletConnect, onStatus, solanaConnector, solanaConnection, solanaRpcUrl, bitcoinConnector, bitcoinConnection, tronConnector, tronConnection, tronAddress, getPrice, setDestinations, proId, forceBridgeProvider, }) {
10
10
  const [isLoading, setIsLoading] = useState(false);
11
11
  const [currentStep, setCurrentStep] = useState('');
12
12
  const [quote, setQuote] = useState(null);
@@ -57,7 +57,7 @@ export function useSilentQuote({ client, address, evmAddress, solAddress, wallet
57
57
  // Initialize specialized hooks
58
58
  const { getQuote: getQuoteInternal } = useQuoteFetching(client, rawAddress, setIsLoading, setCurrentStep, setError, onStatus);
59
59
  const { signAuthorizations, createOrder } = useOrderSigning(walletClient, connector, client, setCurrentStep, onStatus);
60
- const { executeSolanaBridge, executeBitcoinBridge, executeEvmBridge } = useBridgeExecution(walletClient, connector, solanaConnector, solanaConnection, solanaRpcUrl, setCurrentStep, depositorAddress, onStatus, bitcoinConnector, bitcoinConnection);
60
+ const { executeSolanaBridge, executeBitcoinBridge, executeTronBridge, executeEvmBridge } = useBridgeExecution(walletClient, connector, solanaConnector, solanaConnection, solanaRpcUrl, setCurrentStep, depositorAddress, onStatus, bitcoinConnector, bitcoinConnection, tronConnector, tronConnection);
61
61
  const { executeSwapTransaction, approveTokenSpending } = useTransaction({
62
62
  address: normalizedAddress || '0x0000000000000000000000000000000000000000',
63
63
  walletClient,
@@ -65,6 +65,10 @@ export function useSilentQuote({ client, address, evmAddress, solAddress, wallet
65
65
  solanaConnector,
66
66
  solanaConnection,
67
67
  solanaRpcUrl,
68
+ bitcoinConnector,
69
+ bitcoinConnection,
70
+ tronConnector,
71
+ tronConnection,
68
72
  setCurrentStep,
69
73
  onStatus,
70
74
  });
@@ -90,6 +94,7 @@ export function useSilentQuote({ client, address, evmAddress, solAddress, wallet
90
94
  getPrice,
91
95
  setDestinations,
92
96
  proId,
97
+ tronAddress,
93
98
  forceBridgeProvider,
94
99
  });
95
100
  /**
@@ -268,8 +273,9 @@ export function useSilentQuote({ client, address, evmAddress, solAddress, wallet
268
273
  // Check swap type
269
274
  const isSourceSolana = isSolanaAsset(sourceAsset);
270
275
  const isSourceBitcoin = isBitcoinAsset(sourceAsset);
276
+ const isSourceTron = isTronAsset(sourceAsset);
271
277
  const isDepositingDirectly = sourceAsset === S_CAIP19_USDC_AVALANCHE;
272
- const isSourceEvm = !isSourceSolana && !isSourceBitcoin && !isDepositingDirectly && sourceAsset.startsWith('eip155:');
278
+ const isSourceEvm = !isSourceSolana && !isSourceBitcoin && !isSourceTron && !isDepositingDirectly && sourceAsset.startsWith('eip155:');
273
279
  // Generate viewing authorization
274
280
  const viewer = await resolvedGroup.viewer();
275
281
  const evmSigner = await viewer.evmSigner();
@@ -292,7 +298,7 @@ export function useSilentQuote({ client, address, evmAddress, solAddress, wallet
292
298
  viewingAuth,
293
299
  provider: providerForSwap,
294
300
  });
295
- const result = await executeSolanaSwap(quoteResponse, sourceAsset, sourceAmountInUnits, effectiveUsdcAmount, senderContactId, solanaConnector, evmSignerAddress, viewingAuth, createOrder, executeSolanaBridge, resolvedGroup, integratorId);
301
+ const result = await executeSolanaSwap(quoteResponse, sourceAsset, sourceAmountInUnits, effectiveUsdcAmount, senderContactId, solanaConnector, evmSignerAddress, viewingAuth, createOrder, executeSolanaBridge, resolvedGroup, providerForSwap, integratorId);
296
302
  setOrderId(result.orderId);
297
303
  setViewingAuth(result.viewingAuth);
298
304
  return result;
@@ -306,6 +312,13 @@ export function useSilentQuote({ client, address, evmAddress, solAddress, wallet
306
312
  setViewingAuth(result.viewingAuth);
307
313
  return result;
308
314
  }
315
+ // Handle Tron swaps
316
+ if (isSourceTron) {
317
+ const result = await executeTronSwap(quoteResponse, sourceAsset, sourceAmountInUnits, effectiveUsdcAmount, senderContactId, tronConnector, evmSignerAddress, viewingAuth, createOrder, executeTronBridge, resolvedGroup, providerForSwap, integratorId);
318
+ setOrderId(result.orderId);
319
+ setViewingAuth(result.viewingAuth);
320
+ return result;
321
+ }
309
322
  // Sign authorizations (for EVM swaps)
310
323
  const signedAuths = await signAuthorizations(quoteResponse.authorizations, isDepositingDirectly);
311
324
  // Create order with resolved facilitator group
@@ -389,10 +402,13 @@ export function useSilentQuote({ client, address, evmAddress, solAddress, wallet
389
402
  generateWallet,
390
403
  solanaConnector,
391
404
  bitcoinConnector,
405
+ tronConnector,
392
406
  signAuthorizations,
393
407
  createOrder,
394
408
  approveTokenSpending,
395
409
  executeSolanaBridge,
410
+ executeBitcoinBridge,
411
+ executeTronBridge,
396
412
  executeEvmBridge,
397
413
  executeSwapTransaction,
398
414
  calculateQuote,
@@ -433,7 +449,7 @@ export function useSilentQuote({ client, address, evmAddress, solAddress, wallet
433
449
  * 4. Returns swap result
434
450
  */
435
451
  async function executeSolanaSwap(quoteResponse, sourceAsset, sourceAmount, usdcAmount, senderContactId, solanaConnector, evmSignerAddress, // EVM signer address (matches Svelte's s0x_signer)
436
- viewingAuth, createOrder, executeSolanaBridge, facilitatorGroup, integratorId) {
452
+ viewingAuth, createOrder, executeSolanaBridge, facilitatorGroup, provider, integratorId) {
437
453
  if (!solanaConnector) {
438
454
  throw new Error('Solana connector required for Solana swaps');
439
455
  }
@@ -489,7 +505,10 @@ viewingAuth, createOrder, executeSolanaBridge, facilitatorGroup, integratorId) {
489
505
  depositParamsKeys: Object.keys(depositParams),
490
506
  });
491
507
  // Execute bridge transaction
492
- const bridgeResult = await executeSolanaBridge(sourceAsset, sourceAmount, usdcAmount, solanaSenderAddress, evmSignerAddress, depositParams);
508
+ const bridgeResult = await executeSolanaBridge(sourceAsset, sourceAmount, usdcAmount, solanaSenderAddress, evmSignerAddress, {
509
+ depositParams,
510
+ provider,
511
+ });
493
512
  console.log('[SilentSwap:SolanaSwap] Bridge result', {
494
513
  depositTxHash: bridgeResult.depositTxHash,
495
514
  provider: bridgeResult.provider,
@@ -569,6 +588,57 @@ viewingAuth, createOrder, executeBitcoinBridge, facilitatorGroup, integratorId)
569
588
  },
570
589
  };
571
590
  }
591
+ /**
592
+ * Execute Tron swap flow
593
+ *
594
+ * Handles the complete flow for Tron-based bridge swaps:
595
+ * 1. Validates Tron connection
596
+ * 2. Creates order (with empty authorizations for Tron)
597
+ * 3. Executes bridge transaction
598
+ * 4. Returns swap result
599
+ */
600
+ async function executeTronSwap(quoteResponse, sourceAsset, sourceAmount, usdcAmount, senderContactId, tronConnector, evmSignerAddress, viewingAuth, createOrder, executeTronBridge, facilitatorGroup, provider, integratorId) {
601
+ if (!tronConnector) {
602
+ throw new Error('Tron connector required for Tron swaps');
603
+ }
604
+ const accounts = await tronConnector.getAccounts();
605
+ const tronSenderAddress = tronConnector.currentAccount || accounts[0] || '';
606
+ if (!tronSenderAddress) {
607
+ throw new Error('Failed to get Tron sender address');
608
+ }
609
+ const orderResponse = await createOrder(quoteResponse, quoteResponse.authorizations.map((auth) => ({
610
+ ...auth,
611
+ signature: '0x',
612
+ })), {
613
+ sourceAsset: {
614
+ caip19: sourceAsset,
615
+ amount: `${BigInt(sourceAmount)}`,
616
+ },
617
+ sourceSender: {
618
+ contactId: senderContactId,
619
+ },
620
+ ...(integratorId && { integratorId }),
621
+ }, facilitatorGroup);
622
+ const depositParams = orderResponse.transaction.metadata?.params;
623
+ if (!depositParams) {
624
+ throw new Error('Missing deposit parameters in order response');
625
+ }
626
+ const bridgeResult = await executeTronBridge(sourceAsset, sourceAmount, usdcAmount, tronSenderAddress, evmSignerAddress, {
627
+ depositParams,
628
+ provider,
629
+ });
630
+ const resultOrderId = orderResponse.response.orderId;
631
+ return {
632
+ orderId: resultOrderId,
633
+ viewingAuth,
634
+ depositTransaction: {
635
+ hash: bridgeResult.depositTxHash,
636
+ chainId: NI_CHAIN_ID_AVALANCHE,
637
+ status: 'confirmed',
638
+ confirmations: 1,
639
+ },
640
+ };
641
+ }
572
642
  /**
573
643
  * Execute EVM swap flow
574
644
  *
@@ -16,7 +16,7 @@ export declare class AddressBookContact {
16
16
  protected _s_caip10: string;
17
17
  protected _s_ens: string;
18
18
  protected _s_sns: string;
19
- protected _s_caip2_ns: 'eip155' | 'solana' | 'bip122' | 'cosmos';
19
+ protected _s_caip2_ns: 'eip155' | 'solana' | 'bip122' | 'cosmos' | 'tron';
20
20
  private _saveCallback?;
21
21
  constructor(_g_info: AddressBookContactInfo, b_from_id?: boolean, saveCallback?: (contact: AddressBookContact) => void);
22
22
  private updateENSRecord;
@@ -28,7 +28,7 @@ export declare class AddressBookContact {
28
28
  get label(): string;
29
29
  set label(s_label: string);
30
30
  get source(): AddressBookContactSource;
31
- get caip2Ns(): 'eip155' | 'solana' | 'bip122' | 'cosmos';
31
+ get caip2Ns(): 'eip155' | 'solana' | 'bip122' | 'cosmos' | 'tron';
32
32
  isEvm(): boolean;
33
33
  isSolana(): boolean;
34
34
  isBip122(): boolean;
@@ -15,6 +15,8 @@ export interface UseOrderEstimatesOptions {
15
15
  evmAddress?: `0x${string}`;
16
16
  /** User's Solana address (base58 address) */
17
17
  solAddress?: string;
18
+ /** User's Tron address (TVM base58 address) */
19
+ tronAddress?: string;
18
20
  /** User's Bitcoin address */
19
21
  bitcoinAddress?: string;
20
22
  /** Source asset for determining which address to use (if Solana, use solAddress; if EVM, use evmAddress) */
@@ -32,7 +34,7 @@ export interface UseOrderEstimatesOptions {
32
34
  *
33
35
  * Returns retention rates that account for bridge fees and slippage
34
36
  */
35
- export declare function useOrderEstimates({ evmAddress, solAddress, bitcoinAddress, sourceAsset, maxImpactPercent, }?: UseOrderEstimatesOptions): {
37
+ export declare function useOrderEstimates({ evmAddress, solAddress, tronAddress, bitcoinAddress, sourceAsset, maxImpactPercent, }?: UseOrderEstimatesOptions): {
36
38
  estimateOrder: (usdcPrice: number, sourceAsset: AssetInfo, sourcePrice: number, sourceAmount: number | string, destinationAssets: AssetInfo[], destinationPrices: number[], splits: number[], calculationDirection?: CalculationDirection, outputAmounts?: string[], destinationContacts?: string[]) => Promise<OrderEstimateResult>;
37
39
  isLoading: boolean;
38
40
  error: Error | null;
@@ -1,6 +1,6 @@
1
1
  import { useCallback, useRef, useState, useMemo } from 'react';
2
2
  import BigNumber from 'bignumber.js';
3
- import { parseEvmCaip19, parseSolanaCaip19, isEvmNativeToken, isSolanaNativeToken, isSolanaAsset, isBitcoinAsset, EVM_PHONY_ADDRESS, SB58_ADDR_SOL_PROGRAM_SYSTEM, CALCULATION_DIRECTION_INPUT_TO_OUTPUT, CALCULATION_DIRECTION_OUTPUT_TO_INPUT, N_RELAY_CHAIN_ID_BITCOIN, SBTC_ADDR_BITCOIN_NATIVE, } from '@silentswap/sdk';
3
+ import { parseEvmCaip19, parseSolanaCaip19, parseTronCaip19, isEvmNativeToken, isSolanaNativeToken, isSolanaAsset, isBitcoinAsset, isTronAsset, EVM_PHONY_ADDRESS, SB58_ADDR_SOL_PROGRAM_SYSTEM, S0X_ADDR_TRON_NATIVE, CALCULATION_DIRECTION_INPUT_TO_OUTPUT, CALCULATION_DIRECTION_OUTPUT_TO_INPUT, N_RELAY_CHAIN_ID_BITCOIN, SBTC_ADDR_BITCOIN_NATIVE, } from '@silentswap/sdk';
4
4
  import { useQuote } from './useQuote.js';
5
5
  /**
6
6
  * Hook for fetching both ingress and egress estimates in parallel
@@ -12,7 +12,7 @@ import { useQuote } from './useQuote.js';
12
12
  *
13
13
  * Returns retention rates that account for bridge fees and slippage
14
14
  */
15
- export function useOrderEstimates({ evmAddress, solAddress, bitcoinAddress, sourceAsset, maxImpactPercent, } = {}) {
15
+ export function useOrderEstimates({ evmAddress, solAddress, tronAddress, bitcoinAddress, sourceAsset, maxImpactPercent, } = {}) {
16
16
  const [error, setError] = useState(null);
17
17
  const [isLoading, setIsLoading] = useState(false);
18
18
  // Determine address for ingress quotes based on source chain
@@ -120,18 +120,23 @@ export function useOrderEstimates({ evmAddress, solAddress, bitcoinAddress, sour
120
120
  console.log('[OrderEstimates] Step 3: Parsing source asset CAIP-19');
121
121
  const isSourceSolana = isSolanaAsset(sourceAsset.caip19);
122
122
  const isSourceBitcoin = isBitcoinAsset(sourceAsset.caip19);
123
- const sourceEvmParsed = !isSourceSolana && !isSourceBitcoin ? parseEvmCaip19(sourceAsset.caip19) : null;
123
+ const isSourceTron = isTronAsset(sourceAsset.caip19);
124
+ const sourceEvmParsed = !isSourceSolana && !isSourceBitcoin && !isSourceTron ? parseEvmCaip19(sourceAsset.caip19) : null;
124
125
  const sourceSolanaParsed = isSourceSolana ? parseSolanaCaip19(sourceAsset.caip19) : null;
126
+ const sourceTronParsed = isSourceTron ? parseTronCaip19(sourceAsset.caip19) : null;
125
127
  const sourceChainId = sourceEvmParsed?.chainId
126
128
  ?? sourceSolanaParsed?.chainId
129
+ ?? sourceTronParsed?.chainId
127
130
  ?? (isSourceBitcoin ? N_RELAY_CHAIN_ID_BITCOIN : 0);
128
131
  const sourceTokenAddress = isEvmNativeToken(sourceAsset.caip19)
129
132
  ? '0x0000000000000000000000000000000000000000'
130
133
  : isSolanaNativeToken(sourceAsset.caip19)
131
134
  ? '11111111111111111111111111111111'
132
- : isSourceBitcoin
133
- ? SBTC_ADDR_BITCOIN_NATIVE
134
- : (sourceEvmParsed?.tokenAddress ?? sourceSolanaParsed?.tokenAddress ?? '');
135
+ : isSourceTron
136
+ ? (sourceTronParsed?.isNative ? S0X_ADDR_TRON_NATIVE : (sourceTronParsed?.tokenAddress ?? ''))
137
+ : isSourceBitcoin
138
+ ? SBTC_ADDR_BITCOIN_NATIVE
139
+ : (sourceEvmParsed?.tokenAddress ?? sourceSolanaParsed?.tokenAddress ?? '');
135
140
  console.log('[OrderEstimates] Step 3: Source asset parsed', { sourceChainId, sourceTokenAddress, isSourceSolana, isSourceBitcoin });
136
141
  // For reverse calculation, calculate total output USD value first
137
142
  let totalOutputUsd = 0;
@@ -184,18 +189,23 @@ export function useOrderEstimates({ evmAddress, solAddress, bitcoinAddress, sour
184
189
  // Parse destination asset to get chain ID and token address from CAIP-19
185
190
  const isDestSolana = isSolanaAsset(destAsset.caip19);
186
191
  const isDestBitcoin = isBitcoinAsset(destAsset.caip19);
187
- const destEvmParsed = !isDestSolana && !isDestBitcoin ? parseEvmCaip19(destAsset.caip19) : null;
192
+ const isDestTron = isTronAsset(destAsset.caip19);
193
+ const destEvmParsed = !isDestSolana && !isDestBitcoin && !isDestTron ? parseEvmCaip19(destAsset.caip19) : null;
188
194
  const destSolanaParsed = isDestSolana ? parseSolanaCaip19(destAsset.caip19) : null;
195
+ const destTronParsed = isDestTron ? parseTronCaip19(destAsset.caip19) : null;
189
196
  const destChainId = destEvmParsed?.chainId
190
197
  ?? destSolanaParsed?.chainId
198
+ ?? destTronParsed?.chainId
191
199
  ?? (isDestBitcoin ? N_RELAY_CHAIN_ID_BITCOIN : 0);
192
200
  const destTokenAddress = isEvmNativeToken(destAsset.caip19)
193
201
  ? '0x0000000000000000000000000000000000000000'
194
202
  : isSolanaNativeToken(destAsset.caip19)
195
203
  ? '11111111111111111111111111111111'
196
- : isDestBitcoin
197
- ? SBTC_ADDR_BITCOIN_NATIVE
198
- : (destEvmParsed?.tokenAddress ?? destSolanaParsed?.tokenAddress ?? '');
204
+ : isDestTron
205
+ ? (destTronParsed?.isNative ? S0X_ADDR_TRON_NATIVE : (destTronParsed?.tokenAddress ?? ''))
206
+ : isDestBitcoin
207
+ ? SBTC_ADDR_BITCOIN_NATIVE
208
+ : (destEvmParsed?.tokenAddress ?? destSolanaParsed?.tokenAddress ?? '');
199
209
  // Determine recipient address based on destination chain
200
210
  // Prefer the entered contact address (e.g. user-entered BTC address without wallet connected)
201
211
  const contact = destinationContacts?.[idx];
@@ -203,7 +213,9 @@ export function useOrderEstimates({ evmAddress, solAddress, bitcoinAddress, sour
203
213
  ? (contact || solAddress)
204
214
  : isDestBitcoin
205
215
  ? (contact || bitcoinAddress || SBTC_ADDR_BITCOIN_NATIVE)
206
- : (contact && contact.startsWith('0x') ? contact : evmAddress);
216
+ : isDestTron
217
+ ? (contact || tronAddress)
218
+ : (contact && contact.startsWith('0x') ? contact : evmAddress);
207
219
  // For reverse calculation, use output amount directly with EXACT_OUTPUT
208
220
  if (calculationDirection === CALCULATION_DIRECTION_OUTPUT_TO_INPUT && outputAmounts && outputAmounts[idx]) {
209
221
  const outputAmount = parseFloat(outputAmounts[idx]);
@@ -50,13 +50,20 @@ export type PlatformHealthProviderProps = {
50
50
  * API's own maximumDepositUusdc limit applies.
51
51
  */
52
52
  maxDepositUsd?: number;
53
+ /**
54
+ * Optional maintenance override from admin dashboard settings. When true, the effective
55
+ * platform health is forced to 'MAINTENANCE' regardless of what the platform status API
56
+ * reports — flipping formDisabled and trackingDisabled to true and letting consumers
57
+ * show a maintenance screen.
58
+ */
59
+ maintenanceMode?: boolean;
53
60
  };
54
61
  /**
55
62
  * Provider that monitors platform health from SilentSwapContext (which calls useStatus
56
63
  * once with proId) and provides validation functions for deposit amounts, output limits,
57
64
  * and service fee rates.
58
65
  */
59
- export declare function PlatformHealthProvider({ children, onFormDisabledChange, onTrackingDisabledChange, maxDepositUsd, }: PlatformHealthProviderProps): import("react/jsx-runtime").JSX.Element;
66
+ export declare function PlatformHealthProvider({ children, onFormDisabledChange, onTrackingDisabledChange, maxDepositUsd, maintenanceMode, }: PlatformHealthProviderProps): import("react/jsx-runtime").JSX.Element;
60
67
  /**
61
68
  * Hook to access platform health context
62
69
  */
@@ -9,16 +9,19 @@ const PlatformHealthContext = createContext(undefined);
9
9
  * once with proId) and provides validation functions for deposit amounts, output limits,
10
10
  * and service fee rates.
11
11
  */
12
- export function PlatformHealthProvider({ children, onFormDisabledChange, onTrackingDisabledChange, maxDepositUsd, }) {
12
+ export function PlatformHealthProvider({ children, onFormDisabledChange, onTrackingDisabledChange, maxDepositUsd, maintenanceMode, }) {
13
13
  // Consume status data from parent SilentSwapContext instead of calling useStatus again
14
14
  const { status } = useSilentSwap();
15
15
  const { platformHealth: statusPlatformHealth, maximumDepositUusdc, minimumDepositUusdc, outputLimit, serviceFeeRate, overheadUsd, identity, volume, liquidity, storage, } = status;
16
- // Normalize platform health status
16
+ // Normalize platform health status. A dashboard-driven maintenance override forces
17
+ // the effective status to 'MAINTENANCE' regardless of what the status API reports.
17
18
  const platformHealth = useMemo(() => {
19
+ if (maintenanceMode)
20
+ return 'MAINTENANCE';
18
21
  if (!statusPlatformHealth)
19
22
  return null;
20
23
  return statusPlatformHealth;
21
- }, [statusPlatformHealth]);
24
+ }, [statusPlatformHealth, maintenanceMode]);
22
25
  // Track disabled states locally for context value
23
26
  const [formDisabled, setFormDisabled] = React.useState(false);
24
27
  const [trackingDisabled, setTrackingDisabled] = React.useState(false);