@silentswap/react 0.0.43 → 0.0.45
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/OrdersContext.js +1 -0
- package/dist/contexts/SilentSwapContext.js +9 -5
- package/dist/hooks/silent/bitcoin-transaction.d.ts +42 -0
- package/dist/hooks/silent/bitcoin-transaction.js +92 -0
- package/dist/hooks/silent/useBridgeExecution.js +4 -10
- package/dist/hooks/useStatus.js +25 -3
- package/dist/hooks/useSwap.d.ts +1 -1
- package/dist/hooks/useSwap.js +1 -1
- package/dist/hooks/useTransaction.js +6 -18
- package/package.json +3 -3
|
@@ -45,6 +45,7 @@ export const OrdersProvider = ({ children }) => {
|
|
|
45
45
|
// Get baseUrl from environment
|
|
46
46
|
const { config } = useSilentSwap();
|
|
47
47
|
const baseUrl = config.baseUrl;
|
|
48
|
+
console.log('[OrdersContext] Using baseUrl:', baseUrl, 'from config:', config);
|
|
48
49
|
// Fetch recent orders from API (matches Svelte implementation)
|
|
49
50
|
const request_recent_orders = useCallback(async (sb58_auth_view) => {
|
|
50
51
|
try {
|
|
@@ -197,9 +197,13 @@ function SilentSwapInnerProvider({ children, client, evmAddress, solAddress, sol
|
|
|
197
197
|
}, children: children });
|
|
198
198
|
}
|
|
199
199
|
export function SilentSwapProvider({ children, client, evmAddress, solAddress, connector, isConnected, solanaConnector, solanaConnection, environment = ENVIRONMENT.STAGING, baseUrl, solanaRpcUrl, walletClient, }) {
|
|
200
|
-
const config = useMemo(() =>
|
|
201
|
-
environment
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
200
|
+
const config = useMemo(() => {
|
|
201
|
+
const computedBaseUrl = baseUrl ?? ENVIRONMENT_CONFIGS[environment].baseUrl;
|
|
202
|
+
console.log('[SilentSwapProvider] Creating config:', { environment, baseUrl, computedBaseUrl });
|
|
203
|
+
return {
|
|
204
|
+
environment,
|
|
205
|
+
baseUrl: computedBaseUrl,
|
|
206
|
+
};
|
|
207
|
+
}, [environment, baseUrl]);
|
|
208
|
+
return (_jsx(AssetsProvider, { children: _jsx(PricesProvider, { children: _jsx(BalancesProvider, { evmAddress: evmAddress, solAddress: solAddress, solanaRpcUrl: solanaRpcUrl, children: _jsx(SilentSwapInnerProvider, { client: client, connector: connector, isConnected: isConnected, evmAddress: evmAddress, solAddress: solAddress, solanaConnector: solanaConnector, solanaConnection: solanaConnection, environment: environment, config: config, solanaRpcUrl: solanaRpcUrl, walletClient: walletClient, children: _jsx(OrdersProvider, { children: children }) }) }) }) }));
|
|
205
209
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { BridgeTransaction } from '@silentswap/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Bitcoin wallet connector interface
|
|
4
|
+
* Compatible with Bitcoin wallet adapters (e.g., Unisat, Xverse, etc.)
|
|
5
|
+
*/
|
|
6
|
+
export interface BitcoinWalletConnector {
|
|
7
|
+
signPsbt: (psbt: string) => Promise<string>;
|
|
8
|
+
sendPsbt: (psbt: string) => Promise<string>;
|
|
9
|
+
getAccounts: () => Promise<string[]>;
|
|
10
|
+
currentAccount?: string | null;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Bitcoin connection interface
|
|
14
|
+
* For Bitcoin, we typically don't need a separate connection object
|
|
15
|
+
* as wallets handle RPC communication internally
|
|
16
|
+
*/
|
|
17
|
+
export interface BitcoinConnection {
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Bitcoin transaction executor type
|
|
21
|
+
* Similar to SolanaTransactionExecutor but for Bitcoin PSBTs
|
|
22
|
+
*/
|
|
23
|
+
export type BitcoinTransactionExecutor = (tx: BridgeTransaction) => Promise<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Create a Bitcoin transaction executor
|
|
26
|
+
* This function creates a transaction executor that can handle Bitcoin transactions
|
|
27
|
+
* from relay.link bridge quotes
|
|
28
|
+
*
|
|
29
|
+
* @param connector - Bitcoin wallet connector
|
|
30
|
+
* @param connection - Bitcoin connection (optional, for consistency with Solana pattern)
|
|
31
|
+
* @returns Bitcoin transaction executor function
|
|
32
|
+
*/
|
|
33
|
+
export declare function createBitcoinTransactionExecutor(connector: BitcoinWalletConnector, _connection?: BitcoinConnection): BitcoinTransactionExecutor;
|
|
34
|
+
/**
|
|
35
|
+
* Helper to convert relay.link Bitcoin step data to BridgeTransaction
|
|
36
|
+
* Note: Bitcoin transactions from relay.link provide PSBTs in base64 format in the 'psbt' field
|
|
37
|
+
*/
|
|
38
|
+
export declare function convertRelayBitcoinStepToTransaction(stepData: {
|
|
39
|
+
psbt?: string;
|
|
40
|
+
hex?: string;
|
|
41
|
+
data?: string;
|
|
42
|
+
}, chainId: number): BridgeTransaction;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create a Bitcoin transaction executor
|
|
3
|
+
* This function creates a transaction executor that can handle Bitcoin transactions
|
|
4
|
+
* from relay.link bridge quotes
|
|
5
|
+
*
|
|
6
|
+
* @param connector - Bitcoin wallet connector
|
|
7
|
+
* @param connection - Bitcoin connection (optional, for consistency with Solana pattern)
|
|
8
|
+
* @returns Bitcoin transaction executor function
|
|
9
|
+
*/
|
|
10
|
+
export function createBitcoinTransactionExecutor(connector, _connection) {
|
|
11
|
+
return async (tx) => {
|
|
12
|
+
try {
|
|
13
|
+
if (!connector.currentAccount) {
|
|
14
|
+
const accounts = await connector.getAccounts();
|
|
15
|
+
if (!accounts || accounts.length === 0) {
|
|
16
|
+
throw new Error('Bitcoin wallet not connected');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
console.log('Creating Bitcoin transaction:', {
|
|
20
|
+
hasData: !!tx.data,
|
|
21
|
+
hasInstructions: !!tx.instructions,
|
|
22
|
+
instructionsCount: tx.instructions?.length,
|
|
23
|
+
});
|
|
24
|
+
// Bitcoin transactions from relay.link come as PSBTs (Partially Signed Bitcoin Transactions)
|
|
25
|
+
// The PSBT is provided in base64 format in the 'psbt' field of the step data
|
|
26
|
+
// We store it in tx.data, but it's actually base64, not hex
|
|
27
|
+
// Check if we have a psbt field in the transaction (for direct PSBT passing)
|
|
28
|
+
let psbtBase64;
|
|
29
|
+
// Check if tx has a psbt property (for direct PSBT passing)
|
|
30
|
+
if (tx.psbt) {
|
|
31
|
+
psbtBase64 = tx.psbt;
|
|
32
|
+
}
|
|
33
|
+
else if (tx.data) {
|
|
34
|
+
// If data is provided, check if it's base64 or hex
|
|
35
|
+
const dataStr = tx.data.replace(/^0x/, '');
|
|
36
|
+
// Check if it looks like base64 (contains base64 characters and is longer)
|
|
37
|
+
// Base64 PSBTs from relay.link are typically long strings without 0x prefix
|
|
38
|
+
// Hex would be even length and only contain 0-9a-f
|
|
39
|
+
const isBase64 = /^[A-Za-z0-9+/=]+$/.test(dataStr) && dataStr.length > 100;
|
|
40
|
+
if (isBase64) {
|
|
41
|
+
// Already base64
|
|
42
|
+
psbtBase64 = dataStr;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// Convert hex to base64
|
|
46
|
+
const psbtBytes = Buffer.from(dataStr, 'hex');
|
|
47
|
+
psbtBase64 = psbtBytes.toString('base64');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
throw new Error('Bitcoin transaction must have PSBT data');
|
|
52
|
+
}
|
|
53
|
+
console.log('Requesting PSBT signature...');
|
|
54
|
+
// Sign PSBT with wallet (wallet expects base64)
|
|
55
|
+
const signedPsbt = await connector.signPsbt(psbtBase64);
|
|
56
|
+
console.log('PSBT signed');
|
|
57
|
+
console.log('Sending PSBT...');
|
|
58
|
+
// Send signed PSBT (wallet returns base64)
|
|
59
|
+
const txHash = await connector.sendPsbt(signedPsbt);
|
|
60
|
+
console.log('Bitcoin transaction sent:', txHash);
|
|
61
|
+
return txHash;
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.error('Bitcoin transaction execution failed:', {
|
|
65
|
+
error: error instanceof Error ? error.message : String(error),
|
|
66
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
67
|
+
});
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Helper to convert relay.link Bitcoin step data to BridgeTransaction
|
|
74
|
+
* Note: Bitcoin transactions from relay.link provide PSBTs in base64 format in the 'psbt' field
|
|
75
|
+
*/
|
|
76
|
+
export function convertRelayBitcoinStepToTransaction(stepData, chainId) {
|
|
77
|
+
// Extract PSBT from step data
|
|
78
|
+
// relay.link provides it as 'psbt' in base64 format (see example response)
|
|
79
|
+
const psbtData = stepData.psbt || stepData.hex || stepData.data;
|
|
80
|
+
if (!psbtData) {
|
|
81
|
+
throw new Error('Bitcoin transaction step must have psbt, hex, or data field');
|
|
82
|
+
}
|
|
83
|
+
// relay.link provides PSBT in base64 format directly
|
|
84
|
+
// We store it in the transaction object with a psbt property for direct access
|
|
85
|
+
// Also store in data field for compatibility (as base64 string, not hex)
|
|
86
|
+
return {
|
|
87
|
+
chainId,
|
|
88
|
+
data: psbtData, // Store base64 PSBT (type assertion for compatibility)
|
|
89
|
+
// Add psbt property for direct access
|
|
90
|
+
...{ psbt: psbtData },
|
|
91
|
+
};
|
|
92
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useCallback } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { ensureChain, waitForTransactionConfirmation, NI_CHAIN_ID_AVALANCHE, S0X_ADDR_USDC_AVALANCHE, X_MAX_IMPACT_PERCENT, getRelayStatus, getDebridgeStatus, fetchDebridgeOrder, fetchRelayQuote, createPhonyDepositCalldata, isSolanaAsset, parseSolanaCaip19, isSolanaNativeToken, isSplToken, N_RELAY_CHAIN_ID_SOLANA, SB58_ADDR_SOL_PROGRAM_SYSTEM, getChainById, } from '@silentswap/sdk';
|
|
2
|
+
import { encodeFunctionData, erc20Abi, getAddress } from 'viem';
|
|
3
|
+
import { ensureChain, waitForTransactionConfirmation, createPublicClientWithRpc, NI_CHAIN_ID_AVALANCHE, S0X_ADDR_USDC_AVALANCHE, X_MAX_IMPACT_PERCENT, getRelayStatus, getDebridgeStatus, fetchDebridgeOrder, fetchRelayQuote, createPhonyDepositCalldata, isSolanaAsset, parseSolanaCaip19, isSolanaNativeToken, isSplToken, N_RELAY_CHAIN_ID_SOLANA, SB58_ADDR_SOL_PROGRAM_SYSTEM, getChainById, } from '@silentswap/sdk';
|
|
4
4
|
import { createSolanaTransactionExecutor, convertRelaySolanaStepToTransaction } from './solana-transaction.js';
|
|
5
5
|
const S0X_ADDR_EVM_ZERO = '0x0000000000000000000000000000000000000000';
|
|
6
6
|
const XG_UINT256_MAX = (1n << 256n) - 1n;
|
|
@@ -28,14 +28,8 @@ async function ensureChainAndCreateClient(chainId, walletClient, connector) {
|
|
|
28
28
|
const wallet = await ensureChain(chainId, walletClient, connector);
|
|
29
29
|
// Use wallet's chain if available, otherwise look up chain by ID
|
|
30
30
|
const chain = wallet.chain || getChainById(chainId);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
// Create public client - viem has complex union types that TypeScript struggles with
|
|
35
|
-
const publicClient = createPublicClient({
|
|
36
|
-
chain,
|
|
37
|
-
transport: http(),
|
|
38
|
-
});
|
|
31
|
+
// Create public client with RPC fallback configuration
|
|
32
|
+
const publicClient = createPublicClientWithRpc(chainId, chain);
|
|
39
33
|
return { wallet, publicClient };
|
|
40
34
|
}
|
|
41
35
|
/**
|
package/dist/hooks/useStatus.js
CHANGED
|
@@ -4,28 +4,50 @@ import { useSilentSwap } from '../contexts/SilentSwapContext.js';
|
|
|
4
4
|
* Hook to fetch the current platform status, fee rates, and limits
|
|
5
5
|
*/
|
|
6
6
|
export function useStatus() {
|
|
7
|
-
const { config } = useSilentSwap();
|
|
7
|
+
const { config, client } = useSilentSwap();
|
|
8
8
|
const baseUrl = config.baseUrl;
|
|
9
9
|
const [status, setStatus] = useState({});
|
|
10
10
|
const [isLoading, setIsLoading] = useState(true);
|
|
11
11
|
const [error, setError] = useState(null);
|
|
12
12
|
useEffect(() => {
|
|
13
|
+
// Skip if baseUrl is not yet available (shouldn't happen, but safety check)
|
|
14
|
+
if (!baseUrl) {
|
|
15
|
+
console.warn('[useStatus] baseUrl is not available yet');
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
// Skip if we're using the default/placeholder context
|
|
19
|
+
// The DEFAULT_CONTEXT has client: {} as SilentSwapClient (empty object placeholder)
|
|
20
|
+
// Real SilentSwapClient instances are class instances, not plain objects
|
|
21
|
+
// Check if client is the placeholder by verifying it's a plain empty object
|
|
22
|
+
const isPlaceholderClient = client &&
|
|
23
|
+
typeof client === 'object' &&
|
|
24
|
+
Object.getPrototypeOf(client) === Object.prototype &&
|
|
25
|
+
Object.keys(client).length === 0;
|
|
26
|
+
if (isPlaceholderClient) {
|
|
27
|
+
console.warn('[useStatus] Context not yet initialized (placeholder client detected), skipping fetch until real context is available');
|
|
28
|
+
setIsLoading(false);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
13
31
|
let isMounted = true;
|
|
14
32
|
const fetchStatus = async () => {
|
|
15
33
|
try {
|
|
16
34
|
setIsLoading(true);
|
|
17
|
-
const
|
|
35
|
+
const statusUrl = `${baseUrl}/status`;
|
|
36
|
+
console.log('[useStatus] Fetching status from:', statusUrl, 'environment:', config.environment);
|
|
37
|
+
const response = await fetch(statusUrl);
|
|
18
38
|
if (!response.ok) {
|
|
19
39
|
throw new Error(`Failed to fetch status: ${response.statusText}`);
|
|
20
40
|
}
|
|
21
41
|
const data = await response.json();
|
|
22
42
|
if (isMounted) {
|
|
43
|
+
console.log('[useStatus] Status fetched successfully from:', statusUrl);
|
|
23
44
|
setStatus(data);
|
|
24
45
|
setError(null);
|
|
25
46
|
}
|
|
26
47
|
}
|
|
27
48
|
catch (err) {
|
|
28
49
|
if (isMounted) {
|
|
50
|
+
console.error('[useStatus] Failed to fetch status from:', baseUrl, err);
|
|
29
51
|
setError(err instanceof Error ? err : new Error('Failed to fetch status'));
|
|
30
52
|
// Use defaults on error
|
|
31
53
|
setStatus({});
|
|
@@ -41,7 +63,7 @@ export function useStatus() {
|
|
|
41
63
|
return () => {
|
|
42
64
|
isMounted = false;
|
|
43
65
|
};
|
|
44
|
-
}, [baseUrl]);
|
|
66
|
+
}, [baseUrl, config.environment]);
|
|
45
67
|
// Convert overheadUsd from string to number
|
|
46
68
|
const overheadUsd = status.overheadUsd ? parseFloat(status.overheadUsd) : 0;
|
|
47
69
|
// serviceFeeRate is a Decimal (0.01 = 1%), convert to number
|
package/dist/hooks/useSwap.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type AssetInfo } from '@silentswap/sdk';
|
|
2
2
|
export declare const X_RANGE_SLIDER_MIN_GAP = 0.01;
|
|
3
|
-
export declare const OUTPUT_LIMIT =
|
|
3
|
+
export declare const OUTPUT_LIMIT = 10;
|
|
4
4
|
export declare const DEFAULT_SOURCE_ASSET = "eip155:1/slip44:60";
|
|
5
5
|
export declare const DEFAULT_DEST_ASSET = "eip155:1/erc20:0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599";
|
|
6
6
|
export declare const DEFAULT_OUTPUT_ASSET = "eip155:8453/erc20:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
package/dist/hooks/useSwap.js
CHANGED
|
@@ -4,7 +4,7 @@ import { getAssetByCaip19 } from '@silentswap/sdk';
|
|
|
4
4
|
const DEFAULT_SLIPPAGE = 1;
|
|
5
5
|
// Constants matching Svelte app
|
|
6
6
|
export const X_RANGE_SLIDER_MIN_GAP = 0.01;
|
|
7
|
-
export const OUTPUT_LIMIT =
|
|
7
|
+
export const OUTPUT_LIMIT = 10;
|
|
8
8
|
// Default assets
|
|
9
9
|
export const DEFAULT_SOURCE_ASSET = 'eip155:1/slip44:60'; // ETH on Ethereum
|
|
10
10
|
export const DEFAULT_DEST_ASSET = 'eip155:1/erc20:0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599'; // WBTC on Ethereum
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useCallback, useState } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { executeRelayBridge, executeDebridgeBridge, getBridgeStatus, createTransactionExecutor, createChainSwitcher, ensureChain, waitForTransactionConfirmation, parseTransactionRequestForViem, getChainById, } from '@silentswap/sdk';
|
|
2
|
+
import { erc20Abi } from 'viem';
|
|
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
|
/**
|
|
6
6
|
* React hook for executing transactions
|
|
@@ -204,16 +204,10 @@ export function useTransaction({ walletClient, connector, solanaConnector, solan
|
|
|
204
204
|
const chainId = transactionParams.chainId ?? 1;
|
|
205
205
|
// Ensure correct chain
|
|
206
206
|
const wallet = await ensureChain(chainId, walletClient, connector);
|
|
207
|
-
// Create public client
|
|
207
|
+
// Create public client with RPC fallback configuration
|
|
208
208
|
// Use wallet's chain if available, otherwise look up chain by ID
|
|
209
209
|
const chain = wallet.chain || getChainById(chainId);
|
|
210
|
-
|
|
211
|
-
throw new Error(`Unsupported chain ID: ${chainId}. Please ensure the chain is supported.`);
|
|
212
|
-
}
|
|
213
|
-
const publicClient = createPublicClient({
|
|
214
|
-
chain,
|
|
215
|
-
transport: http(),
|
|
216
|
-
});
|
|
210
|
+
const publicClient = createPublicClientWithRpc(chainId, chain);
|
|
217
211
|
setCurrentStep('Sending transaction');
|
|
218
212
|
onStatus?.('Sending transaction');
|
|
219
213
|
// Execute transaction
|
|
@@ -269,16 +263,10 @@ export function useTransaction({ walletClient, connector, solanaConnector, solan
|
|
|
269
263
|
try {
|
|
270
264
|
// Switch to source chain for approval
|
|
271
265
|
const wallet = await ensureChain(chainId, walletClient, connector);
|
|
272
|
-
//
|
|
266
|
+
// Create public client with RPC fallback configuration
|
|
273
267
|
// Use wallet's chain if available, otherwise look up chain by ID
|
|
274
268
|
const chain = wallet.chain || getChainById(chainId);
|
|
275
|
-
|
|
276
|
-
throw new Error(`Unsupported chain ID: ${chainId}. Please ensure the chain is supported.`);
|
|
277
|
-
}
|
|
278
|
-
const publicClient = createPublicClient({
|
|
279
|
-
chain,
|
|
280
|
-
transport: http(),
|
|
281
|
-
});
|
|
269
|
+
const publicClient = createPublicClientWithRpc(chainId, chain);
|
|
282
270
|
const currentAllowance = (await publicClient.readContract({
|
|
283
271
|
address: tokenAddress,
|
|
284
272
|
abi: erc20Abi,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@silentswap/react",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.45",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@ensdomains/ensjs": "^4.2.0",
|
|
26
|
-
"@silentswap/sdk": "0.0.
|
|
27
|
-
"@silentswap/ui-kit": "0.0.
|
|
26
|
+
"@silentswap/sdk": "0.0.45",
|
|
27
|
+
"@silentswap/ui-kit": "0.0.45",
|
|
28
28
|
"@solana/codecs-strings": "^5.1.0",
|
|
29
29
|
"@solana/kit": "^5.1.0",
|
|
30
30
|
"@solana/rpc": "^5.1.0",
|