Created
June 30, 2025 12:50
-
-
Save anyxem/40201e31c0bfa2f2a6b5364cc9b757fa to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| function analysisTransaction({tx, addresses}) { | |
| const { | |
| inputs, | |
| outputs, | |
| } = tx; | |
| const activity = { | |
| txid: null, | |
| type: null, | |
| timestamp: null, | |
| fee: 0, | |
| amount: { | |
| inflow: { | |
| total: 0, | |
| token: { token_id: '' }, | |
| }, | |
| outflow: { | |
| total: 0, | |
| token: { token_id: '' }, | |
| } | |
| }, | |
| }; | |
| activity.txid = tx.id; | |
| activity.fee = tx.fee; | |
| activity.timestamp = tx.timestamp; | |
| // filter out unsupported transactions | |
| const unsupportedTypes = ['IssueNft', 'IssueFungibleToken', 'CreateStakePool']; | |
| const unsupportedInput = inputs.filter(input => unsupportedTypes.includes(input?.utxo?.type)); | |
| const unsupportedOutput = outputs.filter(output => unsupportedTypes.includes(output.type)); | |
| if(unsupportedInput.length > 0 || unsupportedOutput.length > 0) { | |
| activity.type = 'unsupported'; | |
| return activity; | |
| } | |
| // check for delegation widthdrawals | |
| const delegationWithdrawals = inputs.filter(input => input?.input?.account_type === 'DelegationBalance'); | |
| if(delegationWithdrawals.length > 0) { | |
| activity.type = 'delegation_withdrawal'; | |
| activity.interact = { | |
| delegation: inputs[0].input.delegation_id, | |
| }; | |
| activity.amount.inflow.total = outputs[0].value.amount.decimal; | |
| activity.amount.inflow.token = { token_id: 'Coin' }; | |
| return activity; | |
| } | |
| // check for delegation staking | |
| const delegationStaking = outputs.filter(output => output?.type === 'DelegateStaking'); | |
| if(delegationStaking.length > 0) { | |
| activity.type = 'delegation_staking'; | |
| activity.interact = { | |
| delegation: outputs[0].delegation_id, | |
| } | |
| activity.amount.outflow.total = outputs.filter(output => output?.type === 'DelegateStaking')[0].amount.decimal; | |
| activity.amount.outflow.token = { token_id: 'Coin' }; | |
| return activity; | |
| } | |
| // check for delegation creation staking | |
| const delegationCreate = outputs.filter(output => output?.type === 'CreateDelegationId'); | |
| if(delegationCreate.length > 0) { | |
| activity.type = 'delegation_create'; | |
| return activity; | |
| } | |
| // lookup for utxo = null and input.command === 'FillOrder' in inputs | |
| const myFillOrders = inputs.filter(input => | |
| !input.utxo && | |
| input.input.command === 'FillOrder' && | |
| addresses.includes(input.input.destination) | |
| ); | |
| if (myFillOrders.length > 0) { | |
| const myInputs = inputs.filter(input => input.utxo && addresses.includes(input.utxo.destination)); | |
| const myOutputs = outputs.filter(output => addresses.includes(output.destination)); | |
| if (myInputs.length > 0 && myOutputs.length > 0) { | |
| activity.type = 'swap'; | |
| // get order id | |
| const order_id = myFillOrders[0].input.order_id; | |
| activity.interact = { order_id }; | |
| const spentTokenId = myInputs.find(input => input.utxo.value.type === 'TokenV1')?.utxo.value.token_id || 'Coin'; | |
| const spentTotal = myInputs | |
| .filter(input => | |
| (input.utxo.value.token_id || 'Coin') === spentTokenId | |
| ) | |
| .reduce((acc, input) => acc + Number(input.utxo.value.amount.decimal), 0); | |
| const returnedTotal = myOutputs | |
| .filter(output => | |
| (output.value.token_id || 'Coin') === spentTokenId | |
| ) | |
| .reduce((acc, output) => acc + Number(output.value.amount.decimal), 0); | |
| const netSpent = spentTotal - returnedTotal; | |
| activity.amount.outflow = { | |
| total: netSpent, | |
| token: { token_id: spentTokenId } | |
| }; | |
| const receivedOutputs = myOutputs.filter(output => | |
| (output.value.token_id || 'Coin') !== spentTokenId | |
| ); | |
| const receivedTotal = receivedOutputs.reduce((acc, output) => | |
| acc + Number(output.value.amount.decimal), 0); | |
| const receivedTokenId = receivedOutputs.find(output => true)?.value.token_id || 'Coin'; | |
| activity.amount.inflow = { | |
| total: receivedTotal, | |
| token: { token_id: receivedTokenId } | |
| }; | |
| return activity; | |
| } | |
| } | |
| // lookup my addresses in inputs and outputs. if so, that trasanction is sending to someone else | |
| const myInputs = inputs.filter(input => input.utxo && addresses.includes(input.utxo.destination)); | |
| const myOutputs = outputs.filter(output => addresses.includes(output.destination)); | |
| const otherInputs = inputs.filter(input => input.utxo && !addresses.includes(input.utxo.destination)); | |
| const otherOutputs = outputs.filter(output => !addresses.includes(output.destination)); | |
| if(myInputs.length > 0 && myOutputs.length >= 0) { | |
| if(otherInputs.length === 0 && otherOutputs.length === 0) { | |
| activity.type = 'send_self'; | |
| let token = ''; | |
| // let's calculate the amount | |
| const inputAmount = myInputs.reduce((acc, input) => { | |
| acc += Number(input.utxo.value.amount.decimal); | |
| token = input.utxo.value.type === 'TokenV1' ? input.utxo.value.token_id : 'Coin'; | |
| return acc; | |
| }, 0); | |
| activity.amount.outflow.total = inputAmount; | |
| activity.amount.outflow.token = { token_id: token }; | |
| const outputAmount = myOutputs.reduce((acc, output) => { | |
| acc += Number(output.value.amount.decimal); | |
| token = output.value.type === 'TokenV1' ? output.value.token_id : 'Coin'; | |
| return acc; | |
| }, 0); | |
| activity.amount.inflow.total = outputAmount; | |
| activity.amount.inflow.token = { token_id: token }; | |
| return activity; | |
| } | |
| } | |
| if(myInputs.length > 0 && myOutputs.length >= 0) { | |
| activity.type = 'send'; | |
| let token = ''; | |
| // let's calculate the amount | |
| const inputAmount = myInputs.reduce((acc, input) => { | |
| acc += Number(input.utxo.value.amount.decimal); | |
| token = input.utxo.value.type === 'TokenV1' ? input.utxo.value.token_id : 'Coin'; | |
| return acc; | |
| }, 0); | |
| // let's calculate the amount send to other | |
| const outputAmount = otherOutputs.reduce((acc, output) => { | |
| acc += Number(output.value.amount.decimal); | |
| token = output.value.type === 'TokenV1' ? output.value.token_id : 'Coin'; | |
| return acc; | |
| }, 0); | |
| const outputAddresses = otherOutputs.map(output => output.destination); | |
| activity.amount.outflow.total = outputAmount; | |
| activity.amount.outflow.token = { token_id: token }; | |
| activity.interact = { addresses: outputAddresses }; | |
| return activity; | |
| } | |
| if(myInputs.length === 0 && myOutputs.length > 0) { | |
| activity.type = 'receive'; | |
| let token = ''; | |
| // let's calculate the amount | |
| const outputAmount = myOutputs.reduce((acc, output) => { | |
| acc += Number(output.value.amount.decimal); | |
| token = output.value.type === 'TokenV1' ? output.value.token_id : 'Coin'; | |
| return acc; | |
| }, 0); | |
| const inputAddresses = inputs.map(input => input.utxo.destination); | |
| activity.amount.inflow.total = outputAmount; | |
| activity.amount.inflow.token = { token_id: token }; | |
| activity.interact = { addresses: inputAddresses }; | |
| return activity; | |
| } | |
| return activity; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment