-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: moving to another file for testing
- Loading branch information
1 parent
57a2032
commit 908a022
Showing
3 changed files
with
158 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import { ChainId, CrosschainQuote, Source } from '../types'; | ||
import { | ||
ERC20_TRANSFER_SIGNATURE, | ||
ETH_ADDRESS, | ||
RELAY_LINK_BRIDGING_RELAYER_ADDRESS, | ||
SOCKET_GATEWAY_CONTRACT_ADDRESSESS, | ||
} from './constants'; | ||
|
||
/** | ||
* Sanity checks the quote's returned address against the expected address stored in the SDK. | ||
* This function ensures the integrity and correctness of the destination address provided by the quote source. | ||
* | ||
* @param quoteSource The aggregator used for the quote. | ||
* @param chainID The origin network chain ID for the quote. | ||
* @param assertedAddress The destination address provided by the quote. | ||
* @returns {string} The destination address stored in the SDK for the provided (source, chainID) combination. | ||
* @throws {Error} Throws an error if any of the following conditions are met: | ||
* - The quote's destination address is undefined. | ||
* - No destination address is defined in the SDK for the provided (source, chainID) combination. | ||
* - The provided quote's destination address does not case-insensitively match the SDK's stored destination address. | ||
*/ | ||
export function getDestinationAddressForCrosschainSwap( | ||
quoteSource: Source | undefined, | ||
chainID: ChainId, | ||
assertedAddress: string | undefined | ||
): string { | ||
if (assertedAddress === undefined || assertedAddress === '') { | ||
throw new Error( | ||
`quote's allowance and to addresses must be defined (API Response)` | ||
); | ||
} | ||
let expectedAddress = getStoredAddressByCrosschainSource( | ||
quoteSource, | ||
chainID | ||
); | ||
if (expectedAddress === undefined || expectedAddress === '') { | ||
throw new Error( | ||
`expected source ${quoteSource}'s destination address on chainID ${chainID} must be defined (Swap SDK)` | ||
); | ||
} | ||
if (expectedAddress.toLowerCase() !== assertedAddress?.toLowerCase()) { | ||
throw new Error( | ||
`source ${quoteSource}'s destination address '${assertedAddress}' on chainID ${chainID} is not consistent, expected: '${expectedAddress}'` | ||
); | ||
} | ||
return expectedAddress!.toString(); | ||
} | ||
|
||
/** | ||
* Retrieves the destination address from a cross-chain quote object, returning undefined | ||
* when the quote source is not known or the quote does not contain a valid destination address. | ||
* | ||
* @param quote The cross-chain quote object returned by the API. | ||
* | ||
* @returns The destination address as a string if available. | ||
* Returns undefined if the quote does not properly specify a destination. | ||
* | ||
* @example | ||
* // Example for a quote from socket | ||
* const quoteSocket = { | ||
* to: '0x1234567890123456789012345678901234567890', | ||
* data: '0x...', | ||
* sellTokenAddress: '0x...' | ||
* }; | ||
* console.log(getToAddressFromCrosschainQuote(Source.CrosschainAggregatorSocket, quoteSocket)); | ||
* // Output: '0x1234567890123456789012345678901234567890' | ||
* | ||
* // Example for a quote from CrosschainAggregatorRelay where the sell token is ETH | ||
* const quoteRelayETH = { | ||
* to: '0xabcdefabcdefabcdefabcdefabcdefabcdefabcdef', | ||
* data: '0x...', | ||
* sellTokenAddress: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE' | ||
* }; | ||
* console.log(getToAddressFromCrosschainQuote(Source.CrosschainAggregatorRelay, quoteRelayETH)); | ||
* // Output: '0xabcdefabcdefabcdefabcdefabcdefabcdefabcdef' | ||
* | ||
* // Example for a quote from CrosschainAggregatorRelay where the sell token is not ETH | ||
* const quoteRelayERC20 = { | ||
* to: '0xabcdefabcdefabcdefabcdefabcdefabcdefabcdef', | ||
* data: '0xa9059cbb000000000000000000000000f70da97812cb96acdf810712aa562db8dfa3dbef...', | ||
* sellTokenAddress: '0x1234567890123456789012345678901234567890' | ||
* }; | ||
* console.log(getToAddressFromCrosschainQuote(Source.CrosschainAggregatorRelay, quoteRelayERC20)); | ||
* // Output: '0xf70da97812cb96acdf810712aa562db8dfa3dbef' (assuming the call data was a ERC20 transfer) | ||
*/ | ||
export function getToAddressFromCrosschainQuote( | ||
quote: CrosschainQuote | ||
): string | undefined { | ||
const quoteSource = quote.source; | ||
const validQuoteSource = quoteSource !== undefined; | ||
if (validQuoteSource && quoteSource === Source.CrosschainAggregatorSocket) { | ||
return quote.to; | ||
} | ||
if (validQuoteSource && quoteSource === Source.CrosschainAggregatorRelay) { | ||
if (quote.sellTokenAddress?.toLowerCase() === ETH_ADDRESS.toLowerCase()) { | ||
return quote.to; | ||
} | ||
return decodeERC20TransferData(quote.data); | ||
} | ||
return undefined; | ||
} | ||
|
||
/** | ||
* Decodes the ERC-20 token transfer data from a transaction's input data. | ||
* This function expects the input data to start with the ERC-20 transfer method ID (`0xa9059cbb`), | ||
* followed by the 64 hexadecimal characters for the destination address and 64 hexadecimal characters | ||
* for the transfer amount. The function will check and parse the input data, extracting the recipient's address | ||
* | ||
* The method assumes the data is properly formatted and begins with the correct method ID. | ||
* If the data does not conform to these expectations, the function will return an 'undefined' object. | ||
* | ||
* @param data The hex encoded input data string from an ERC-20 transfer transaction. This string | ||
* should include the method ID followed by the encoded parameters (address and amount). | ||
* | ||
* @returns { string | undefined } The destination address. If any error happens. | ||
* Returns 'undefined' if it could not decode the call data. | ||
*/ | ||
export function decodeERC20TransferData( | ||
data: string | undefined | ||
): string | undefined { | ||
if (!data?.startsWith(ERC20_TRANSFER_SIGNATURE)) { | ||
return undefined; | ||
} | ||
const paramsData = data.slice(ERC20_TRANSFER_SIGNATURE.length); | ||
if (paramsData.length >= 64 * 2) { | ||
return `0x${paramsData.slice(0, 64).replace(/^0+/, '')}`; | ||
} | ||
return undefined; | ||
} | ||
|
||
/** | ||
* Retrieves the destination address stored in the SDK corresponding to the specified aggregator and chain ID. | ||
* | ||
* @param quoteSource The aggregator used for the quote. | ||
* @param chainID The origin network chain ID for the quote. | ||
* @returns {string | undefined} The destination address stored in the SDK for the provided (source, chainID) combination. | ||
* Returns `undefined` if no address is stored for the specified combination. | ||
*/ | ||
export function getStoredAddressByCrosschainSource( | ||
quoteSource: Source | undefined, | ||
chainID: ChainId | ||
): string | undefined { | ||
const validSource = quoteSource !== undefined; | ||
if (validSource && quoteSource === Source.CrosschainAggregatorSocket) { | ||
return SOCKET_GATEWAY_CONTRACT_ADDRESSESS.get(chainID); | ||
} else if (validSource && quoteSource === Source.CrosschainAggregatorRelay) { | ||
return RELAY_LINK_BRIDGING_RELAYER_ADDRESS; | ||
} | ||
return undefined; | ||
} |