From 209fcea1e3a14313e64998a4385a356da535898a Mon Sep 17 00:00:00 2001 From: lissavxo Date: Sat, 11 Jan 2025 20:54:05 -0300 Subject: [PATCH 1/3] feat: broadcast input addresses --- services/chronikService.ts | 12 ++++++++---- services/transactionService.ts | 5 +++-- ws-service/types.ts | 1 + 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/services/chronikService.ts b/services/chronikService.ts index 95a899454..3136d5eac 100644 --- a/services/chronikService.ts +++ b/services/chronikService.ts @@ -381,10 +381,12 @@ export class ChronikBlockchainClient implements BlockchainClient { console.log(`${this.CHRONIK_MSG_PREFIX}: [${msg.msgType}] ${msg.txid}`) const transaction = await this.chronik.tx(msg.txid) const addressesWithTransactions = await this.getAddressesForTransaction(transaction) + const inputAddresses = transaction.inputs.map(inp => outputScriptToAddress(this.networkSlug, inp.outputScript)) + for (const addressWithTransaction of addressesWithTransactions) { const { created, tx } = await createTransaction(addressWithTransaction.transaction) if (tx !== undefined) { - const broadcastTxData = this.broadcastIncomingTx(addressWithTransaction.address.address, tx) + const broadcastTxData = this.broadcastIncomingTx(addressWithTransaction.address.address, tx, inputAddresses) if (created) { // only execute trigger for newly added txs await executeAddressTriggers(broadcastTxData, tx.address.networkId) } @@ -402,11 +404,11 @@ export class ChronikBlockchainClient implements BlockchainClient { } } - private broadcastIncomingTx (addressString: string, createdTx: TransactionWithAddressAndPrices): BroadcastTxData { + private broadcastIncomingTx (addressString: string, createdTx: TransactionWithAddressAndPrices, inputAddresses: Array): BroadcastTxData { const broadcastTxData: BroadcastTxData = {} as BroadcastTxData broadcastTxData.address = addressString broadcastTxData.messageType = 'NewTx' - const newSimplifiedTransaction = getSimplifiedTrasaction(createdTx) + const newSimplifiedTransaction = getSimplifiedTrasaction(createdTx, inputAddresses) broadcastTxData.txs = [newSimplifiedTransaction] try { // emit broadcast for both unconfirmed and confirmed txs this.wsEndpoint.emit(SOCKET_MESSAGES.TXS_BROADCAST, broadcastTxData) @@ -430,10 +432,12 @@ export class ChronikBlockchainClient implements BlockchainClient { } for (const transaction of blockTxsToSync) { const addressesWithTransactions = await this.getAddressesForTransaction(transaction) + const inputAddresses = transaction.inputs.map(inp => outputScriptToAddress(this.networkSlug, inp.outputScript)) + for (const addressWithTransaction of addressesWithTransactions) { const { created, tx } = await createTransaction(addressWithTransaction.transaction) if (tx !== undefined) { - const broadcastTxData = this.broadcastIncomingTx(addressWithTransaction.address.address, tx) + const broadcastTxData = this.broadcastIncomingTx(addressWithTransaction.address.address, tx, inputAddresses) if (created) { // only execute trigger for newly added txs await executeAddressTriggers(broadcastTxData, tx.address.networkId) } diff --git a/services/transactionService.ts b/services/transactionService.ts index bcb95684f..36578955d 100644 --- a/services/transactionService.ts +++ b/services/transactionService.ts @@ -44,7 +44,7 @@ export function getSimplifiedTransactions (transactionsToPersist: TransactionWit return simplifiedTransactions } -export function getSimplifiedTrasaction (tx: TransactionWithAddressAndPrices): SimplifiedTransaction { +export function getSimplifiedTrasaction (tx: TransactionWithAddressAndPrices, inputAddresses?: Array): SimplifiedTransaction { const { hash, amount, @@ -64,7 +64,8 @@ export function getSimplifiedTrasaction (tx: TransactionWithAddressAndPrices): S address: address.address, timestamp, message: parsedOpReturn?.message ?? '', - rawMessage: parsedOpReturn?.rawMessage ?? '' + rawMessage: parsedOpReturn?.rawMessage ?? '', + inputAddresses } return simplifiedTransaction diff --git a/ws-service/types.ts b/ws-service/types.ts index a33bcb1b9..a33948f88 100644 --- a/ws-service/types.ts +++ b/ws-service/types.ts @@ -17,6 +17,7 @@ export interface SimplifiedTransaction { timestamp: number address: string rawMessage: string + inputAddresses?: Array } export interface CreateQuoteAndShiftData { From 0b65a5e3663bf7d7a461b3d6e351d21d11fd43d0 Mon Sep 17 00:00:00 2001 From: lissavxo Date: Mon, 13 Jan 2025 12:26:18 -0300 Subject: [PATCH 2/3] feat: consolidate n sort inputs --- services/chronikService.ts | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/services/chronikService.ts b/services/chronikService.ts index 3136d5eac..822384c42 100644 --- a/services/chronikService.ts +++ b/services/chronikService.ts @@ -356,6 +356,24 @@ export class ChronikBlockchainClient implements BlockchainClient { } } + private getInputAddresses (transaction: Tx_InNode): string[] { + const addressValueMap = new Map() + + transaction.inputs.forEach((inp) => { + const address = outputScriptToAddress(this.networkSlug, inp.outputScript) + if (address !== undefined && address !== '') { + const currentValue = addressValueMap.get(address) ?? 0 + addressValueMap.set(address, currentValue + inp.value) + } + }) + + const sortedInputAddresses = Array.from(addressValueMap.entries()) + .sort(([, valueA], [, valueB]) => valueB - valueA) + .map(([address]) => address) + + return sortedInputAddresses + } + private async processWsMessage (msg: WsMsgClient): Promise { // delete unconfirmed transaction from our database // if they were cancelled and not confirmed @@ -381,8 +399,7 @@ export class ChronikBlockchainClient implements BlockchainClient { console.log(`${this.CHRONIK_MSG_PREFIX}: [${msg.msgType}] ${msg.txid}`) const transaction = await this.chronik.tx(msg.txid) const addressesWithTransactions = await this.getAddressesForTransaction(transaction) - const inputAddresses = transaction.inputs.map(inp => outputScriptToAddress(this.networkSlug, inp.outputScript)) - + const inputAddresses = this.getInputAddresses(transaction) for (const addressWithTransaction of addressesWithTransactions) { const { created, tx } = await createTransaction(addressWithTransaction.transaction) if (tx !== undefined) { From 9c0c7df45e2710cec3c880cb750733d09540a921 Mon Sep 17 00:00:00 2001 From: lissavxo Date: Tue, 14 Jan 2025 19:16:53 -0300 Subject: [PATCH 3/3] refactor: clean up --- services/chronikService.ts | 8 ++++---- services/transactionService.ts | 4 ++-- ws-service/types.ts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/services/chronikService.ts b/services/chronikService.ts index 822384c42..34e97ab98 100644 --- a/services/chronikService.ts +++ b/services/chronikService.ts @@ -356,7 +356,7 @@ export class ChronikBlockchainClient implements BlockchainClient { } } - private getInputAddresses (transaction: Tx_InNode): string[] { + private getSortedInputAddresses (transaction: Tx_InNode): string[] { const addressValueMap = new Map() transaction.inputs.forEach((inp) => { @@ -399,7 +399,7 @@ export class ChronikBlockchainClient implements BlockchainClient { console.log(`${this.CHRONIK_MSG_PREFIX}: [${msg.msgType}] ${msg.txid}`) const transaction = await this.chronik.tx(msg.txid) const addressesWithTransactions = await this.getAddressesForTransaction(transaction) - const inputAddresses = this.getInputAddresses(transaction) + const inputAddresses = this.getSortedInputAddresses(transaction) for (const addressWithTransaction of addressesWithTransactions) { const { created, tx } = await createTransaction(addressWithTransaction.transaction) if (tx !== undefined) { @@ -421,7 +421,7 @@ export class ChronikBlockchainClient implements BlockchainClient { } } - private broadcastIncomingTx (addressString: string, createdTx: TransactionWithAddressAndPrices, inputAddresses: Array): BroadcastTxData { + private broadcastIncomingTx (addressString: string, createdTx: TransactionWithAddressAndPrices, inputAddresses: string[]): BroadcastTxData { const broadcastTxData: BroadcastTxData = {} as BroadcastTxData broadcastTxData.address = addressString broadcastTxData.messageType = 'NewTx' @@ -449,7 +449,7 @@ export class ChronikBlockchainClient implements BlockchainClient { } for (const transaction of blockTxsToSync) { const addressesWithTransactions = await this.getAddressesForTransaction(transaction) - const inputAddresses = transaction.inputs.map(inp => outputScriptToAddress(this.networkSlug, inp.outputScript)) + const inputAddresses = this.getSortedInputAddresses(transaction) for (const addressWithTransaction of addressesWithTransactions) { const { created, tx } = await createTransaction(addressWithTransaction.transaction) diff --git a/services/transactionService.ts b/services/transactionService.ts index 36578955d..9d2b014aa 100644 --- a/services/transactionService.ts +++ b/services/transactionService.ts @@ -44,7 +44,7 @@ export function getSimplifiedTransactions (transactionsToPersist: TransactionWit return simplifiedTransactions } -export function getSimplifiedTrasaction (tx: TransactionWithAddressAndPrices, inputAddresses?: Array): SimplifiedTransaction { +export function getSimplifiedTrasaction (tx: TransactionWithAddressAndPrices, inputAddresses?: string[]): SimplifiedTransaction { const { hash, amount, @@ -65,7 +65,7 @@ export function getSimplifiedTrasaction (tx: TransactionWithAddressAndPrices, in timestamp, message: parsedOpReturn?.message ?? '', rawMessage: parsedOpReturn?.rawMessage ?? '', - inputAddresses + inputAddresses: inputAddresses ?? [] } return simplifiedTransaction diff --git a/ws-service/types.ts b/ws-service/types.ts index a33948f88..827fe5866 100644 --- a/ws-service/types.ts +++ b/ws-service/types.ts @@ -17,7 +17,7 @@ export interface SimplifiedTransaction { timestamp: number address: string rawMessage: string - inputAddresses?: Array + inputAddresses: string[] } export interface CreateQuoteAndShiftData {