From b158d7d2521872ac79a926b178f5e63eb11ad7b2 Mon Sep 17 00:00:00 2001 From: TaprootFreak <142087526+TaprootFreak@users.noreply.github.com> Date: Tue, 3 Mar 2026 09:51:58 +0100 Subject: [PATCH 1/5] Improve transaction matching algorithm to prevent suboptimal pairs Problem: The previous greedy matching algorithm could create suboptimal pairs, leading to unmatched transactions that should have been matched based on exact references or temporal proximity. Example case: - bank_tx 191175 (E2E-79792) created 07:31 - exchange_tx 125970 (DEPOSIT-79792) created 07:33 - These belong together (same reference, 2 min apart) - But exchange_tx 125970 was matched with bank_tx 190594 (5 days apart) - Result: 40k CHF stuck as "pending to Scrypt" for 34+ hours Solution: Implement two-phase optimal matching: Phase 1: Exact Reference Matching - Match bank_tx.endToEndId with exchange_tx.txId - Ensures transactions with matching references are paired first - Prevents false matches based purely on timing Phase 2: Optimal Timing-based Matching - Build cost matrix based on temporal proximity - Use greedy algorithm on sorted pairs (best matches first) - Ensures closest temporal matches are selected Changes: - Add matchByExactReference() method for Phase 1 - Add buildCostMatrix() and findOptimalMatches() for Phase 2 - Replace greedy iteration in filterSenderPendingList() with two-phase approach - Add comprehensive test cases for both phases - Add verbose logging for match tracking and debugging Benefits: - Prevents suboptimal matches that cause false "pending" balances - Prioritizes exact reference matches over approximations - Reduces manual intervention needed for stuck transactions - Improves overall matching accuracy and reliability --- .../log/__tests__/log-job.service.spec.ts | 153 ++++++++++++ .../supporting/log/log-job.service.ts | 217 ++++++++++++++++-- 2 files changed, 346 insertions(+), 24 deletions(-) diff --git a/src/subdomains/supporting/log/__tests__/log-job.service.spec.ts b/src/subdomains/supporting/log/__tests__/log-job.service.spec.ts index 4023e4a9ee..0061973e4c 100644 --- a/src/subdomains/supporting/log/__tests__/log-job.service.spec.ts +++ b/src/subdomains/supporting/log/__tests__/log-job.service.spec.ts @@ -465,4 +465,157 @@ describe('LogJobService', () => { receiver: receiverTx.slice(7), }); }); + + describe('Optimal Transaction Matching', () => { + it('should match transactions by exact reference (endToEndId ↔ txId) first', () => { + const now = new Date(); + + // Bank transaction with exact reference + const senderWithRef = createCustomBankTx({ + id: 191175, + created: new Date(now.getTime() - 2 * 60 * 1000), // 2 minutes ago + valueDate: new Date(now.getTime() - 2 * 60 * 1000), + instructedAmount: 40000, + amount: 40000, + endToEndId: 'E2E-79792', + }); + + // Bank transaction without matching reference + const senderWithoutRef = createCustomBankTx({ + id: 190594, + created: new Date(now.getTime() - 5 * 24 * 60 * 60 * 1000), // 5 days ago + valueDate: new Date(now.getTime() - 5 * 24 * 60 * 60 * 1000), + instructedAmount: 40000, + amount: 40000, + }); + + // Exchange transaction with matching reference + const receiverWithRef = createCustomExchangeTx({ + id: 125970, + created: now, + amount: 40000, + txId: 'DEPOSIT-79792', + }); + + const senderTx = [senderWithoutRef, senderWithRef]; // Older sender first + const receiverTx = [receiverWithRef]; + + const result = service.filterSenderPendingList(senderTx, receiverTx); + + // senderWithRef should be matched due to exact reference + // senderWithoutRef should remain unmatched + expect(result.sender).toHaveLength(1); + expect(result.sender[0].id).toBe(190594); + expect(result.receiver).toHaveLength(0); + }); + + it('should prefer temporally closer matches when no exact reference exists', () => { + const baseTime = new Date('2026-03-02T10:00:00Z'); + + // Two senders with different temporal distances to receiver + const senderFarAway = createCustomBankTx({ + id: 190001, + created: new Date(baseTime.getTime() - 5 * 24 * 60 * 60 * 1000), // 5 days before + valueDate: new Date(baseTime.getTime() - 5 * 24 * 60 * 60 * 1000), + instructedAmount: 40000, + amount: 40000, + }); + + const senderClose = createCustomBankTx({ + id: 191001, + created: new Date(baseTime.getTime() - 10 * 60 * 1000), // 10 minutes before + valueDate: new Date(baseTime.getTime() - 10 * 60 * 1000), + instructedAmount: 40000, + amount: 40000, + }); + + // One receiver + const receiver1 = createCustomExchangeTx({ + id: 125001, + created: baseTime, + amount: 40000, + }); + + const senderTx = [senderFarAway, senderClose]; + const receiverTx = [receiver1]; + + const result = service.filterSenderPendingList(senderTx, receiverTx); + + // senderClose should be matched (temporally closer) + // senderFarAway should remain unmatched + expect(result.sender).toHaveLength(1); + expect(result.sender[0].id).toBe(190001); // Far away sender is unmatched + expect(result.receiver).toHaveLength(0); + }); + + it('should handle multiple matches optimally', () => { + const baseTime = new Date('2026-03-02T10:00:00Z'); + + const sender1 = createCustomBankTx({ + id: 191001, + created: new Date(baseTime.getTime() - 30 * 60 * 1000), // 30 min before + valueDate: new Date(baseTime.getTime() - 30 * 60 * 1000), + instructedAmount: 40000, + amount: 40000, + }); + + const sender2 = createCustomBankTx({ + id: 191002, + created: new Date(baseTime.getTime() - 20 * 60 * 1000), // 20 min before + valueDate: new Date(baseTime.getTime() - 20 * 60 * 1000), + instructedAmount: 40000, + amount: 40000, + }); + + const receiver1 = createCustomExchangeTx({ + id: 125001, + created: new Date(baseTime.getTime() - 25 * 60 * 1000), // 25 min before (closer to sender1) + amount: 40000, + }); + + const receiver2 = createCustomExchangeTx({ + id: 125002, + created: baseTime, // Now (closer to sender2) + amount: 40000, + }); + + const senderTx = [sender1, sender2]; + const receiverTx = [receiver1, receiver2]; + + const result = service.filterSenderPendingList(senderTx, receiverTx); + + // Both should be matched optimally + expect(result.sender).toHaveLength(0); + expect(result.receiver).toHaveLength(0); + }); + + it('should handle transactions outside 5-day tolerance correctly', () => { + const baseTime = new Date('2026-03-02T10:00:00Z'); + + // Sender outside 5-day tolerance + const senderTooOld = createCustomBankTx({ + id: 190001, + created: new Date(baseTime.getTime() - 6 * 24 * 60 * 60 * 1000), // 6 days before + valueDate: new Date(baseTime.getTime() - 6 * 24 * 60 * 60 * 1000), + instructedAmount: 40000, + amount: 40000, + }); + + const receiver = createCustomExchangeTx({ + id: 125001, + created: baseTime, + amount: 40000, + }); + + const senderTx = [senderTooOld]; + const receiverTx = [receiver]; + + const result = service.filterSenderPendingList(senderTx, receiverTx); + + // Should not match (outside tolerance) + expect(result.sender).toHaveLength(1); + expect(result.sender[0].id).toBe(190001); + expect(result.receiver).toHaveLength(1); + }); + }); }); diff --git a/src/subdomains/supporting/log/log-job.service.ts b/src/subdomains/supporting/log/log-job.service.ts index 0ff2287301..eecf58afd1 100644 --- a/src/subdomains/supporting/log/log-job.service.ts +++ b/src/subdomains/supporting/log/log-job.service.ts @@ -1072,54 +1072,223 @@ export class LogJobService { ); } + /** + * Phase 1: Match transactions by exact reference (endToEndId ↔ txId) + * This ensures that transactions with matching references are paired first, + * preventing suboptimal matches based purely on timing. + */ + private matchByExactReference( + senders: BankTx[], + receivers: ExchangeTx[], + ): { + matched: Array<{ sender: BankTx; receiver: ExchangeTx }>; + unmatchedSenders: BankTx[]; + unmatchedReceivers: ExchangeTx[]; + } { + const matched: Array<{ sender: BankTx; receiver: ExchangeTx }> = []; + const unmatchedSenders = [...senders]; + const unmatchedReceivers = [...receivers]; + + // Match based on references (endToEndId ↔ txId) + for (const sender of senders) { + if (!sender.endToEndId) continue; + + // Extract reference number from "E2E-79792" → "79792" + const refNumber = sender.endToEndId.replace(/^E2E-/, ''); + + const receiverIndex = unmatchedReceivers.findIndex( + (r) => r.txId === `DEPOSIT-${refNumber}` || r.txId === refNumber, + ); + + if (receiverIndex !== -1) { + const receiver = unmatchedReceivers[receiverIndex]; + + matched.push({ sender, receiver }); + + // Remove from unmatched lists + const senderIdx = unmatchedSenders.findIndex((s) => s.id === sender.id); + if (senderIdx !== -1) unmatchedSenders.splice(senderIdx, 1); + unmatchedReceivers.splice(receiverIndex, 1); + } + } + + return { matched, unmatchedSenders, unmatchedReceivers }; + } + + /** + * Build cost matrix for optimal matching based on temporal proximity + */ + private buildCostMatrix(senders: (BankTx | ExchangeTx)[], receivers: (BankTx | ExchangeTx)[]): number[][] { + const matrix: number[][] = []; + + for (let i = 0; i < senders.length; i++) { + matrix[i] = []; + + for (let j = 0; j < receivers.length; j++) { + const sender = senders[i]; + const receiver = receivers[j]; + + // Check basic matching criteria + const senderAmount = sender instanceof BankTx ? sender.instructedAmount : sender.amount; + const receiverAmount = receiver instanceof BankTx ? receiver.instructedAmount : receiver.amount; + const amountMatch = senderAmount === receiverAmount; + const createdAfter = receiver.created > sender.created; + + if (!amountMatch || !createdAfter) { + matrix[i][j] = Infinity; // Impossible match + continue; + } + + // For BankTx, check day difference from valueDate + if (sender instanceof BankTx) { + const daysDiff = Math.abs(Util.daysDiff(sender.valueDate, receiver.created)); + if (daysDiff > 5) { + matrix[i][j] = Infinity; + continue; + } + } + + // Calculate cost based on temporal proximity (lower is better) + // Use minute difference as cost + const minutesDiff = Math.abs(receiver.created.getTime() - sender.created.getTime()) / (1000 * 60); + + matrix[i][j] = minutesDiff; + } + } + + return matrix; + } + + /** + * Phase 2: Find optimal matches based on cost matrix (temporal proximity) + * Uses greedy algorithm on sorted pairs to ensure best matches are selected first + */ + private findOptimalMatches( + costMatrix: number[][], + senders: (BankTx | ExchangeTx)[], + receivers: (BankTx | ExchangeTx)[], + ): { + matched: Array<{ sender: BankTx | ExchangeTx; receiver: BankTx | ExchangeTx }>; + unmatchedSenders: (BankTx | ExchangeTx)[]; + unmatchedReceivers: (BankTx | ExchangeTx)[]; + } { + const matched: Array<{ sender: BankTx | ExchangeTx; receiver: BankTx | ExchangeTx }> = []; + + // Create list of all possible pairs with their costs + const possiblePairs: Array<{ + senderIndex: number; + receiverIndex: number; + cost: number; + sender: BankTx | ExchangeTx; + receiver: BankTx | ExchangeTx; + }> = []; + + for (let i = 0; i < senders.length; i++) { + for (let j = 0; j < receivers.length; j++) { + if (costMatrix[i][j] !== Infinity) { + possiblePairs.push({ + senderIndex: i, + receiverIndex: j, + cost: costMatrix[i][j], + sender: senders[i], + receiver: receivers[j], + }); + } + } + } + + // Sort by cost (best matches first) + possiblePairs.sort((a, b) => a.cost - b.cost); + + // Greedy matching on sorted list + const usedSenders = new Set(); + const usedReceivers = new Set(); + + for (const pair of possiblePairs) { + if (!usedSenders.has(pair.senderIndex) && !usedReceivers.has(pair.receiverIndex)) { + matched.push({ + sender: pair.sender, + receiver: pair.receiver, + }); + + usedSenders.add(pair.senderIndex); + usedReceivers.add(pair.receiverIndex); + } + } + + // Determine unmatched + const unmatchedSenders = senders.filter((_, i) => !usedSenders.has(i)); + const unmatchedReceivers = receivers.filter((_, i) => !usedReceivers.has(i)); + + return { matched, unmatchedSenders, unmatchedReceivers }; + } + public filterSenderPendingList( senderTx: (BankTx | ExchangeTx)[], receiverTx: (BankTx | ExchangeTx)[] | undefined, ): { receiver: (BankTx | ExchangeTx)[]; sender: (BankTx | ExchangeTx)[] } { const before21Days = Util.daysBefore(21); - let filtered21SenderTx = senderTx.filter((s) => s.created > before21Days); - let filtered21ReceiverTx = receiverTx.filter((r) => r.created > before21Days); + const filtered21SenderTx = senderTx.filter((s) => s.created > before21Days); + const filtered21ReceiverTx = receiverTx?.filter((r) => r.created > before21Days) || []; if (!filtered21SenderTx.length) return { receiver: [], sender: [] }; - if (!filtered21ReceiverTx?.length) { + if (!filtered21ReceiverTx.length) { return { sender: filtered21SenderTx, receiver: [], }; } - const { senderPair, receiverIndex } = this.findSenderReceiverPair(filtered21SenderTx, filtered21ReceiverTx); + let unmatchedSenders = filtered21SenderTx; + let unmatchedReceivers = filtered21ReceiverTx; - if (filtered21SenderTx[0] instanceof BankTx) { - this.logger.verbose( - `FinanceLog receiverTxId/date: ${filtered21ReceiverTx?.[receiverIndex]?.id}/${filtered21ReceiverTx?.[ - receiverIndex - ]?.created.toDateString()}; senderTx[0] id/date: ${ - filtered21SenderTx[0]?.id - }/${filtered21SenderTx[0].valueDate.toDateString()}; senderPair id/date: ${senderPair?.id}/${ - senderPair && senderPair instanceof BankTx - ? senderPair.valueDate.toDateString() - : senderPair?.created.toDateString() - }; senderTx length: ${filtered21SenderTx.length}`, + // Phase 1: Exact Reference Matching (only for BankTx → ExchangeTx) + if (filtered21SenderTx[0] instanceof BankTx && filtered21ReceiverTx[0] instanceof ExchangeTx) { + const phase1Result = this.matchByExactReference( + unmatchedSenders as BankTx[], + unmatchedReceivers as ExchangeTx[], ); + + if (phase1Result.matched.length > 0) { + this.logger.verbose( + `FinanceLog Phase 1 (Exact Reference): ${phase1Result.matched.length} matches found. ` + + `Matched pairs: ${phase1Result.matched.map((m) => `${m.sender.id}↔${m.receiver.id}`).join(', ')}`, + ); + } + + unmatchedSenders = phase1Result.unmatchedSenders; + unmatchedReceivers = phase1Result.unmatchedReceivers; } - filtered21SenderTx = senderPair ? filtered21SenderTx.filter((s) => s.id >= senderPair.id) : filtered21SenderTx; + // Phase 2: Optimal Timing-based Matching + if (unmatchedSenders.length > 0 && unmatchedReceivers.length > 0) { + const costMatrix = this.buildCostMatrix(unmatchedSenders, unmatchedReceivers); + const phase2Result = this.findOptimalMatches(costMatrix, unmatchedSenders, unmatchedReceivers); - if (filtered21ReceiverTx.length > filtered21SenderTx.length) { - const { senderPair } = this.findSenderReceiverPair(filtered21SenderTx, filtered21ReceiverTx, true); + if (phase2Result.matched.length > 0) { + this.logger.verbose( + `FinanceLog Phase 2 (Optimal Timing): ${phase2Result.matched.length} matches found. ` + + `Matched pairs: ${phase2Result.matched.map((m) => `${m.sender.id}↔${m.receiver.id}`).join(', ')}`, + ); + } - const senderTxLength = senderPair - ? filtered21SenderTx.filter((s) => s.id <= senderPair.id).length - : filtered21ReceiverTx.length; + unmatchedSenders = phase2Result.unmatchedSenders; + unmatchedReceivers = phase2Result.unmatchedReceivers; + } - filtered21ReceiverTx = filtered21ReceiverTx.slice(filtered21ReceiverTx.length - senderTxLength); + // Log unmatched transactions + if (unmatchedSenders.length > 0) { + this.logger.verbose( + `FinanceLog Unmatched Senders: ${unmatchedSenders.length} remaining. ` + + `IDs: ${unmatchedSenders.map((s) => s.id).join(', ')}`, + ); } + // Return unmatched as "pending" return { - receiver: filtered21ReceiverTx.filter((r) => r.id >= (filtered21ReceiverTx[receiverIndex]?.id ?? 0)), - sender: filtered21SenderTx.sort((a, b) => a.id - b.id), + receiver: unmatchedReceivers, + sender: unmatchedSenders.sort((a, b) => a.id - b.id), }; } From dd84ae76bfea87be9e7777184192e3674bdc5088 Mon Sep 17 00:00:00 2001 From: TaprootFreak <142087526+TaprootFreak@users.noreply.github.com> Date: Tue, 3 Mar 2026 11:36:37 +0100 Subject: [PATCH 2/5] Fix: Format log-job.service.ts with Prettier --- src/subdomains/supporting/log/log-job.service.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/subdomains/supporting/log/log-job.service.ts b/src/subdomains/supporting/log/log-job.service.ts index eecf58afd1..0e3aa2fd75 100644 --- a/src/subdomains/supporting/log/log-job.service.ts +++ b/src/subdomains/supporting/log/log-job.service.ts @@ -1245,10 +1245,7 @@ export class LogJobService { // Phase 1: Exact Reference Matching (only for BankTx → ExchangeTx) if (filtered21SenderTx[0] instanceof BankTx && filtered21ReceiverTx[0] instanceof ExchangeTx) { - const phase1Result = this.matchByExactReference( - unmatchedSenders as BankTx[], - unmatchedReceivers as ExchangeTx[], - ); + const phase1Result = this.matchByExactReference(unmatchedSenders as BankTx[], unmatchedReceivers as ExchangeTx[]); if (phase1Result.matched.length > 0) { this.logger.verbose( From 84c029c85a371b47893b874b2a3341d48537ad45 Mon Sep 17 00:00:00 2001 From: TaprootFreak <142087526+TaprootFreak@users.noreply.github.com> Date: Tue, 3 Mar 2026 11:42:16 +0100 Subject: [PATCH 3/5] Fix: Update test expectations for optimal transaction matching The new optimal matching algorithm (Phase 1: Exact Reference + Phase 2: Optimal Timing) matches more transactions successfully than the old greedy approach. Tests now expect: - Fewer unmatched transactions - Better pairing based on timing and exact references - All 13 tests passing --- .../log/__tests__/log-job.service.spec.ts | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/src/subdomains/supporting/log/__tests__/log-job.service.spec.ts b/src/subdomains/supporting/log/__tests__/log-job.service.spec.ts index 0061973e4c..2a39e55a23 100644 --- a/src/subdomains/supporting/log/__tests__/log-job.service.spec.ts +++ b/src/subdomains/supporting/log/__tests__/log-job.service.spec.ts @@ -205,9 +205,10 @@ describe('LogJobService', () => { }), ]; + // With optimal matching: 3 senders (312h old) match 3 receivers (310h old), 1 sender (309h) remains expect(service.filterSenderPendingList(senderTx, receiverTx)).toMatchObject({ - sender: senderTx.slice(7), - receiver: receiverTx.slice(7), + sender: [senderTx[10]], // Only 142409 remains unmatched + receiver: [], }); }); @@ -228,9 +229,10 @@ describe('LogJobService', () => { }), ]; + // With optimal matching: sender (27h) and receiver (26h) match perfectly (same amount, receiver after sender, < 5d) expect(service.filterSenderPendingList(senderTx, receiverTx)).toMatchObject({ - sender: senderTx, - receiver: receiverTx, + sender: [], + receiver: [], }); }); @@ -265,9 +267,13 @@ describe('LogJobService', () => { }), ]; + // With optimal matching: all 3 senders match all 3 receivers optimally + // sender[0] (8d) ↔ receiver[0] (6d): 2d apart + // sender[1] (8d) ↔ receiver[1] (5d): 3d apart + // sender[2] (7d) ↔ receiver[2] (5d): 2d apart expect(service.filterSenderPendingList(senderTx, receiverTx)).toMatchObject({ - sender: [senderTx[2]], - receiver: [receiverTx[2]], + sender: [], + receiver: [], }); }); @@ -302,9 +308,11 @@ describe('LogJobService', () => { }), ]; + // With optimal matching: sender[1] (17d) matches receiver[1] (16d), sender[2] (7d) matches receiver[2] (6d) + // First pair filtered by 21d rule expect(service.filterSenderPendingList(senderTx, receiverTx)).toMatchObject({ - sender: senderTx.slice(1), - receiver: receiverTx.slice(1), + sender: [], + receiver: [], }); }); @@ -331,9 +339,13 @@ describe('LogJobService', () => { }), ]; + // With optimal matching: + // sender[0] filtered out (>= 21d) + // sender[1] (17d, 19999.0) matches receiver[1] (16d, 19999.0) + // receiver[0] stays unmatched (amount mismatch: 47543.81 vs 47520.04) expect(service.filterSenderPendingList(senderTx, receiverTx)).toMatchObject({ - sender: [senderTx[1]], - receiver: [receiverTx[1]], + sender: [], + receiver: [receiverTx[0]], }); }); @@ -362,11 +374,13 @@ describe('LogJobService', () => { }), ]; - // Matching finds sender id=3 (oldest sender that's still older than receiver at 18d) - // Filter keeps only senders with id >= 3 + // With optimal matching: + // receiver[0] filtered out (>= 21d) + // receiver[1] (18d) matches sender[1] (19d, temporally closest: 1d apart) + // sender[0] and sender[2] remain unmatched (sorted by id: [1, 3]) expect(service.filterSenderPendingList(senderTx, receiverTx)).toMatchObject({ - sender: [senderTx[0]], // Only id=3 remains after matching - receiver: [receiverTx[1]], + sender: [senderTx[2], senderTx[0]], // id=1 and id=3 remain unmatched, sorted by id + receiver: [], }); }); @@ -460,9 +474,10 @@ describe('LogJobService', () => { }), ]; + // With optimal matching: 3 senders (312h old) match 3 receivers (310h old) expect(service.filterSenderPendingList(senderTx, receiverTx)).toMatchObject({ - sender: senderTx.slice(7), - receiver: receiverTx.slice(7), + sender: [], + receiver: [], }); }); From 509b1e81ed188458e1c8c2fff2a3624a7a2ed7da Mon Sep 17 00:00:00 2001 From: TaprootFreak <142087526+TaprootFreak@users.noreply.github.com> Date: Tue, 3 Mar 2026 14:55:32 +0100 Subject: [PATCH 4/5] Add explicit ICP dependencies to package.json Add missing @dfinity dependencies that were previously only transitive dependencies: - @dfinity/agent@^3.4.3 - @dfinity/principal@^3.4.3 - @dfinity/candid@^3.4.3 These are required by ICP blockchain integration files and should be explicitly listed since they are directly imported. --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index d9f767b379..58d42b526c 100644 --- a/package.json +++ b/package.json @@ -32,9 +32,12 @@ "@buildonspark/spark-sdk": "^0.3.5", "@cardano-foundation/cardano-verify-datasignature": "^1.0.11", "@deuro/eurocoin": "^1.0.16", + "@dfinity/agent": "^3.4.3", + "@dfinity/candid": "^3.4.3", "@dfinity/identity": "^3.4.3", "@dfinity/ledger-icp": "^9.1.0", "@dfinity/ledger-icrc": "^7.1.0", + "@dfinity/principal": "^3.4.3", "@dhedge/v2-sdk": "^1.11.1", "@emurgo/cardano-serialization-lib-nodejs": "^15.0.3", "@eth-optimism/sdk": "^3.3.3", From 3b232f97521ea4ebf2df2827739126ca2716bd40 Mon Sep 17 00:00:00 2001 From: TaprootFreak <142087526+TaprootFreak@users.noreply.github.com> Date: Thu, 5 Mar 2026 04:09:45 +0100 Subject: [PATCH 5/5] Remove unrelated @dfinity dependencies Remove @dfinity/agent, @dfinity/candid, and @dfinity/principal that were accidentally added as they are not needed by this PR. --- package.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/package.json b/package.json index 58d42b526c..d9f767b379 100644 --- a/package.json +++ b/package.json @@ -32,12 +32,9 @@ "@buildonspark/spark-sdk": "^0.3.5", "@cardano-foundation/cardano-verify-datasignature": "^1.0.11", "@deuro/eurocoin": "^1.0.16", - "@dfinity/agent": "^3.4.3", - "@dfinity/candid": "^3.4.3", "@dfinity/identity": "^3.4.3", "@dfinity/ledger-icp": "^9.1.0", "@dfinity/ledger-icrc": "^7.1.0", - "@dfinity/principal": "^3.4.3", "@dhedge/v2-sdk": "^1.11.1", "@emurgo/cardano-serialization-lib-nodejs": "^15.0.3", "@eth-optimism/sdk": "^3.3.3",