From 074893c5ba597e7b40c60d71dd8c52ff7afa0082 Mon Sep 17 00:00:00 2001 From: Apotheosis <0xapotheosis@gmail.com> Date: Tue, 27 Jan 2026 11:06:29 +1100 Subject: [PATCH 1/2] fix: update thorchain api endpoint in swap widget (#90) The daemon.thorchain.shapeshift.com domain has been deprecated. Updated to use api.thorchain.shapeshift.com which is the correct endpoint, matching the fix applied to the main web repo in commit 7de6e916af. Co-authored-by: Claude Opus 4.5 --- app/[lang]/_components/trading/TradingWidget.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/[lang]/_components/trading/TradingWidget.tsx b/app/[lang]/_components/trading/TradingWidget.tsx index 7dc5a86..7530394 100644 --- a/app/[lang]/_components/trading/TradingWidget.tsx +++ b/app/[lang]/_components/trading/TradingWidget.tsx @@ -45,7 +45,7 @@ export function TradingWidget(): ReactNode { setIsLoading(true) const numericAmount = Number(debouncedAmount) fetch( - `https://daemon.thorchain.shapeshift.com/lcd/thorchain/quote/swap?amount=${numericAmount * 10 ** (fromToken.decimals[toToken.symbol?.toLowerCase() || 'eth'] || 6)}&from_asset=${fromChain.requestKey}.${fromToken.requestKey}&to_asset=${toChain.requestKey}.${toToken.requestKey}&affiliate_bps=64&affiliate=ss&streaming_interval=1` + `https://api.thorchain.shapeshift.com/lcd/thorchain/quote/swap?amount=${numericAmount * 10 ** (fromToken.decimals[toToken.symbol?.toLowerCase() || 'eth'] || 6)}&from_asset=${fromChain.requestKey}.${fromToken.requestKey}&to_asset=${toChain.requestKey}.${toToken.requestKey}&affiliate_bps=64&affiliate=ss&streaming_interval=1` ) .then(async res => res.json()) .then(data => { From dbbd7fcdd156bce568a989d1ef7cfa7bbc59787b Mon Sep 17 00:00:00 2001 From: Apotheosis <0xapotheosis@gmail.com> Date: Tue, 27 Jan 2026 11:42:21 +1100 Subject: [PATCH 2/2] fix: enable Solana swaps via Chainflip with correct decimals (#91) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: fix Solana swap rates in trading widget - Remove outdated blocking logic that prevented SOL→BTC, SOL→ETH, and ETH→SOL pairs from fetching quotes - Add getChainflipAssetId helper to map token/chain combinations to correct Chainflip asset identifiers (e.g., ETH on any chain maps to Eth.Eth since Chainflip only supports ETH on Ethereum mainnet) Chainflip now supports all these pairs and returns valid quotes. Co-Authored-By: Claude Opus 4.5 * fix: use correct decimals for Chainflip API requests SOL → ETH swaps were failing because the amount calculation used the destination token's decimals instead of the source token's native decimals. Added getChainflipDecimals helper to return correct decimals for each asset (SOL=9, BTC=8, ETH=18, USDT=6). Co-Authored-By: Claude * fix: use BigInt for Chainflip amount to avoid scientific notation JavaScript's Number type can produce scientific notation (1e+18) for large numbers when converted to string, which the Chainflip API may not parse correctly. Using BigInt ensures the amount is formatted as a proper integer string (1000000000000000000). Co-Authored-By: Claude * fix: use correct decimals for output amount display For Chainflip swaps (Solana involved), use getChainflipDecimals for the destination token. For THORChain swaps, use the existing decimals lookup. This fixes the output showing in scientific notation. Co-Authored-By: Claude --------- Co-authored-by: Claude Opus 4.5 --- .../_components/trading/TradingWidget.tsx | 57 ++++++++++++++----- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/app/[lang]/_components/trading/TradingWidget.tsx b/app/[lang]/_components/trading/TradingWidget.tsx index 7530394..f2d0556 100644 --- a/app/[lang]/_components/trading/TradingWidget.tsx +++ b/app/[lang]/_components/trading/TradingWidget.tsx @@ -17,6 +17,37 @@ import type {TChain} from './ChainSelect' import type {TToken} from './TokenSelect' import type {ReactNode} from 'react' +const getChainflipAssetId = (token: TToken, chain: TChain): string => { + if (token.symbol === 'SOL') { + return 'Sol.Sol' + } + if (token.symbol === 'BTC') { + return 'Btc.Btc' + } + if (token.symbol === 'ETH') { + return 'Eth.Eth' + } + if (token.symbol === 'USDT') { + return 'Usdt.Eth' + } + return `${token.symbol}.${chain.requestKey}` +} + +const getChainflipDecimals = (token: TToken): number => { + switch (token.symbol) { + case 'SOL': + return 9 + case 'BTC': + return 8 + case 'ETH': + return 18 + case 'USDT': + return 6 + default: + return 18 + } +} + export function TradingWidget(): ReactNode { const [fromToken, setFromToken] = useState(SUPPORTED_TOKENS[0]) const [toToken, setToToken] = useState(SUPPORTED_TOKENS[1]) @@ -76,8 +107,12 @@ export function TradingWidget(): ReactNode { setIsLoading(true) try { const numericAmount = Number(debouncedAmount) + const sourceAsset = getChainflipAssetId(fromToken, fromChain) + const destinationAsset = getChainflipAssetId(toToken, toChain) + const decimals = getChainflipDecimals(fromToken) + const amountInBaseUnits = BigInt(Math.round(numericAmount * 10 ** decimals)).toString() fetch( - `https://chainflip-broker.io/quotes-native?apiKey=09bc0796ff40435482c0a54fa6ae2784&sourceAsset=${fromToken.symbol}.${fromChain.requestKey}&destinationAsset=${toToken.symbol}.${toChain.requestKey}&amount=${numericAmount * 10 ** (fromToken.decimals[toToken.symbol?.toLowerCase() || 'eth'] || 6)}&commissionBps=63` + `https://chainflip-broker.io/quotes-native?apiKey=09bc0796ff40435482c0a54fa6ae2784&sourceAsset=${sourceAsset}&destinationAsset=${destinationAsset}&amount=${amountInBaseUnits}&commissionBps=63` ) .then(async res => res.json()) .then(data => { @@ -98,11 +133,10 @@ export function TradingWidget(): ReactNode { } }, [ debouncedAmount, - fromToken.symbol, - fromToken.decimals, - fromChain.requestKey, - toToken.symbol, - toChain.requestKey + fromChain, + fromToken, + toChain, + toToken ]) useEffect(() => { @@ -113,13 +147,6 @@ export function TradingWidget(): ReactNode { if (toToken.symbol === fromToken.symbol && toChain.id === fromChain.id) { return setError('Please select different tokens') } - if ( - (fromChain.id === 'solana' && toChain.id === 'bitcoin') || - (fromToken.symbol === 'SOL' && toToken.symbol === 'ETH') || - (fromToken.symbol === 'ETH' && toToken.symbol === 'SOL') - ) { - return setError('No rate available') - } if (fromChain.id === 'solana' || toChain.id === 'solana') { return fetchFromChainFlip() @@ -321,7 +348,9 @@ export function TradingWidget(): ReactNode { {formatNumber( outputAmount.amount, outputAmount.isNative, - toToken.decimals[fromToken.symbol?.toLowerCase() || 'eth'] || 6 + fromChain.id === 'solana' || toChain.id === 'solana' + ? getChainflipDecimals(toToken) + : toToken.decimals[fromToken.symbol?.toLowerCase() || 'eth'] || 6 )} )}