@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.
- package/dist/contexts/AssetsContext.js +1 -0
- package/dist/contexts/BalancesContext.d.ts +3 -1
- package/dist/contexts/BalancesContext.js +235 -7
- package/dist/contexts/SilentSwapContext.d.ts +6 -1
- package/dist/contexts/SilentSwapContext.js +7 -4
- package/dist/hooks/silent/tron-transaction.d.ts +34 -4
- package/dist/hooks/silent/tron-transaction.js +45 -1
- package/dist/hooks/silent/useAuth.js +14 -0
- package/dist/hooks/silent/useBridgeExecution.d.ts +12 -2
- package/dist/hooks/silent/useBridgeExecution.js +341 -114
- package/dist/hooks/silent/useQuoteCalculation.d.ts +3 -1
- package/dist/hooks/silent/useQuoteCalculation.js +72 -5
- package/dist/hooks/silent/useSilentQuote.d.ts +8 -1
- package/dist/hooks/silent/useSilentQuote.js +77 -7
- package/dist/hooks/useContacts.d.ts +2 -2
- package/dist/hooks/useOrderEstimates.d.ts +3 -1
- package/dist/hooks/useOrderEstimates.js +23 -11
- package/dist/hooks/usePlatformHealth.d.ts +8 -1
- package/dist/hooks/usePlatformHealth.js +6 -3
- package/dist/hooks/useQuote.js +53 -15
- package/dist/hooks/useTransaction.d.ts +6 -1
- package/dist/hooks/useTransaction.js +89 -8
- package/dist/hooks/useTransactionAddress.d.ts +3 -2
- package/dist/hooks/useTransactionAddress.js +10 -6
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/package.json +3 -3
package/dist/hooks/useQuote.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import BigNumber from 'bignumber.js';
|
|
3
|
-
import { NI_CHAIN_ID_AVALANCHE, S0X_ADDR_USDC_AVALANCHE, S_CAIP19_USDC_AVALANCHE, X_MAX_IMPACT_PERCENT, getBridgeQuote, interpolateSamples as sdkInterpolateSamples, fetchRelayQuote, fetchDebridgeOrder, normalizeAddress, getAssetByCaip19, N_DEBRIDGE_CHAIN_ID_SOLANA, N_RELAY_CHAIN_ID_SOLANA, N_RELAY_CHAIN_ID_BITCOIN, SBTC_ADDR_BITCOIN_NATIVE, SBTC_ADDR_BTC_RELAY_LINK_RECIPIENT, SB58_ADDR_SOL_PROGRAM_SYSTEM, S0X_ADDR_EVM_RELAY_LINK_DEAD, SB58_ADDR_SOL_RELAY_LINK_RECIPIENT, isSolanaAsset, isBitcoinAsset, EVM_PHONY_ADDRESS, } from '@silentswap/sdk';
|
|
4
|
-
// Constants for estimateLive
|
|
5
|
-
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
3
|
+
import { NI_CHAIN_ID_AVALANCHE, S0X_ADDR_USDC_AVALANCHE, S_CAIP19_USDC_AVALANCHE, X_MAX_IMPACT_PERCENT, getBridgeQuote, interpolateSamples as sdkInterpolateSamples, fetchRelayQuote, fetchDebridgeOrder, normalizeAddress, getAssetByCaip19, N_DEBRIDGE_CHAIN_ID_SOLANA, N_RELAY_CHAIN_ID_SOLANA, N_RELAY_CHAIN_ID_BITCOIN, SBTC_ADDR_BITCOIN_NATIVE, SBTC_ADDR_BTC_RELAY_LINK_RECIPIENT, SB58_ADDR_SOL_PROGRAM_SYSTEM, S0X_ADDR_EVM_ZERO, S0X_ADDR_EVM_RELAY_LINK_DEAD, SB58_ADDR_SOL_RELAY_LINK_RECIPIENT, isSolanaAsset, isBitcoinAsset, isTronAsset, N_RELAY_CHAIN_ID_TRON, N_DEBRIDGE_CHAIN_ID_TRON, S0X_ADDR_TRON_NATIVE, SB58_ADDR_TRON_DEAD, EVM_PHONY_ADDRESS, } from '@silentswap/sdk';
|
|
6
4
|
/**
|
|
7
5
|
* Hook for getting optimized bridge quotes with retention rate tracking
|
|
8
6
|
* Implements the same functionality as estimate.ts from the original app
|
|
@@ -66,8 +64,8 @@ export function useQuote({ address, maxImpactPercent = X_MAX_IMPACT_PERCENT, for
|
|
|
66
64
|
try {
|
|
67
65
|
// Normalize addresses
|
|
68
66
|
console.log('[Quote] Step 2: Normalizing token addresses');
|
|
69
|
-
const srcTokenNorm = srcToken === '0x0' || srcToken ===
|
|
70
|
-
const dstTokenNorm = dstToken === '0x0' || dstToken ===
|
|
67
|
+
const srcTokenNorm = srcToken === '0x0' || srcToken === S0X_ADDR_EVM_ZERO ? S0X_ADDR_EVM_ZERO : srcToken;
|
|
68
|
+
const dstTokenNorm = dstToken === '0x0' || dstToken === S0X_ADDR_EVM_ZERO ? S0X_ADDR_EVM_ZERO : dstToken;
|
|
71
69
|
// Use shared quote fetching function
|
|
72
70
|
// normalizedAddress can be EVM (0x...) or Solana (base58) address
|
|
73
71
|
// sourceAddress is the address format for the source chain (for relay.link)
|
|
@@ -112,11 +110,12 @@ export function useQuote({ address, maxImpactPercent = X_MAX_IMPACT_PERCENT, for
|
|
|
112
110
|
isReverseCalculation,
|
|
113
111
|
targetAmount,
|
|
114
112
|
});
|
|
115
|
-
// Determine if this is a Solana or
|
|
113
|
+
// Determine if this is a Solana, Bitcoin, or Tron chain by checking the asset CAIP-19
|
|
116
114
|
// This is more reliable than checking chainId format
|
|
117
115
|
const isSolanaChain = isSolanaAsset(assetCaip19);
|
|
118
116
|
const isBitcoinChain = isBitcoinAsset(assetCaip19);
|
|
119
|
-
|
|
117
|
+
const isTronChain = isTronAsset(assetCaip19);
|
|
118
|
+
console.log('[Quote] Step 2: Chain type determined', { isSolanaChain, isBitcoinChain, isTronChain, chainId });
|
|
120
119
|
let numericChainId;
|
|
121
120
|
if (isSolanaChain) {
|
|
122
121
|
// For Solana, we'll use different chain IDs for different providers
|
|
@@ -127,6 +126,10 @@ export function useQuote({ address, maxImpactPercent = X_MAX_IMPACT_PERCENT, for
|
|
|
127
126
|
// Bitcoin uses the relay chain ID directly (only relay supports Bitcoin)
|
|
128
127
|
numericChainId = N_RELAY_CHAIN_ID_BITCOIN;
|
|
129
128
|
}
|
|
129
|
+
else if (isTronChain) {
|
|
130
|
+
// Tron uses different chain IDs per provider, set per-provider below
|
|
131
|
+
numericChainId = 0; // Placeholder, will be set per provider
|
|
132
|
+
}
|
|
130
133
|
else {
|
|
131
134
|
// For EVM chains, convert chainId to number if needed
|
|
132
135
|
if (typeof chainId === 'string') {
|
|
@@ -157,7 +160,7 @@ export function useQuote({ address, maxImpactPercent = X_MAX_IMPACT_PERCENT, for
|
|
|
157
160
|
try {
|
|
158
161
|
// Special case for USDC on Avalanche
|
|
159
162
|
// Check numericChainId (exclude non-EVM chains which use relay chain IDs)
|
|
160
|
-
const checkChainId = (isSolanaChain || isBitcoinChain) ? 0 : numericChainId;
|
|
163
|
+
const checkChainId = (isSolanaChain || isBitcoinChain || isTronChain) ? 0 : numericChainId;
|
|
161
164
|
if (checkChainId === NI_CHAIN_ID_AVALANCHE &&
|
|
162
165
|
tokenAddress.toLowerCase() === S0X_ADDR_USDC_AVALANCHE.toLowerCase()) {
|
|
163
166
|
console.log('[Quote] Step 3: Special case - USDC on Avalanche, returning identity estimate');
|
|
@@ -218,6 +221,12 @@ export function useQuote({ address, maxImpactPercent = X_MAX_IMPACT_PERCENT, for
|
|
|
218
221
|
? normalizedAddress
|
|
219
222
|
: SBTC_ADDR_BITCOIN_NATIVE;
|
|
220
223
|
}
|
|
224
|
+
else if (isTronChain) {
|
|
225
|
+
// For Tron ingress, use Tron address (starts with T) or dead address as fallback
|
|
226
|
+
userAddress = normalizedAddress && normalizedAddress.startsWith('T')
|
|
227
|
+
? normalizedAddress
|
|
228
|
+
: SB58_ADDR_TRON_DEAD;
|
|
229
|
+
}
|
|
221
230
|
else {
|
|
222
231
|
// For EVM ingress, use EVM address (or phony if not available)
|
|
223
232
|
userAddress = normalizedAddress && normalizedAddress.startsWith('0x')
|
|
@@ -231,11 +240,14 @@ export function useQuote({ address, maxImpactPercent = X_MAX_IMPACT_PERCENT, for
|
|
|
231
240
|
? normalizedAddress
|
|
232
241
|
: EVM_PHONY_ADDRESS;
|
|
233
242
|
}
|
|
234
|
-
// Map chain IDs per provider (Solana and
|
|
243
|
+
// Map chain IDs per provider (Solana, Bitcoin, and Tron use provider-specific IDs)
|
|
235
244
|
const relayChainId = isSolanaChain ? N_RELAY_CHAIN_ID_SOLANA
|
|
236
245
|
: isBitcoinChain ? N_RELAY_CHAIN_ID_BITCOIN
|
|
246
|
+
: isTronChain ? N_RELAY_CHAIN_ID_TRON
|
|
247
|
+
: numericChainId;
|
|
248
|
+
const debridgeChainId = isSolanaChain ? N_DEBRIDGE_CHAIN_ID_SOLANA
|
|
249
|
+
: isTronChain ? N_DEBRIDGE_CHAIN_ID_TRON
|
|
237
250
|
: numericChainId;
|
|
238
|
-
const debridgeChainId = isSolanaChain ? N_DEBRIDGE_CHAIN_ID_SOLANA : numericChainId;
|
|
239
251
|
console.log('[Quote] Step 4: Address and chain IDs determined', {
|
|
240
252
|
userAddress,
|
|
241
253
|
relayChainId,
|
|
@@ -279,7 +291,9 @@ export function useQuote({ address, maxImpactPercent = X_MAX_IMPACT_PERCENT, for
|
|
|
279
291
|
destinationChainId: NI_CHAIN_ID_AVALANCHE,
|
|
280
292
|
originCurrency: isBitcoinChain
|
|
281
293
|
? (tokenAddress || SBTC_ADDR_BITCOIN_NATIVE)
|
|
282
|
-
:
|
|
294
|
+
: isTronChain
|
|
295
|
+
? (tokenAddress || S0X_ADDR_TRON_NATIVE)
|
|
296
|
+
: (tokenAddress === S0X_ADDR_EVM_ZERO ? S0X_ADDR_EVM_ZERO : tokenAddress),
|
|
283
297
|
destinationCurrency: S0X_ADDR_USDC_AVALANCHE,
|
|
284
298
|
...(isReverseCalculation && tradeType === 'EXACT_OUTPUT'
|
|
285
299
|
? {
|
|
@@ -295,7 +309,9 @@ export function useQuote({ address, maxImpactPercent = X_MAX_IMPACT_PERCENT, for
|
|
|
295
309
|
? { recipient: EVM_PHONY_ADDRESS }
|
|
296
310
|
: isBitcoinChain
|
|
297
311
|
? { recipient: EVM_PHONY_ADDRESS }
|
|
298
|
-
:
|
|
312
|
+
: isTronChain
|
|
313
|
+
? { recipient: EVM_PHONY_ADDRESS }
|
|
314
|
+
: {}),
|
|
299
315
|
}
|
|
300
316
|
: {
|
|
301
317
|
originChainId: NI_CHAIN_ID_AVALANCHE,
|
|
@@ -303,7 +319,9 @@ export function useQuote({ address, maxImpactPercent = X_MAX_IMPACT_PERCENT, for
|
|
|
303
319
|
destinationChainId: relayChainId,
|
|
304
320
|
destinationCurrency: isBitcoinChain
|
|
305
321
|
? (tokenAddress || SBTC_ADDR_BITCOIN_NATIVE)
|
|
306
|
-
:
|
|
322
|
+
: isTronChain
|
|
323
|
+
? (tokenAddress || S0X_ADDR_TRON_NATIVE)
|
|
324
|
+
: (tokenAddress === S0X_ADDR_EVM_ZERO ? S0X_ADDR_EVM_ZERO : tokenAddress),
|
|
307
325
|
...(isReverseCalculation && tradeType === 'EXACT_OUTPUT'
|
|
308
326
|
? {
|
|
309
327
|
// For reverse egress: we specify the destination (output) amount
|
|
@@ -326,7 +344,14 @@ export function useQuote({ address, maxImpactPercent = X_MAX_IMPACT_PERCENT, for
|
|
|
326
344
|
? recipientAddress
|
|
327
345
|
: SBTC_ADDR_BTC_RELAY_LINK_RECIPIENT,
|
|
328
346
|
}
|
|
329
|
-
:
|
|
347
|
+
: isTronChain
|
|
348
|
+
? {
|
|
349
|
+
// Tron egress: recipient must be a valid Tron address (starts with T)
|
|
350
|
+
recipient: recipientAddress && recipientAddress.startsWith('T')
|
|
351
|
+
? recipientAddress
|
|
352
|
+
: SB58_ADDR_TRON_DEAD,
|
|
353
|
+
}
|
|
354
|
+
: {}),
|
|
330
355
|
}),
|
|
331
356
|
}, signal);
|
|
332
357
|
return quote;
|
|
@@ -351,9 +376,12 @@ export function useQuote({ address, maxImpactPercent = X_MAX_IMPACT_PERCENT, for
|
|
|
351
376
|
return null; // Skip DeBridge for Bitcoin, will use Relay.link only
|
|
352
377
|
}
|
|
353
378
|
// For reverse calculation ingress: use srcChainTokenInAmount: 'auto' and specify dstChainTokenOutAmount
|
|
379
|
+
const srcTokenForDebridge = isTronChain
|
|
380
|
+
? (tokenAddress || S0X_ADDR_TRON_NATIVE)
|
|
381
|
+
: (tokenAddress === S0X_ADDR_EVM_ZERO ? S0X_ADDR_EVM_ZERO : tokenAddress);
|
|
354
382
|
const debridgeParams = {
|
|
355
383
|
srcChainId: debridgeChainId,
|
|
356
|
-
srcChainTokenIn:
|
|
384
|
+
srcChainTokenIn: srcTokenForDebridge,
|
|
357
385
|
dstChainId: NI_CHAIN_ID_AVALANCHE,
|
|
358
386
|
dstChainTokenOut: S0X_ADDR_USDC_AVALANCHE,
|
|
359
387
|
prependOperatingExpenses: true,
|
|
@@ -386,6 +414,16 @@ export function useQuote({ address, maxImpactPercent = X_MAX_IMPACT_PERCENT, for
|
|
|
386
414
|
debridgeParams.dstChainTokenOutRecipient = EVM_PHONY_ADDRESS;
|
|
387
415
|
debridgeParams.dstChainOrderAuthorityAddress = EVM_PHONY_ADDRESS;
|
|
388
416
|
}
|
|
417
|
+
else if (isTronChain) {
|
|
418
|
+
// Tron source requires Tron-format authority fields and estimate disabled
|
|
419
|
+
const tronAddr = userAddress.startsWith('T') ? userAddress : SB58_ADDR_TRON_DEAD;
|
|
420
|
+
debridgeParams.enableEstimate = false;
|
|
421
|
+
debridgeParams.account = tronAddr;
|
|
422
|
+
debridgeParams.srcChainOrderAuthorityAddress = tronAddr;
|
|
423
|
+
debridgeParams.srcChainRefundAddress = tronAddr;
|
|
424
|
+
debridgeParams.dstChainTokenOutRecipient = EVM_PHONY_ADDRESS;
|
|
425
|
+
debridgeParams.dstChainOrderAuthorityAddress = EVM_PHONY_ADDRESS;
|
|
426
|
+
}
|
|
389
427
|
const quote = await fetchDebridgeOrder(debridgeParams, signal);
|
|
390
428
|
return quote;
|
|
391
429
|
}
|
|
@@ -3,6 +3,7 @@ import type { Connector } from 'wagmi';
|
|
|
3
3
|
import type { BridgeProvider, BridgeQuote, BridgeStatus, OrderResponse } from '@silentswap/sdk';
|
|
4
4
|
import type { SolanaWalletConnector, SolanaConnection } from './silent/solana-transaction.js';
|
|
5
5
|
import type { BitcoinWalletConnector, BitcoinConnection } from './silent/bitcoin-transaction.js';
|
|
6
|
+
import type { TronWalletConnector, TronConnection } from './silent/tron-transaction.js';
|
|
6
7
|
export interface useTransactionOptions {
|
|
7
8
|
/** User's EVM address */
|
|
8
9
|
address: `0x${string}`;
|
|
@@ -20,6 +21,10 @@ export interface useTransactionOptions {
|
|
|
20
21
|
bitcoinConnector?: BitcoinWalletConnector;
|
|
21
22
|
/** Bitcoin connection (optional, for consistency with Solana pattern) */
|
|
22
23
|
bitcoinConnection?: BitcoinConnection;
|
|
24
|
+
/** Tron wallet connector (required for Tron transactions) */
|
|
25
|
+
tronConnector?: TronWalletConnector;
|
|
26
|
+
/** Tron connection (optional, for consistency with other adapters) */
|
|
27
|
+
tronConnection?: TronConnection;
|
|
23
28
|
/** Optional callback to set current step (for external state management) */
|
|
24
29
|
setCurrentStep?: (step: string) => void;
|
|
25
30
|
/** Optional status update callback */
|
|
@@ -121,4 +126,4 @@ export interface useTransactionReturn {
|
|
|
121
126
|
* }
|
|
122
127
|
* ```
|
|
123
128
|
*/
|
|
124
|
-
export declare function useTransaction({ walletClient, connector, solanaConnector, solanaConnection, solanaRpcUrl, bitcoinConnector, bitcoinConnection, setCurrentStep: externalSetCurrentStep, onStatus: externalOnStatus, }: useTransactionOptions): useTransactionReturn;
|
|
129
|
+
export declare function useTransaction({ walletClient, connector, solanaConnector, solanaConnection, solanaRpcUrl, bitcoinConnector, bitcoinConnection, tronConnector, tronConnection, setCurrentStep: externalSetCurrentStep, onStatus: externalOnStatus, }: useTransactionOptions): useTransactionReturn;
|
|
@@ -3,8 +3,9 @@ import { erc20Abi } from 'viem';
|
|
|
3
3
|
import { executeRelayBridge, executeDebridgeBridge, getBridgeStatus, createTransactionExecutor, createChainSwitcher, ensureChain, waitForTransactionConfirmation, parseTransactionRequestForViem, createPublicClientWithRpc, getChainById, } from '@silentswap/sdk';
|
|
4
4
|
import { createSolanaTransactionExecutor } from './silent/solana-transaction.js';
|
|
5
5
|
import { createBitcoinTransactionExecutor, convertRelayBitcoinStepToTransaction } from './silent/bitcoin-transaction.js';
|
|
6
|
+
import { createTronTransactionExecutor, convertRelayTronStepToTransaction, isRelayTronStepData } from './silent/tron-transaction.js';
|
|
7
|
+
import { N_RELAY_CHAIN_ID_BITCOIN, N_RELAY_CHAIN_ID_TRON, N_DEBRIDGE_CHAIN_ID_TRON } from '@silentswap/sdk';
|
|
6
8
|
import { N_DEBRIDGE_CHAIN_ID_SOLANA } from '@silentswap/sdk';
|
|
7
|
-
import { N_RELAY_CHAIN_ID_BITCOIN } from '@silentswap/sdk';
|
|
8
9
|
/**
|
|
9
10
|
* React hook for executing transactions
|
|
10
11
|
*
|
|
@@ -79,7 +80,7 @@ import { N_RELAY_CHAIN_ID_BITCOIN } from '@silentswap/sdk';
|
|
|
79
80
|
* }
|
|
80
81
|
* ```
|
|
81
82
|
*/
|
|
82
|
-
export function useTransaction({ walletClient, connector, solanaConnector, solanaConnection, solanaRpcUrl, bitcoinConnector, bitcoinConnection, setCurrentStep: externalSetCurrentStep, onStatus: externalOnStatus, }) {
|
|
83
|
+
export function useTransaction({ walletClient, connector, solanaConnector, solanaConnection, solanaRpcUrl, bitcoinConnector, bitcoinConnection, tronConnector, tronConnection, setCurrentStep: externalSetCurrentStep, onStatus: externalOnStatus, }) {
|
|
83
84
|
const [isLoading, setIsLoading] = useState(false);
|
|
84
85
|
const [internalCurrentStep, setInternalCurrentStep] = useState('');
|
|
85
86
|
const [error, setError] = useState(null);
|
|
@@ -106,6 +107,8 @@ export function useTransaction({ walletClient, connector, solanaConnector, solan
|
|
|
106
107
|
return false;
|
|
107
108
|
});
|
|
108
109
|
const hasBitcoinTransactions = hasBitcoinInTxs || hasBitcoinInRoute;
|
|
110
|
+
// Check if quote contains Tron transactions (relay or deBridge)
|
|
111
|
+
const hasTronTransactions = quote.txs.some((tx) => tx.chainId === N_RELAY_CHAIN_ID_TRON || tx.chainId === N_DEBRIDGE_CHAIN_ID_TRON);
|
|
109
112
|
// Check if quote contains Solana transactions (relay instructions or deBridge serialized tx)
|
|
110
113
|
const hasSolanaTransactions = quote.txs.some((tx) => tx.instructions !== undefined || tx.chainId === N_DEBRIDGE_CHAIN_ID_SOLANA);
|
|
111
114
|
if (hasBitcoinTransactions) {
|
|
@@ -166,7 +169,7 @@ export function useTransaction({ walletClient, connector, solanaConnector, solan
|
|
|
166
169
|
else {
|
|
167
170
|
// Use standard execution path if txs array has Bitcoin transactions
|
|
168
171
|
const executeTx = createTransactionExecutor(walletClient, connector, undefined, // solanaExecutor
|
|
169
|
-
bitcoinExecutor);
|
|
172
|
+
bitcoinExecutor, undefined);
|
|
170
173
|
// Create a no-op chain switcher for Bitcoin (chain switching is handled by connector)
|
|
171
174
|
const switchChain = async (_chainId) => {
|
|
172
175
|
// Bitcoin doesn't require chain switching
|
|
@@ -194,6 +197,84 @@ export function useTransaction({ walletClient, connector, solanaConnector, solan
|
|
|
194
197
|
setCurrentStep('');
|
|
195
198
|
}
|
|
196
199
|
}
|
|
200
|
+
else if (hasTronTransactions) {
|
|
201
|
+
if (!tronConnector) {
|
|
202
|
+
throw new Error('Tron connector is required for Tron bridge transactions. ' +
|
|
203
|
+
'Please provide tronConnector option.');
|
|
204
|
+
}
|
|
205
|
+
const tronExecutor = createTronTransactionExecutor(tronConnector, tronConnection);
|
|
206
|
+
setIsLoading(true);
|
|
207
|
+
setError(null);
|
|
208
|
+
try {
|
|
209
|
+
switch (quote.provider) {
|
|
210
|
+
case 'relay': {
|
|
211
|
+
const steps = quote.route?.steps || [];
|
|
212
|
+
const txHashes = [];
|
|
213
|
+
for (const step of steps) {
|
|
214
|
+
if (step.kind === 'transaction' && step.items) {
|
|
215
|
+
for (const item of step.items) {
|
|
216
|
+
const itemData = item.data || {};
|
|
217
|
+
// Relay returns Tron steps as nested TriggerSmartContract
|
|
218
|
+
// payloads (no top-level chainId), so discriminate by shape.
|
|
219
|
+
if (!isRelayTronStepData(itemData)) {
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
const label = step.id === 'approve'
|
|
223
|
+
? 'Requesting approval...'
|
|
224
|
+
: step.id === 'deposit'
|
|
225
|
+
? 'Requesting deposit...'
|
|
226
|
+
: 'Requesting bridge...';
|
|
227
|
+
setCurrentStep(label);
|
|
228
|
+
onStatus?.(label);
|
|
229
|
+
const tronTx = convertRelayTronStepToTransaction(itemData, N_RELAY_CHAIN_ID_TRON);
|
|
230
|
+
const hash = await tronExecutor(tronTx);
|
|
231
|
+
if (hash)
|
|
232
|
+
txHashes.push(hash);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const requestId = steps.find((s) => s.requestId)?.requestId;
|
|
237
|
+
if (!requestId) {
|
|
238
|
+
throw new Error('Missing relay.link request ID');
|
|
239
|
+
}
|
|
240
|
+
if (txHashes.length === 0) {
|
|
241
|
+
throw new Error('No Tron transactions were executed for relay quote. ' +
|
|
242
|
+
'The quote may not contain any Tron steps.');
|
|
243
|
+
}
|
|
244
|
+
return {
|
|
245
|
+
status: 'pending',
|
|
246
|
+
txHashes: txHashes,
|
|
247
|
+
requestId,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
case 'debridge': {
|
|
251
|
+
// For deBridge Tron transactions, route through the universal executor.
|
|
252
|
+
// The TronLink connector handles chain context — walletClient/connector
|
|
253
|
+
// are not required for the Tron path.
|
|
254
|
+
const executeTx = createTransactionExecutor(walletClient, connector, undefined, undefined, tronExecutor);
|
|
255
|
+
const switchChain = async (_chainId) => {
|
|
256
|
+
// Tron doesn't require EVM chain switching
|
|
257
|
+
};
|
|
258
|
+
return await executeDebridgeBridge(quote, executeTx, switchChain, (step) => {
|
|
259
|
+
setCurrentStep(step);
|
|
260
|
+
onStatus?.(step);
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
default:
|
|
264
|
+
throw new Error(`Unsupported bridge provider: ${quote.provider}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
catch (err) {
|
|
268
|
+
const error = err instanceof Error ? err : new Error('Bridge execution failed');
|
|
269
|
+
console.error('Bridge execution failed:', error);
|
|
270
|
+
setError(error);
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
finally {
|
|
274
|
+
setIsLoading(false);
|
|
275
|
+
setCurrentStep('');
|
|
276
|
+
}
|
|
277
|
+
}
|
|
197
278
|
else if (hasSolanaTransactions) {
|
|
198
279
|
// Solana transactions require Solana connector and connection
|
|
199
280
|
if (!solanaConnector || !solanaConnection) {
|
|
@@ -204,7 +285,7 @@ export function useTransaction({ walletClient, connector, solanaConnector, solan
|
|
|
204
285
|
const solanaExecutor = createSolanaTransactionExecutor(solanaConnector, solanaConnection);
|
|
205
286
|
// For Solana, we still need EVM wallet client for chain switching (if needed)
|
|
206
287
|
// But the actual transaction execution will use Solana executor
|
|
207
|
-
const executeTx = createTransactionExecutor(walletClient, connector, solanaExecutor);
|
|
288
|
+
const executeTx = createTransactionExecutor(walletClient, connector, solanaExecutor, undefined, undefined);
|
|
208
289
|
// Create a no-op chain switcher for Solana (chain switching is handled by connector)
|
|
209
290
|
const switchChain = async (_chainId) => {
|
|
210
291
|
// Solana doesn't require chain switching
|
|
@@ -251,7 +332,7 @@ export function useTransaction({ walletClient, connector, solanaConnector, solan
|
|
|
251
332
|
setError(null);
|
|
252
333
|
try {
|
|
253
334
|
// Create wrapper functions using shared utilities
|
|
254
|
-
const executeTx = createTransactionExecutor(walletClient, connector);
|
|
335
|
+
const executeTx = createTransactionExecutor(walletClient, connector, undefined, undefined, undefined);
|
|
255
336
|
const switchChain = createChainSwitcher(walletClient, connector);
|
|
256
337
|
// Execute based on provider
|
|
257
338
|
switch (quote.provider) {
|
|
@@ -280,7 +361,7 @@ export function useTransaction({ walletClient, connector, solanaConnector, solan
|
|
|
280
361
|
setCurrentStep('');
|
|
281
362
|
}
|
|
282
363
|
}
|
|
283
|
-
}, [walletClient, connector, solanaConnector, solanaConnection, solanaRpcUrl]);
|
|
364
|
+
}, [walletClient, connector, solanaConnector, solanaConnection, solanaRpcUrl, bitcoinConnector, bitcoinConnection, tronConnector, tronConnection]);
|
|
284
365
|
/**
|
|
285
366
|
* Execute a deposit transaction from an OrderResponse
|
|
286
367
|
*
|
|
@@ -417,14 +498,14 @@ export function useTransaction({ walletClient, connector, solanaConnector, solan
|
|
|
417
498
|
const getStatus = useCallback(async (requestId, provider) => {
|
|
418
499
|
setIsLoading(true);
|
|
419
500
|
setCurrentStep('Checking bridge status');
|
|
420
|
-
setError(null);
|
|
421
501
|
try {
|
|
422
502
|
// Use shared status function
|
|
423
503
|
return await getBridgeStatus(requestId, provider);
|
|
424
504
|
}
|
|
425
505
|
catch (err) {
|
|
506
|
+
// Status checks are polled by the caller and can fail transiently (e.g. deBridge indexing lag).
|
|
507
|
+
// Do not surface this as a global transaction error in hook state.
|
|
426
508
|
const error = err instanceof Error ? err : new Error('Failed to get bridge status');
|
|
427
|
-
setError(error);
|
|
428
509
|
throw error;
|
|
429
510
|
}
|
|
430
511
|
finally {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { type AssetInfo } from '@silentswap/sdk';
|
|
2
2
|
/**
|
|
3
3
|
* Hook to select the correct transaction/quote address based on the input token.
|
|
4
|
-
* Returns EVM address for EVM tokens, Solana
|
|
4
|
+
* Returns EVM address for EVM tokens, Solana for Solana, Bitcoin for Bitcoin, Tron for Tron.
|
|
5
5
|
*
|
|
6
6
|
* @param tokenIn - The input token asset info
|
|
7
7
|
* @param evmAddress - The user's EVM address (0x...) or null
|
|
8
8
|
* @param solAddress - The user's Solana address (base58) or null
|
|
9
9
|
* @param bitcoinAddress - The user's Bitcoin address or null
|
|
10
|
+
* @param tronAddress - The user's Tron address or null
|
|
10
11
|
* @returns The appropriate address for the token's chain, or undefined if no token/address
|
|
11
12
|
*/
|
|
12
|
-
export declare function useTransactionAddress(tokenIn: AssetInfo | null | undefined, evmAddress: string | null | undefined, solAddress: string | null | undefined, bitcoinAddress?: string | null | undefined): `0x${string}` | string | undefined;
|
|
13
|
+
export declare function useTransactionAddress(tokenIn: AssetInfo | null | undefined, evmAddress: string | null | undefined, solAddress: string | null | undefined, bitcoinAddress?: string | null | undefined, tronAddress?: string | null | undefined): `0x${string}` | string | undefined;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
|
-
import { isEvmAsset, isSolanaAsset, isBitcoinAsset } from '@silentswap/sdk';
|
|
2
|
+
import { isEvmAsset, isSolanaAsset, isBitcoinAsset, isTronAsset } from '@silentswap/sdk';
|
|
3
3
|
/**
|
|
4
4
|
* Hook to select the correct transaction/quote address based on the input token.
|
|
5
|
-
* Returns EVM address for EVM tokens, Solana
|
|
5
|
+
* Returns EVM address for EVM tokens, Solana for Solana, Bitcoin for Bitcoin, Tron for Tron.
|
|
6
6
|
*
|
|
7
7
|
* @param tokenIn - The input token asset info
|
|
8
8
|
* @param evmAddress - The user's EVM address (0x...) or null
|
|
9
9
|
* @param solAddress - The user's Solana address (base58) or null
|
|
10
10
|
* @param bitcoinAddress - The user's Bitcoin address or null
|
|
11
|
+
* @param tronAddress - The user's Tron address or null
|
|
11
12
|
* @returns The appropriate address for the token's chain, or undefined if no token/address
|
|
12
13
|
*/
|
|
13
|
-
export function useTransactionAddress(tokenIn, evmAddress, solAddress, bitcoinAddress) {
|
|
14
|
+
export function useTransactionAddress(tokenIn, evmAddress, solAddress, bitcoinAddress, tronAddress) {
|
|
14
15
|
return useMemo(() => {
|
|
15
16
|
if (!tokenIn) {
|
|
16
17
|
return (evmAddress ?? undefined);
|
|
@@ -19,12 +20,15 @@ export function useTransactionAddress(tokenIn, evmAddress, solAddress, bitcoinAd
|
|
|
19
20
|
return (evmAddress ?? undefined);
|
|
20
21
|
}
|
|
21
22
|
if (isSolanaAsset(tokenIn.caip19)) {
|
|
22
|
-
return solAddress ?? undefined;
|
|
23
|
+
return solAddress ?? undefined;
|
|
23
24
|
}
|
|
24
25
|
if (isBitcoinAsset(tokenIn.caip19)) {
|
|
25
|
-
return bitcoinAddress ?? undefined;
|
|
26
|
+
return bitcoinAddress ?? undefined;
|
|
27
|
+
}
|
|
28
|
+
if (isTronAsset(tokenIn.caip19)) {
|
|
29
|
+
return tronAddress ?? undefined;
|
|
26
30
|
}
|
|
27
31
|
// Default to EVM address
|
|
28
32
|
return (evmAddress ?? undefined);
|
|
29
|
-
}, [tokenIn?.caip19, evmAddress, solAddress, bitcoinAddress]);
|
|
33
|
+
}, [tokenIn?.caip19, evmAddress, solAddress, bitcoinAddress, tronAddress]);
|
|
30
34
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -60,4 +60,6 @@ export { createSolanaTransactionExecutor, convertRelaySolanaStepToTransaction, }
|
|
|
60
60
|
export type { SolanaWalletConnector, SolanaConnection } from './hooks/silent/solana-transaction.js';
|
|
61
61
|
export { createBitcoinTransactionExecutor, convertRelayBitcoinStepToTransaction, } from './hooks/silent/bitcoin-transaction.js';
|
|
62
62
|
export type { BitcoinWalletConnector, BitcoinConnection } from './hooks/silent/bitcoin-transaction.js';
|
|
63
|
+
export { createTronTransactionExecutor, convertRelayTronStepToTransaction, } from './hooks/silent/tron-transaction.js';
|
|
64
|
+
export type { TronWalletConnector, TronConnection } from './hooks/silent/tron-transaction.js';
|
|
63
65
|
export type { Outputs, IOutput } from './contexts/orderTrackingTypes.js';
|
package/dist/index.js
CHANGED
|
@@ -44,3 +44,5 @@ NI_CHAIN_ID_AVALANCHE, XT_TTL_SESSION_CACHE, X_MINIMUM_INPUT_USD, X_MAX_IMPACT_P
|
|
|
44
44
|
export { createSolanaTransactionExecutor, convertRelaySolanaStepToTransaction, } from './hooks/silent/solana-transaction.js';
|
|
45
45
|
// Bitcoin transaction utilities
|
|
46
46
|
export { createBitcoinTransactionExecutor, convertRelayBitcoinStepToTransaction, } from './hooks/silent/bitcoin-transaction.js';
|
|
47
|
+
// Tron transaction utilities
|
|
48
|
+
export { createTronTransactionExecutor, convertRelayTronStepToTransaction, } from './hooks/silent/tron-transaction.js';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@silentswap/react",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.51",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@bigmi/core": "^0.6.5",
|
|
26
26
|
"@ensdomains/ensjs": "^4.2.0",
|
|
27
|
-
"@silentswap/sdk": "0.1.
|
|
28
|
-
"@silentswap/ui-kit": "0.1.
|
|
27
|
+
"@silentswap/sdk": "0.1.51",
|
|
28
|
+
"@silentswap/ui-kit": "0.1.51",
|
|
29
29
|
"@solana/codecs-strings": "^5.1.0",
|
|
30
30
|
"@solana/kit": "^5.1.0",
|
|
31
31
|
"@solana/rpc": "^5.1.0",
|