diff --git a/api/helper.ts b/api/helper.ts index d746791a..c6e7eba7 100644 --- a/api/helper.ts +++ b/api/helper.ts @@ -298,6 +298,12 @@ export function parseMempoolStxTransactionsData({ return parsedTx; } +/** + * parseStxTransactionData + * @param responseTx StxTransactionDataResponse + * @param stxAddress string + * @returns StxTransactionData parsed for display + */ export function parseStxTransactionData({ responseTx, stxAddress, @@ -329,23 +335,27 @@ export function parseStxTransactionData({ // add token transfer data if type is token transfer if (parsedTx.txType === 'token_transfer') { + const amount = new BigNumber(responseTx.token_transfer?.amount ?? 0); parsedTx.tokenTransfer = { - recipientAddress: responseTx.token_transfer.recipient_address, - amount: new BigNumber(responseTx.token_transfer.amount), - memo: responseTx.token_transfer.memo, + recipientAddress: responseTx.token_transfer?.recipient_address, + amount, + memo: responseTx.token_transfer?.memo, }; - const amount = new BigNumber(responseTx.token_transfer.amount); parsedTx.amount = amount; } if (parsedTx.txType === 'contract_call') { parsedTx.contractCall = responseTx.contract_call; - if (responseTx.contract_call?.function_name === 'transfer') { - if (responseTx.post_conditions && responseTx.post_conditions.length > 0) { - parsedTx.tokenType = responseTx.post_conditions.find((x) => x !== undefined)?.type; - parsedTx.amount = new BigNumber(responseTx.post_conditions.find((x) => x !== undefined)?.amount ?? 0); - parsedTx.tokenName = responseTx.post_conditions.find((x) => x !== undefined)?.asset.asset_name; - if (responseTx.post_conditions.find((x) => x !== undefined)?.asset_value) - parsedTx.assetId = responseTx.post_conditions.find((x) => x !== undefined)?.asset_value?.repr.substring(1); + if ( + responseTx.contract_call?.function_name === 'transfer' && + responseTx.post_conditions && + responseTx.post_conditions.length > 0 + ) { + const firstPostCondition = responseTx.post_conditions.find(Boolean); + parsedTx.tokenType = firstPostCondition?.type; + parsedTx.amount = new BigNumber(firstPostCondition?.amount ?? 0); + parsedTx.tokenName = firstPostCondition?.asset?.asset_name; + if (firstPostCondition?.asset_value) { + parsedTx.assetId = firstPostCondition.asset_value.repr?.substring(1); } } } diff --git a/tests/api/helper.test.ts b/tests/api/helper.test.ts index b71320c6..f25c0c95 100644 --- a/tests/api/helper.test.ts +++ b/tests/api/helper.test.ts @@ -1,6 +1,12 @@ import { describe, expect, it } from 'vitest'; -import { getUniquePendingTx } from 'api/helper'; -import { StxMempoolTransactionData, StxTransactionData } from 'types/*'; +import { getUniquePendingTx, parseStxTransactionData } from 'api/helper'; +import { + StxMempoolTransactionData, + StxMempoolTransactionDataResponse, + StxTransactionData, + StxTransactionDataResponse, +} from 'types/*'; +import { TransactionType } from 'types/api/shared/transaction'; describe('getUniquePendingTx', () => { [ @@ -66,3 +72,24 @@ describe('getUniquePendingTx', () => { }); }); }); + +describe('parseStxTransactionData', () => { + it('does not throw if post condition has no asset', () => { + const inputs = { + responseTx: { + tx_type: 'contract_call' as TransactionType, + contract_call: { + function_name: 'transfer', + }, + post_conditions: [ + { + type: '', + amount: 0, + }, + ], + } as unknown as StxTransactionDataResponse, + stxAddress: 'address1', + }; + expect(() => parseStxTransactionData(inputs)).not.toThrow(); + }); +}); diff --git a/types/api/shared/transaction.ts b/types/api/shared/transaction.ts index abe3e774..73de4cc0 100644 --- a/types/api/shared/transaction.ts +++ b/types/api/shared/transaction.ts @@ -6,7 +6,8 @@ export type TransactionType = | 'poison_microblock' | 'bitcoin' | 'unsupported' - | 'brc20'; + | 'brc20' + | 'message_sign'; export type TransactionStatus = | 'pending'