Skip to content
Merged
7 changes: 6 additions & 1 deletion packages/swapper/src/swappers/ButterSwap/ButterSwap.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import type { Swapper } from '../../types'
import { executeEvmTransaction, executeSolanaTransaction } from '../../utils'
import {
executeEvmTransaction,
executeSolanaTransaction,
executeTronTransaction,
} from '../../utils'

export const butterSwap: Swapper = {
executeEvmTransaction,
executeSolanaTransaction,
executeTronTransaction,
executeUtxoTransaction: (txToSign, { signAndBroadcastTransaction }) => {
return signAndBroadcastTransaction(txToSign)
},
Expand Down
4 changes: 4 additions & 0 deletions packages/swapper/src/swappers/ButterSwap/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import BigNumber from 'bignumber.js'

import { getSolanaTransactionFees } from '../../solana-utils/getSolanaTransactionFees'
import { getUnsignedSolanaTransaction } from '../../solana-utils/getUnsignedSolanaTransaction'
import { getTronTransactionFees } from '../../tron-utils/getTronTransactionFees'
import { getUnsignedTronTransaction } from '../../tron-utils/getUnsignedTronTransaction'
import type { SwapperApi } from '../../types'
import { getExecutableTradeStep, isExecutableTradeQuote } from '../../utils'
import { checkTradeStatus } from './swapperApi/checkTradeStatus'
Expand Down Expand Up @@ -85,4 +87,6 @@ export const butterSwapApi: SwapperApi = {
},
getUnsignedSolanaTransaction,
getSolanaTransactionFees,
getTronTransactionFees,
getUnsignedTronTransaction,
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { solanaChainId } from '@shapeshiftoss/caip'
import { solanaChainId, tronChainId } from '@shapeshiftoss/caip'
import { isEvmChainId } from '@shapeshiftoss/chain-adapters'
import { TxStatus } from '@shapeshiftoss/unchained-client'

Expand Down Expand Up @@ -52,6 +52,31 @@ export const checkTradeStatus = async (input: CheckTradeStatusInput): Promise<Tr
})
}

if (sellChainId === tronChainId) {
const adapter = input.assertGetTronChainAdapter(tronChainId)
const tx = await adapter.httpProvider.getTransaction({ txid: txHash })

if (!tx) {
return createDefaultStatusResponse(txHash)
}

const contractRet = tx.ret?.[0]?.contractRet

// Only mark as confirmed if SUCCESS AND has confirmations (in a block)
const status =
contractRet === 'SUCCESS' && tx.confirmations > 0
? TxStatus.Confirmed
: contractRet === 'REVERT'
? TxStatus.Failed
: TxStatus.Pending
Comment thread
NeOMakinG marked this conversation as resolved.

return {
status,
buyTxHash: txHash,
message: undefined,
}
}

// Fallback: unknown same-chain type (should never happen for Butter, but just in case). Avoid bridge polling.
return createDefaultStatusResponse(txHash)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { btcAssetId, btcChainId, solanaChainId } from '@shapeshiftoss/caip'
import { btcAssetId, btcChainId, solanaChainId, tronChainId } from '@shapeshiftoss/caip'
import { isEvmChainId } from '@shapeshiftoss/chain-adapters'
import {
bnOrZero,
Expand Down Expand Up @@ -52,7 +52,8 @@ export const getTradeQuote = async (
if (
!isEvmChainId(sellAsset.chainId) &&
sellAsset.chainId !== btcChainId &&
sellAsset.chainId !== solanaChainId
sellAsset.chainId !== solanaChainId &&
sellAsset.chainId !== tronChainId
) {
return Err(
makeSwapErrorRight({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { btcAssetId, btcChainId, solanaChainId } from '@shapeshiftoss/caip'
import { btcAssetId, btcChainId, solanaChainId, tronChainId } from '@shapeshiftoss/caip'
import { isEvmChainId } from '@shapeshiftoss/chain-adapters'
import {
bn,
Expand Down Expand Up @@ -42,7 +42,8 @@ export const getTradeRate = async (
if (
!isEvmChainId(sellAsset.chainId) &&
sellAsset.chainId !== btcChainId &&
sellAsset.chainId !== solanaChainId
sellAsset.chainId !== solanaChainId &&
sellAsset.chainId !== tronChainId
) {
return Err(
makeSwapErrorRight({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const BUTTERSWAP_CHAIN_ID_TO_CHAIN_ID: Record<number, KnownChainIds> = {
43114: KnownChainIds.AvalancheMainnet,
1360108768460801: KnownChainIds.SolanaMainnet,
1360095883558913: KnownChainIds.BitcoinMainnet,
728126428: KnownChainIds.TronMainnet,
}

const CHAIN_ID_TO_BUTTERSWAP_CHAIN_ID: Record<KnownChainIds, number> = Object.entries(
Expand Down
5 changes: 4 additions & 1 deletion packages/swapper/src/swappers/ButterSwap/xhr.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { fromAssetId, solanaChainId } from '@shapeshiftoss/caip'
import { fromAssetId, solanaChainId, tronChainId } from '@shapeshiftoss/caip'
import type { Asset } from '@shapeshiftoss/types'
import { chainIdToFeeAssetId } from '@shapeshiftoss/utils'
import type { Result } from '@sniptt/monads'
Expand Down Expand Up @@ -39,6 +39,7 @@ export type GetButterRouteArgs = {
}

const SOLANA_NATIVE_ADDRESS = 'So11111111111111111111111111111111111111112'
const TRON_NATIVE_ADDRESS = 'T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb'

export const getButterRoute = async ({
sellAsset,
Expand Down Expand Up @@ -67,12 +68,14 @@ export const getButterRoute = async ({

const sellAssetAddress = (() => {
if (sellAsset.chainId === solanaChainId && sellAssetIsNative) return SOLANA_NATIVE_ADDRESS
if (sellAsset.chainId === tronChainId && sellAssetIsNative) return TRON_NATIVE_ADDRESS
if (sellAssetIsNative) return zeroAddress
return sellAssetAddressRaw
})()

const buyAssetAddress = (() => {
if (buyAsset.chainId === solanaChainId && buyAssetIsNative) return SOLANA_NATIVE_ADDRESS
if (buyAsset.chainId === tronChainId && buyAssetIsNative) return TRON_NATIVE_ADDRESS
if (buyAssetIsNative) return zeroAddress
return buyAssetAddressRaw
})()
Expand Down
13 changes: 11 additions & 2 deletions packages/swapper/src/tron-utils/getUnsignedTronTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,20 @@ export const getUnsignedTronTransaction = ({

const step = getExecutableTradeStep(tradeQuote, stepIndex)

const { accountNumber, sellAsset, relayTransactionMetadata, nearIntentsSpecific } = step
const {
accountNumber,
sellAsset,
relayTransactionMetadata,
nearIntentsSpecific,
butterSwapTransactionMetadata,
} = step

const adapter = assertGetTronChainAdapter(sellAsset.chainId)

const to = relayTransactionMetadata?.to ?? nearIntentsSpecific?.depositAddress
const to =
relayTransactionMetadata?.to ??
nearIntentsSpecific?.depositAddress ??
butterSwapTransactionMetadata?.to
if (!to) throw new Error('Missing transaction destination address')

const value = step.sellAmountIncludingProtocolFeesCryptoBaseUnit
Expand Down