@openscan/algorithms 0.0.1-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Openscan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,8 @@
1
+ import type { Algorithm, AlgorithmResult, GasPriceParams, GasPricePage } from "../shared/types.js";
2
+ export declare class GasPriceHistoryAlgorithm implements Algorithm<GasPriceParams, GasPricePage> {
3
+ readonly name = "gas-price-history";
4
+ readonly description = "Retrieve gas price history using exponential block sampling";
5
+ readonly supportedChains: number[];
6
+ execute(params: GasPriceParams): Promise<AlgorithmResult<GasPricePage>>;
7
+ }
8
+ //# sourceMappingURL=GasPriceHistoryAlgorithm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GasPriceHistoryAlgorithm.d.ts","sourceRoot":"","sources":["../../src/gas-price/GasPriceHistoryAlgorithm.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EACf,cAAc,EACd,YAAY,EAEb,MAAM,oBAAoB,CAAC;AAa5B,qBAAa,wBAAyB,YAAW,SAAS,CAAC,cAAc,EAAE,YAAY,CAAC;IACtF,QAAQ,CAAC,IAAI,uBAAuB;IACpC,QAAQ,CAAC,WAAW,iEAAiE;IACrF,QAAQ,CAAC,eAAe,WAAoB;IAEtC,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;CAmG9E"}
@@ -0,0 +1,97 @@
1
+ import { hexToNumber, weiToGwei } from "@openscan/utils";
2
+ const SUPPORTED_CHAINS = [1, 10, 56, 137, 8453, 42161, 43114, 31337, 11155111];
3
+ const DEFAULT_TARGET_DISTANCE = 1000;
4
+ export class GasPriceHistoryAlgorithm {
5
+ name = "gas-price-history";
6
+ description = "Retrieve gas price history using exponential block sampling";
7
+ supportedChains = SUPPORTED_CHAINS;
8
+ async execute(params) {
9
+ const startTime = Date.now();
10
+ let rpcCalls = 0;
11
+ // Dynamic import to keep network-connectors as peer dep
12
+ const nc = await import("@openscan/network-connectors");
13
+ const config = {
14
+ type: (params.strategyType ?? "fallback"),
15
+ rpcUrls: params.rpcUrls,
16
+ };
17
+ const client = nc.ClientFactory.createClient(params.chainId, config);
18
+ try {
19
+ // 1. Get current block number
20
+ const blockNumResult = await client.execute("eth_blockNumber", []);
21
+ rpcCalls++;
22
+ if (!blockNumResult.success || !blockNumResult.data) {
23
+ return {
24
+ success: false,
25
+ error: {
26
+ code: "RPC_ERROR",
27
+ message: blockNumResult.errors?.[0]?.error ?? "eth_blockNumber failed",
28
+ },
29
+ };
30
+ }
31
+ const currentBlock = Number(hexToNumber(blockNumResult.data));
32
+ // 2. Resolve target block
33
+ let targetBlock;
34
+ if (params.targetBlock != null) {
35
+ targetBlock =
36
+ typeof params.targetBlock === "string"
37
+ ? Number(hexToNumber(params.targetBlock))
38
+ : params.targetBlock;
39
+ }
40
+ else {
41
+ targetBlock = Math.max(0, currentBlock - DEFAULT_TARGET_DISTANCE);
42
+ }
43
+ // 3. Generate exponential sample points
44
+ const sampleBlocks = [];
45
+ let offset = 1;
46
+ while (currentBlock - offset >= targetBlock) {
47
+ sampleBlocks.push(currentBlock - offset);
48
+ offset *= 2;
49
+ }
50
+ // Always include the target block itself
51
+ if (sampleBlocks.length === 0 || sampleBlocks[sampleBlocks.length - 1] !== targetBlock) {
52
+ sampleBlocks.push(targetBlock);
53
+ }
54
+ // 4. Fetch block headers for each sample point
55
+ const entries = [];
56
+ for (const blockNum of sampleBlocks) {
57
+ const blockResult = await client.execute("eth_getBlockByNumber", [
58
+ `0x${blockNum.toString(16)}`,
59
+ false,
60
+ ]);
61
+ rpcCalls++;
62
+ if (!blockResult.success || !blockResult.data) {
63
+ continue;
64
+ }
65
+ const block = blockResult.data;
66
+ const gasUsed = Number(hexToNumber(block.gasUsed));
67
+ const gasLimit = Number(hexToNumber(block.gasLimit));
68
+ const gasUsedRatio = gasLimit > 0 ? gasUsed / gasLimit : 0;
69
+ const baseFee = block.baseFeePerGas ?? "0x0";
70
+ entries.push({
71
+ blockNumber: blockNum,
72
+ timestamp: Number(hexToNumber(block.timestamp)),
73
+ baseFee,
74
+ avgGasPrice: weiToGwei(baseFee),
75
+ minGasPrice: weiToGwei(baseFee),
76
+ maxGasPrice: weiToGwei(baseFee),
77
+ gasUsedRatio,
78
+ });
79
+ }
80
+ return {
81
+ success: true,
82
+ data: { entries, chainId: params.chainId },
83
+ metadata: {
84
+ chainId: params.chainId,
85
+ duration: Date.now() - startTime,
86
+ rpcCalls,
87
+ archivalRequired: false,
88
+ timestamp: Date.now(),
89
+ },
90
+ };
91
+ }
92
+ finally {
93
+ await client.close();
94
+ }
95
+ }
96
+ }
97
+ //# sourceMappingURL=GasPriceHistoryAlgorithm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GasPriceHistoryAlgorithm.js","sourceRoot":"","sources":["../../src/gas-price/GasPriceHistoryAlgorithm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { GasPriceHistoryAlgorithm } from "./gas-price/GasPriceHistoryAlgorithm.js";
2
+ export { TransactionHistoryAlgorithm } from "./tx-history/TransactionHistoryAlgorithm.js";
3
+ export { TokenBalanceHistoryAlgorithm } from "./token-balance/TokenBalanceHistoryAlgorithm.js";
4
+ export type { Algorithm, AlgorithmParams, AlgorithmResult, PaginationParams, TxHistoryParams, TxHistoryEntry, TxHistoryPage, TxSearchProgress, TxSearchProgressCallback, TxSearchTransactionFoundCallback, TxSearchOptions, TxSearchResult, TokenBalanceParams, TokenBalanceEntry, TokenBalancePage, GasPriceParams, GasPriceEntry, GasPricePage, } from "./shared/types.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AACnF,OAAO,EAAE,2BAA2B,EAAE,MAAM,6CAA6C,CAAC;AAC1F,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC;AAG/F,YAAY,EACV,SAAS,EACT,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,wBAAwB,EACxB,gCAAgC,EAChC,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,YAAY,GACb,MAAM,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ // Algorithms
2
+ export { GasPriceHistoryAlgorithm } from "./gas-price/GasPriceHistoryAlgorithm.js";
3
+ export { TransactionHistoryAlgorithm } from "./tx-history/TransactionHistoryAlgorithm.js";
4
+ export { TokenBalanceHistoryAlgorithm } from "./token-balance/TokenBalanceHistoryAlgorithm.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,aAAa;AACb,OAAO,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AACnF,OAAO,EAAE,2BAA2B,EAAE,MAAM,6CAA6C,CAAC;AAC1F,OAAO,EAAE,4BAA4B,EAAE,MAAM,iDAAiD,CAAC"}
@@ -0,0 +1,123 @@
1
+ import type { OpResult, OpError, OpMetadata } from "@openscan/utils";
2
+ export type { OpResult, OpError, OpMetadata };
3
+ export interface AlgorithmParams {
4
+ chainId: number | string;
5
+ rpcUrls: string[];
6
+ strategyType?: "fallback" | "parallel" | "race";
7
+ }
8
+ export interface PaginationParams {
9
+ fromBlock?: number | string;
10
+ toBlock?: number | string;
11
+ pageSize?: number;
12
+ cursor?: string;
13
+ }
14
+ export interface AlgorithmResult<T> extends OpResult<T> {
15
+ pagination?: {
16
+ hasMore: boolean;
17
+ nextCursor?: string;
18
+ totalBlocks?: number;
19
+ };
20
+ }
21
+ /** Algorithm interface contract */
22
+ export interface Algorithm<TParams, TResult> {
23
+ readonly name: string;
24
+ readonly description: string;
25
+ readonly supportedChains: (number | string)[];
26
+ execute(params: TParams): Promise<AlgorithmResult<TResult>>;
27
+ }
28
+ /** Transaction History */
29
+ export interface TxHistoryParams extends AlgorithmParams {
30
+ address: string;
31
+ pagination?: PaginationParams;
32
+ }
33
+ export interface TxHistoryEntry {
34
+ hash: string;
35
+ blockNumber: number;
36
+ timestamp: number;
37
+ from: string;
38
+ to: string | null;
39
+ value: string;
40
+ gasUsed: string;
41
+ gasPrice: string;
42
+ status: "success" | "failure";
43
+ type: "sent" | "received" | "internal";
44
+ methodId?: string;
45
+ decodedMethod?: string;
46
+ }
47
+ export interface TxHistoryPage {
48
+ entries: TxHistoryEntry[];
49
+ address: string;
50
+ chainId: number | string;
51
+ }
52
+ export interface TxSearchProgress {
53
+ phase: "searching" | "fetching";
54
+ current: number;
55
+ total: number;
56
+ message?: string;
57
+ blockRange?: {
58
+ from: number;
59
+ to: number;
60
+ };
61
+ }
62
+ export type TxSearchProgressCallback = (progress: TxSearchProgress) => void;
63
+ export type TxSearchTransactionFoundCallback = (entries: TxHistoryEntry[]) => void;
64
+ export interface TxSearchOptions {
65
+ limit?: number;
66
+ fromBlock?: number;
67
+ toBlock?: number;
68
+ onProgress?: TxSearchProgressCallback;
69
+ onTransactionsFound?: TxSearchTransactionFoundCallback;
70
+ signal?: AbortSignal;
71
+ }
72
+ export interface TxSearchResult {
73
+ blocks: number[];
74
+ entries: TxHistoryEntry[];
75
+ stats: {
76
+ totalBlocks: number;
77
+ totalTxs: number;
78
+ sentCount: number;
79
+ receivedCount: number;
80
+ internalCount: number;
81
+ rpcCalls: number;
82
+ elapsedMs: number;
83
+ };
84
+ }
85
+ /** Token Balance History */
86
+ export interface TokenBalanceParams extends AlgorithmParams {
87
+ address: string;
88
+ tokenAddress: string;
89
+ pagination?: PaginationParams;
90
+ }
91
+ export interface TokenBalanceEntry {
92
+ blockNumber: number;
93
+ timestamp: number;
94
+ balance: string;
95
+ change: string;
96
+ txHash: string;
97
+ }
98
+ export interface TokenBalancePage {
99
+ entries: TokenBalanceEntry[];
100
+ address: string;
101
+ tokenAddress: string;
102
+ chainId: number | string;
103
+ }
104
+ /** Gas Price History */
105
+ export interface GasPriceParams extends AlgorithmParams {
106
+ targetBlock?: number | string;
107
+ pagination?: PaginationParams;
108
+ granularity?: "block" | "hour" | "day";
109
+ }
110
+ export interface GasPriceEntry {
111
+ blockNumber: number;
112
+ timestamp: number;
113
+ baseFee: string;
114
+ avgGasPrice: string;
115
+ minGasPrice: string;
116
+ maxGasPrice: string;
117
+ gasUsedRatio: number;
118
+ }
119
+ export interface GasPricePage {
120
+ entries: GasPriceEntry[];
121
+ chainId: number | string;
122
+ }
123
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ import type { Algorithm, AlgorithmResult, TokenBalanceParams, TokenBalancePage } from "../shared/types.js";
2
+ export declare class TokenBalanceHistoryAlgorithm implements Algorithm<TokenBalanceParams, TokenBalancePage> {
3
+ readonly name = "token-balance-history";
4
+ readonly description = "Track ERC-20 token balance changes via Transfer event logs";
5
+ readonly supportedChains: number[];
6
+ execute(params: TokenBalanceParams): Promise<AlgorithmResult<TokenBalancePage>>;
7
+ }
8
+ //# sourceMappingURL=TokenBalanceHistoryAlgorithm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenBalanceHistoryAlgorithm.d.ts","sourceRoot":"","sources":["../../src/token-balance/TokenBalanceHistoryAlgorithm.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAEjB,MAAM,oBAAoB,CAAC;AAmB5B,qBAAa,4BACX,YAAW,SAAS,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;IAE1D,QAAQ,CAAC,IAAI,2BAA2B;IACxC,QAAQ,CAAC,WAAW,gEAAgE;IACpF,QAAQ,CAAC,eAAe,WAAoB;IAEtC,OAAO,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC;CAuGtF"}
@@ -0,0 +1,103 @@
1
+ import { hexToNumber } from "@openscan/utils";
2
+ const SUPPORTED_CHAINS = [1, 10, 56, 137, 8453, 42161, 43114, 31337, 11155111];
3
+ // ERC-20 Transfer event signature
4
+ const TRANSFER_TOPIC = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef";
5
+ export class TokenBalanceHistoryAlgorithm {
6
+ name = "token-balance-history";
7
+ description = "Track ERC-20 token balance changes via Transfer event logs";
8
+ supportedChains = SUPPORTED_CHAINS;
9
+ async execute(params) {
10
+ const startTime = Date.now();
11
+ let rpcCalls = 0;
12
+ const nc = await import("@openscan/network-connectors");
13
+ const config = {
14
+ type: (params.strategyType ?? "fallback"),
15
+ rpcUrls: params.rpcUrls,
16
+ };
17
+ const client = nc.ClientFactory.createClient(params.chainId, config);
18
+ try {
19
+ const paddedAddress = `0x${params.address.slice(2).toLowerCase().padStart(64, "0")}`;
20
+ const fromBlock = params.pagination?.fromBlock
21
+ ? typeof params.pagination.fromBlock === "number"
22
+ ? `0x${params.pagination.fromBlock.toString(16)}`
23
+ : params.pagination.fromBlock
24
+ : "earliest";
25
+ const toBlock = params.pagination?.toBlock
26
+ ? typeof params.pagination.toBlock === "number"
27
+ ? `0x${params.pagination.toBlock.toString(16)}`
28
+ : params.pagination.toBlock
29
+ : "latest";
30
+ // Get Transfer events FROM address (outgoing)
31
+ const outgoingResult = await client.execute("eth_getLogs", [
32
+ {
33
+ address: params.tokenAddress,
34
+ topics: [TRANSFER_TOPIC, paddedAddress],
35
+ fromBlock,
36
+ toBlock,
37
+ },
38
+ ]);
39
+ rpcCalls++;
40
+ // Get Transfer events TO address (incoming)
41
+ const incomingResult = await client.execute("eth_getLogs", [
42
+ {
43
+ address: params.tokenAddress,
44
+ topics: [TRANSFER_TOPIC, null, paddedAddress],
45
+ fromBlock,
46
+ toBlock,
47
+ },
48
+ ]);
49
+ rpcCalls++;
50
+ const allLogs = [];
51
+ if (outgoingResult.success && outgoingResult.data) {
52
+ for (const log of outgoingResult.data) {
53
+ allLogs.push({ ...log, isIncoming: false });
54
+ }
55
+ }
56
+ if (incomingResult.success && incomingResult.data) {
57
+ for (const log of incomingResult.data) {
58
+ allLogs.push({ ...log, isIncoming: true });
59
+ }
60
+ }
61
+ // Sort by block number then log index
62
+ allLogs.sort((a, b) => {
63
+ const blockDiff = Number(hexToNumber(a.blockNumber)) - Number(hexToNumber(b.blockNumber));
64
+ if (blockDiff !== 0)
65
+ return blockDiff;
66
+ return Number(hexToNumber(a.logIndex)) - Number(hexToNumber(b.logIndex));
67
+ });
68
+ let runningBalance = 0n;
69
+ const entries = allLogs.map((log) => {
70
+ const value = BigInt(log.data);
71
+ const change = log.isIncoming ? value : -value;
72
+ runningBalance += change;
73
+ return {
74
+ blockNumber: Number(hexToNumber(log.blockNumber)),
75
+ timestamp: 0,
76
+ balance: runningBalance.toString(),
77
+ change: change.toString(),
78
+ txHash: log.transactionHash,
79
+ };
80
+ });
81
+ return {
82
+ success: true,
83
+ data: {
84
+ entries,
85
+ address: params.address,
86
+ tokenAddress: params.tokenAddress,
87
+ chainId: params.chainId,
88
+ },
89
+ metadata: {
90
+ chainId: params.chainId,
91
+ duration: Date.now() - startTime,
92
+ rpcCalls,
93
+ archivalRequired: fromBlock === "earliest",
94
+ timestamp: Date.now(),
95
+ },
96
+ };
97
+ }
98
+ finally {
99
+ await client.close();
100
+ }
101
+ }
102
+ }
103
+ //# sourceMappingURL=TokenBalanceHistoryAlgorithm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenBalanceHistoryAlgorithm.js","sourceRoot":"","sources":["../../src/token-balance/TokenBalanceHistoryAlgorithm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAU9C,MAAM,gBAAgB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;AAE/E,kCAAkC;AAClC,MAAM,cAAc,GAAG,oEAAoE,CAAC;AAc5F,MAAM,OAAO,4BAA4B;IAG9B,IAAI,GAAG,uBAAuB,CAAC;IAC/B,WAAW,GAAG,4DAA4D,CAAC;IAC3E,eAAe,GAAG,gBAAgB,CAAC;IAE5C,KAAK,CAAC,OAAO,CAAC,MAA0B;QACtC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,IAAI,QAAQ,GAAG,CAAC,CAAC;QAEjB,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,8BAA8B,CAAC,CAAC;QAExD,MAAM,MAAM,GAAG;YACb,IAAI,EAAE,CAAC,MAAM,CAAC,YAAY,IAAI,UAAU,CAAqC;YAC7E,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC;QACF,MAAM,MAAM,GAAG,EAAE,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,OAA2B,EAAE,MAAM,CAAC,CAAC;QAEzF,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,KAAK,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;YAErF,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,EAAE,SAAS;gBAC5C,CAAC,CAAC,OAAO,MAAM,CAAC,UAAU,CAAC,SAAS,KAAK,QAAQ;oBAC/C,CAAC,CAAC,KAAK,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;oBACjD,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS;gBAC/B,CAAC,CAAC,UAAU,CAAC;YACf,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,OAAO;gBACxC,CAAC,CAAC,OAAO,MAAM,CAAC,UAAU,CAAC,OAAO,KAAK,QAAQ;oBAC7C,CAAC,CAAC,KAAK,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;oBAC/C,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO;gBAC7B,CAAC,CAAC,QAAQ,CAAC;YAEb,8CAA8C;YAC9C,MAAM,cAAc,GAAG,MAAM,MAAM,CAAC,OAAO,CAAW,aAAa,EAAE;gBACnE;oBACE,OAAO,EAAE,MAAM,CAAC,YAAY;oBAC5B,MAAM,EAAE,CAAC,cAAc,EAAE,aAAa,CAAC;oBACvC,SAAS;oBACT,OAAO;iBACR;aACF,CAAC,CAAC;YACH,QAAQ,EAAE,CAAC;YAEX,4CAA4C;YAC5C,MAAM,cAAc,GAAG,MAAM,MAAM,CAAC,OAAO,CAAW,aAAa,EAAE;gBACnE;oBACE,OAAO,EAAE,MAAM,CAAC,YAAY;oBAC5B,MAAM,EAAE,CAAC,cAAc,EAAE,IAAI,EAAE,aAAa,CAAC;oBAC7C,SAAS;oBACT,OAAO;iBACR;aACF,CAAC,CAAC;YACH,QAAQ,EAAE,CAAC;YAEX,MAAM,OAAO,GAA4C,EAAE,CAAC;YAE5D,IAAI,cAAc,CAAC,OAAO,IAAI,cAAc,CAAC,IAAI,EAAE,CAAC;gBAClD,KAAK,MAAM,GAAG,IAAI,cAAc,CAAC,IAAI,EAAE,CAAC;oBACtC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC9C,CAAC;YACH,CAAC;YACD,IAAI,cAAc,CAAC,OAAO,IAAI,cAAc,CAAC,IAAI,EAAE,CAAC;gBAClD,KAAK,MAAM,GAAG,IAAI,cAAc,CAAC,IAAI,EAAE,CAAC;oBACtC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC7C,CAAC;YACH,CAAC;YAED,sCAAsC;YACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gBACpB,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;gBAC1F,IAAI,SAAS,KAAK,CAAC;oBAAE,OAAO,SAAS,CAAC;gBACtC,OAAO,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC3E,CAAC,CAAC,CAAC;YAEH,IAAI,cAAc,GAAG,EAAE,CAAC;YACxB,MAAM,OAAO,GAAwB,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;gBACvD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC/B,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;gBAC/C,cAAc,IAAI,MAAM,CAAC;gBAEzB,OAAO;oBACL,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;oBACjD,SAAS,EAAE,CAAC;oBACZ,OAAO,EAAE,cAAc,CAAC,QAAQ,EAAE;oBAClC,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE;oBACzB,MAAM,EAAE,GAAG,CAAC,eAAe;iBAC5B,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE;oBACJ,OAAO;oBACP,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,YAAY,EAAE,MAAM,CAAC,YAAY;oBACjC,OAAO,EAAE,MAAM,CAAC,OAAO;iBACxB;gBACD,QAAQ,EAAE;oBACR,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;oBAChC,QAAQ;oBACR,gBAAgB,EAAE,SAAS,KAAK,UAAU;oBAC1C,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;iBACtB;aACF,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,68 @@
1
+ import type { Algorithm, AlgorithmResult, TxHistoryParams, TxHistoryPage, TxSearchOptions, TxSearchResult } from "../shared/types.js";
2
+ type RpcClient = {
3
+ execute: <T>(method: string, params: any[]) => Promise<{
4
+ success: boolean;
5
+ data?: T | null;
6
+ }>;
7
+ close: () => Promise<void>;
8
+ };
9
+ export declare class TransactionHistoryAlgorithm implements Algorithm<TxHistoryParams, TxHistoryPage> {
10
+ readonly name = "tx-history";
11
+ readonly description = "Retrieve transaction history for an address via binary search on state changes";
12
+ readonly supportedChains: number[];
13
+ private client;
14
+ private nonceCache;
15
+ private balanceCache;
16
+ private rpcCalls;
17
+ /**
18
+ * Initialize with an externally-provided RPC client.
19
+ * Use this when integrating with an app that manages its own client lifecycle.
20
+ * The caller is responsible for closing the client.
21
+ */
22
+ initClient(client: RpcClient): void;
23
+ /** Clear internal nonce/balance caches. Call between different address searches. */
24
+ clearCache(): void;
25
+ private getNonce;
26
+ private getBalance;
27
+ private getState;
28
+ private getStatesInBatches;
29
+ private getOptimalSegmentCount;
30
+ private calculateBoundaries;
31
+ /**
32
+ * Find the smallest recent block range containing address activity.
33
+ * Uses exponential (galloping) search from the given block, doubling each step.
34
+ * Returns null if the address has no on-chain activity.
35
+ */
36
+ findRecentActivityRange(address: string, latestBlock?: number, signal?: AbortSignal): Promise<{
37
+ fromBlock: number;
38
+ toBlock: number;
39
+ } | null>;
40
+ /**
41
+ * Get the block range and total sent transaction count for an address.
42
+ * Uses binary search on nonce only — much faster than a full transaction search.
43
+ */
44
+ getTransactionRange(address: string): Promise<{
45
+ startBlock: number;
46
+ endBlock: number;
47
+ totalSent: number;
48
+ } | null>;
49
+ private findActivityBlocks;
50
+ private fetchBlockReceipts;
51
+ private fetchIndividualReceipts;
52
+ private fetchBlockTransactions;
53
+ /**
54
+ * Search for all transactions of an address using binary search on state changes.
55
+ * Supports progress callbacks, streaming results, and abort signals.
56
+ *
57
+ * Requires `initClient()` to be called first with an RPC client.
58
+ * The caller is responsible for closing the client.
59
+ */
60
+ searchAddressActivity(address: string, options?: TxSearchOptions): Promise<TxSearchResult>;
61
+ /**
62
+ * Algorithm interface entry point used by CLI and LangChain adapter.
63
+ * Creates its own client and manages the full lifecycle.
64
+ */
65
+ execute(params: TxHistoryParams): Promise<AlgorithmResult<TxHistoryPage>>;
66
+ }
67
+ export {};
68
+ //# sourceMappingURL=TransactionHistoryAlgorithm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TransactionHistoryAlgorithm.d.ts","sourceRoot":"","sources":["../../src/tx-history/TransactionHistoryAlgorithm.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EACf,eAAe,EACf,aAAa,EAEb,eAAe,EACf,cAAc,EACf,MAAM,oBAAoB,CAAC;AAyC5B,KAAK,SAAS,GAAG;IACf,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IAC9F,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B,CAAC;AAgBF,qBAAa,2BAA4B,YAAW,SAAS,CAAC,eAAe,EAAE,aAAa,CAAC;IAC3F,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,WAAW,oFAC+D;IACnF,QAAQ,CAAC,eAAe,WAAoB;IAE5C,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,QAAQ,CAAK;IAErB;;;;OAIG;IACH,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAInC,oFAAoF;IACpF,UAAU,IAAI,IAAI;YAOJ,QAAQ;YAYR,UAAU;YAYV,QAAQ;YAQR,kBAAkB;IAkBhC,OAAO,CAAC,sBAAsB;IAoB9B,OAAO,CAAC,mBAAmB;IAgB3B;;;;OAIG;IACG,uBAAuB,CAC3B,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAkCzD;;;OAGG;IACG,mBAAmB,CACvB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;YA2ChE,kBAAkB;YAkGlB,kBAAkB;YAsBlB,uBAAuB;YAgBvB,sBAAsB;IA4HpC;;;;;;OAMG;IACG,qBAAqB,CACzB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,cAAc,CAAC;IAiK1B;;;OAGG;IACG,OAAO,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;CAwEhF"}
@@ -0,0 +1,590 @@
1
+ import { hexToNumber } from "@openscan/utils";
2
+ const SUPPORTED_CHAINS = [1, 10, 56, 137, 8453, 42161, 43114, 31337, 11155111];
3
+ const INITIAL_RANGE = 100_000;
4
+ const MAX_SEGMENTS = 8;
5
+ const BATCH_SIZE = 8;
6
+ function toHex(n) {
7
+ return `0x${n.toString(16)}`;
8
+ }
9
+ async function batchExecute(tasks, batchSize) {
10
+ const results = [];
11
+ for (let i = 0; i < tasks.length; i += batchSize) {
12
+ const batch = tasks.slice(i, i + batchSize);
13
+ const batchResults = await Promise.all(batch.map((fn) => fn()));
14
+ results.push(...batchResults);
15
+ }
16
+ return results;
17
+ }
18
+ export class TransactionHistoryAlgorithm {
19
+ name = "tx-history";
20
+ description = "Retrieve transaction history for an address via binary search on state changes";
21
+ supportedChains = SUPPORTED_CHAINS;
22
+ client = null;
23
+ nonceCache = new Map();
24
+ balanceCache = new Map();
25
+ rpcCalls = 0;
26
+ /**
27
+ * Initialize with an externally-provided RPC client.
28
+ * Use this when integrating with an app that manages its own client lifecycle.
29
+ * The caller is responsible for closing the client.
30
+ */
31
+ initClient(client) {
32
+ this.client = client;
33
+ }
34
+ /** Clear internal nonce/balance caches. Call between different address searches. */
35
+ clearCache() {
36
+ this.nonceCache.clear();
37
+ this.balanceCache.clear();
38
+ }
39
+ // -- State queries --
40
+ async getNonce(address, block) {
41
+ const key = `${address}:${block}`;
42
+ const cached = this.nonceCache.get(key);
43
+ if (cached !== undefined)
44
+ return cached;
45
+ const client = this.client;
46
+ const result = await client.execute("eth_getTransactionCount", [address, toHex(block)]);
47
+ this.rpcCalls++;
48
+ const nonce = Number(hexToNumber(result.data || "0x0"));
49
+ this.nonceCache.set(key, nonce);
50
+ return nonce;
51
+ }
52
+ async getBalance(address, block) {
53
+ const key = `${address}:${block}`;
54
+ const cached = this.balanceCache.get(key);
55
+ if (cached !== undefined)
56
+ return cached;
57
+ const client = this.client;
58
+ const result = await client.execute("eth_getBalance", [address, toHex(block)]);
59
+ this.rpcCalls++;
60
+ const balance = BigInt(result.data || "0x0");
61
+ this.balanceCache.set(key, balance);
62
+ return balance;
63
+ }
64
+ async getState(address, block) {
65
+ const [nonce, balance] = await Promise.all([
66
+ this.getNonce(address, block),
67
+ this.getBalance(address, block),
68
+ ]);
69
+ return { nonce, balance };
70
+ }
71
+ async getStatesInBatches(address, blocks) {
72
+ const results = new Map();
73
+ const tasks = blocks.map((block) => async () => {
74
+ const state = await this.getState(address, block);
75
+ return { block, state };
76
+ });
77
+ const batchResults = await batchExecute(tasks, BATCH_SIZE);
78
+ for (const { block, state } of batchResults) {
79
+ results.set(block, state);
80
+ }
81
+ return results;
82
+ }
83
+ // -- Segmentation --
84
+ getOptimalSegmentCount(startState, endState, blockRange) {
85
+ const nonceDelta = endState.nonce - startState.nonce;
86
+ const balanceChanged = startState.balance !== endState.balance;
87
+ if (nonceDelta === 0 && !balanceChanged)
88
+ return 0;
89
+ if (blockRange <= 100)
90
+ return 2;
91
+ if (nonceDelta > 0) {
92
+ if (nonceDelta <= 2)
93
+ return 2;
94
+ if (nonceDelta <= 10)
95
+ return 4;
96
+ return MAX_SEGMENTS;
97
+ }
98
+ return 2;
99
+ }
100
+ calculateBoundaries(startBlock, endBlock, segmentCount) {
101
+ const segmentSize = Math.floor((endBlock - startBlock) / segmentCount);
102
+ const boundaries = [startBlock];
103
+ for (let i = 1; i < segmentCount; i++) {
104
+ boundaries.push(startBlock + segmentSize * i);
105
+ }
106
+ boundaries.push(endBlock);
107
+ return boundaries;
108
+ }
109
+ // -- Range finding --
110
+ /**
111
+ * Find the smallest recent block range containing address activity.
112
+ * Uses exponential (galloping) search from the given block, doubling each step.
113
+ * Returns null if the address has no on-chain activity.
114
+ */
115
+ async findRecentActivityRange(address, latestBlock, signal) {
116
+ if (!latestBlock) {
117
+ const result = await this.client.execute("eth_blockNumber", []);
118
+ this.rpcCalls++;
119
+ if (!result.data)
120
+ return null;
121
+ latestBlock = Number(hexToNumber(result.data));
122
+ }
123
+ const latestState = await this.getState(address, latestBlock);
124
+ if (latestState.nonce === 0 && latestState.balance === 0n)
125
+ return null;
126
+ let range = INITIAL_RANGE;
127
+ let prevBoundary = latestBlock;
128
+ while (true) {
129
+ if (signal?.aborted)
130
+ return null;
131
+ const boundary = Math.max(latestBlock - range, 0);
132
+ const boundaryState = await this.getState(address, boundary);
133
+ if (boundaryState.nonce !== latestState.nonce ||
134
+ boundaryState.balance !== latestState.balance) {
135
+ return { fromBlock: boundary, toBlock: prevBoundary };
136
+ }
137
+ if (boundary === 0)
138
+ break;
139
+ prevBoundary = boundary;
140
+ range *= 2;
141
+ }
142
+ return { fromBlock: 0, toBlock: latestBlock };
143
+ }
144
+ /**
145
+ * Get the block range and total sent transaction count for an address.
146
+ * Uses binary search on nonce only — much faster than a full transaction search.
147
+ */
148
+ async getTransactionRange(address) {
149
+ const client = this.client;
150
+ const blockResult = await client.execute("eth_blockNumber", []);
151
+ this.rpcCalls++;
152
+ if (!blockResult.data)
153
+ return null;
154
+ const latestBlock = Number(hexToNumber(blockResult.data));
155
+ const currentNonce = await this.getNonce(address, latestBlock);
156
+ if (currentNonce === 0)
157
+ return null;
158
+ // Binary search for first block where nonce became 1 (first sent tx)
159
+ let lo = 0;
160
+ let hi = latestBlock;
161
+ while (lo < hi) {
162
+ const mid = Math.floor((lo + hi) / 2);
163
+ const nonce = await this.getNonce(address, mid);
164
+ if (nonce >= 1) {
165
+ hi = mid;
166
+ }
167
+ else {
168
+ lo = mid + 1;
169
+ }
170
+ }
171
+ const startBlock = lo;
172
+ // Binary search for first block where nonce reached currentNonce (last sent tx)
173
+ lo = startBlock;
174
+ hi = latestBlock;
175
+ while (lo < hi) {
176
+ const mid = Math.floor((lo + hi) / 2);
177
+ const nonce = await this.getNonce(address, mid);
178
+ if (nonce >= currentNonce) {
179
+ hi = mid;
180
+ }
181
+ else {
182
+ lo = mid + 1;
183
+ }
184
+ }
185
+ const endBlock = lo;
186
+ return { startBlock, endBlock, totalSent: currentNonce };
187
+ }
188
+ // -- Binary search --
189
+ async findActivityBlocks(address, startBlock, endBlock, startState, endState, maxBlocks, foundBlocks, signal) {
190
+ if (signal?.aborted)
191
+ return;
192
+ if (foundBlocks.size >= maxBlocks)
193
+ return;
194
+ if (endBlock - startBlock <= 1) {
195
+ const nonceChanged = startState.nonce !== endState.nonce;
196
+ const balanceChanged = startState.balance !== endState.balance;
197
+ if (nonceChanged || balanceChanged) {
198
+ foundBlocks.add(endBlock);
199
+ }
200
+ return;
201
+ }
202
+ const blockRange = endBlock - startBlock;
203
+ const segmentCount = this.getOptimalSegmentCount(startState, endState, blockRange);
204
+ if (segmentCount === 0)
205
+ return;
206
+ if (segmentCount <= 2) {
207
+ const midBlock = Math.floor((startBlock + endBlock) / 2);
208
+ const midState = await this.getState(address, midBlock);
209
+ const rightChanged = midState.nonce !== endState.nonce || midState.balance !== endState.balance;
210
+ const leftChanged = startState.nonce !== midState.nonce || startState.balance !== midState.balance;
211
+ if (rightChanged) {
212
+ await this.findActivityBlocks(address, midBlock, endBlock, midState, endState, maxBlocks, foundBlocks, signal);
213
+ }
214
+ if (leftChanged && foundBlocks.size < maxBlocks) {
215
+ await this.findActivityBlocks(address, startBlock, midBlock, startState, midState, maxBlocks, foundBlocks, signal);
216
+ }
217
+ return;
218
+ }
219
+ // Multi-segment path
220
+ const boundaries = this.calculateBoundaries(startBlock, endBlock, segmentCount);
221
+ const internalBlocks = boundaries.slice(1, -1);
222
+ const stateMap = await this.getStatesInBatches(address, internalBlocks);
223
+ stateMap.set(startBlock, startState);
224
+ stateMap.set(endBlock, endState);
225
+ for (let i = segmentCount - 1; i >= 0; i--) {
226
+ if (signal?.aborted)
227
+ break;
228
+ if (foundBlocks.size >= maxBlocks)
229
+ break;
230
+ const segStart = boundaries[i];
231
+ const segEnd = boundaries[i + 1];
232
+ const segStartState = stateMap.get(segStart);
233
+ const segEndState = stateMap.get(segEnd);
234
+ if (!segStartState || !segEndState)
235
+ continue;
236
+ const hasChanges = segStartState.nonce !== segEndState.nonce || segStartState.balance !== segEndState.balance;
237
+ if (hasChanges) {
238
+ await this.findActivityBlocks(address, segStart, segEnd, segStartState, segEndState, maxBlocks, foundBlocks, signal);
239
+ }
240
+ }
241
+ }
242
+ // -- Block transaction fetching --
243
+ async fetchBlockReceipts(blockNum) {
244
+ const client = this.client;
245
+ const receipts = new Map();
246
+ try {
247
+ const result = await client.execute("eth_getBlockReceipts", [
248
+ toHex(blockNum),
249
+ ]);
250
+ this.rpcCalls++;
251
+ if (result.data && Array.isArray(result.data)) {
252
+ for (const receipt of result.data) {
253
+ if (receipt?.transactionHash) {
254
+ receipts.set(receipt.transactionHash.toLowerCase(), receipt);
255
+ }
256
+ }
257
+ return receipts;
258
+ }
259
+ }
260
+ catch {
261
+ // Not supported — caller will use individual fetches
262
+ }
263
+ return receipts;
264
+ }
265
+ async fetchIndividualReceipts(hashes) {
266
+ const client = this.client;
267
+ const receipts = new Map();
268
+ const tasks = hashes.map((hash) => async () => {
269
+ const result = await client.execute("eth_getTransactionReceipt", [
270
+ hash,
271
+ ]);
272
+ this.rpcCalls++;
273
+ if (result.data)
274
+ receipts.set(hash.toLowerCase(), result.data);
275
+ });
276
+ await batchExecute(tasks, BATCH_SIZE);
277
+ return receipts;
278
+ }
279
+ async fetchBlockTransactions(blockNum, normalizedAddress, signal) {
280
+ if (signal?.aborted)
281
+ return [];
282
+ const client = this.client;
283
+ const blockResult = await client.execute("eth_getBlockByNumber", [
284
+ toHex(blockNum),
285
+ true,
286
+ ]);
287
+ this.rpcCalls++;
288
+ const block = blockResult.data;
289
+ if (!block?.transactions)
290
+ return [];
291
+ const timestamp = Number(hexToNumber(block.timestamp || "0x0"));
292
+ const directTxs = [];
293
+ const otherTxs = [];
294
+ for (const raw of block.transactions) {
295
+ if (typeof raw === "string")
296
+ continue;
297
+ const txFrom = raw.from?.toLowerCase();
298
+ const txTo = raw.to?.toLowerCase();
299
+ const isSent = txFrom === normalizedAddress;
300
+ const isReceived = txTo === normalizedAddress;
301
+ if (isSent) {
302
+ directTxs.push({ tx: raw, type: "sent" });
303
+ }
304
+ else if (isReceived) {
305
+ directTxs.push({ tx: raw, type: "received" });
306
+ }
307
+ else {
308
+ otherTxs.push(raw);
309
+ }
310
+ }
311
+ // Fetch receipts
312
+ let receipts = await this.fetchBlockReceipts(blockNum);
313
+ if (receipts.size === 0) {
314
+ const neededHashes = directTxs.map(({ tx }) => tx.hash);
315
+ if (directTxs.length === 0) {
316
+ for (const tx of otherTxs)
317
+ neededHashes.push(tx.hash);
318
+ }
319
+ if (neededHashes.length > 0) {
320
+ receipts = await this.fetchIndividualReceipts(neededHashes);
321
+ }
322
+ }
323
+ const buildEntry = (tx, type, receipt) => ({
324
+ hash: tx.hash,
325
+ blockNumber: blockNum,
326
+ timestamp,
327
+ from: tx.from,
328
+ to: tx.to,
329
+ value: tx.value,
330
+ gasUsed: receipt?.gasUsed ?? tx.gas,
331
+ gasPrice: tx.gasPrice,
332
+ status: receipt?.status === "0x1" ? "success" : "failure",
333
+ type,
334
+ methodId: tx.input.length >= 10 ? tx.input.slice(0, 10) : undefined,
335
+ });
336
+ const entries = [];
337
+ for (const { tx, type } of directTxs) {
338
+ entries.push(buildEntry(tx, type, receipts.get(tx.hash.toLowerCase())));
339
+ }
340
+ // Internal transaction detection when no direct match found
341
+ if (directTxs.length === 0 && otherTxs.length > 0) {
342
+ const strippedAddress = normalizedAddress.replace("0x", "");
343
+ const inputMatches = [];
344
+ const remaining = [];
345
+ for (const tx of otherTxs) {
346
+ if (tx.input?.toLowerCase().includes(strippedAddress)) {
347
+ inputMatches.push(tx);
348
+ }
349
+ else {
350
+ remaining.push(tx);
351
+ }
352
+ }
353
+ for (const tx of inputMatches) {
354
+ entries.push(buildEntry(tx, "internal", receipts.get(tx.hash.toLowerCase())));
355
+ }
356
+ if (inputMatches.length === 0) {
357
+ for (const tx of remaining) {
358
+ const receipt = receipts.get(tx.hash.toLowerCase());
359
+ const logs = receipt?.logs || [];
360
+ let found = false;
361
+ for (const log of logs) {
362
+ if (log.topics) {
363
+ for (const topic of log.topics) {
364
+ if (topic.toLowerCase().includes(strippedAddress)) {
365
+ found = true;
366
+ break;
367
+ }
368
+ }
369
+ }
370
+ if (!found && log.data?.toLowerCase().includes(strippedAddress)) {
371
+ found = true;
372
+ }
373
+ if (found)
374
+ break;
375
+ }
376
+ if (found) {
377
+ entries.push(buildEntry(tx, "internal", receipt));
378
+ }
379
+ }
380
+ }
381
+ }
382
+ return entries;
383
+ }
384
+ // -- Public search methods --
385
+ /**
386
+ * Search for all transactions of an address using binary search on state changes.
387
+ * Supports progress callbacks, streaming results, and abort signals.
388
+ *
389
+ * Requires `initClient()` to be called first with an RPC client.
390
+ * The caller is responsible for closing the client.
391
+ */
392
+ async searchAddressActivity(address, options = {}) {
393
+ const { limit = 100, fromBlock: optFromBlock, toBlock: optToBlock, onProgress, onTransactionsFound, signal, } = options;
394
+ const searchStart = performance.now();
395
+ this.rpcCalls = 0;
396
+ const normalizedAddress = address.toLowerCase();
397
+ // Resolve latest block
398
+ const blockResult = await this.client.execute("eth_blockNumber", []);
399
+ this.rpcCalls++;
400
+ if (!blockResult.data) {
401
+ return {
402
+ blocks: [],
403
+ entries: [],
404
+ stats: {
405
+ totalBlocks: 0,
406
+ totalTxs: 0,
407
+ sentCount: 0,
408
+ receivedCount: 0,
409
+ internalCount: 0,
410
+ rpcCalls: this.rpcCalls,
411
+ elapsedMs: 0,
412
+ },
413
+ };
414
+ }
415
+ const latestBlock = Number(hexToNumber(blockResult.data));
416
+ let toBlock = optToBlock ?? latestBlock;
417
+ let fromBlock;
418
+ if (optFromBlock !== undefined) {
419
+ fromBlock = optFromBlock;
420
+ }
421
+ else {
422
+ onProgress?.({
423
+ phase: "searching",
424
+ current: 0,
425
+ total: 0,
426
+ message: "Finding activity range...",
427
+ });
428
+ const range = await this.findRecentActivityRange(normalizedAddress, toBlock, signal);
429
+ if (!range || signal?.aborted) {
430
+ return {
431
+ blocks: [],
432
+ entries: [],
433
+ stats: {
434
+ totalBlocks: 0,
435
+ totalTxs: 0,
436
+ sentCount: 0,
437
+ receivedCount: 0,
438
+ internalCount: 0,
439
+ rpcCalls: this.rpcCalls,
440
+ elapsedMs: performance.now() - searchStart,
441
+ },
442
+ };
443
+ }
444
+ fromBlock = range.fromBlock;
445
+ toBlock = Math.min(toBlock, range.toBlock);
446
+ }
447
+ onProgress?.({
448
+ phase: "searching",
449
+ current: 0,
450
+ total: 0,
451
+ message: "Binary searching for transaction blocks...",
452
+ blockRange: { from: fromBlock, to: toBlock },
453
+ });
454
+ const [startState, endState] = await Promise.all([
455
+ this.getState(normalizedAddress, fromBlock),
456
+ this.getState(normalizedAddress, toBlock),
457
+ ]);
458
+ if (startState.nonce === endState.nonce && startState.balance === endState.balance) {
459
+ return {
460
+ blocks: [],
461
+ entries: [],
462
+ stats: {
463
+ totalBlocks: 0,
464
+ totalTxs: 0,
465
+ sentCount: 0,
466
+ receivedCount: 0,
467
+ internalCount: 0,
468
+ rpcCalls: this.rpcCalls,
469
+ elapsedMs: performance.now() - searchStart,
470
+ },
471
+ };
472
+ }
473
+ // Find blocks with activity
474
+ const foundBlocks = new Set();
475
+ await this.findActivityBlocks(normalizedAddress, fromBlock, toBlock, startState, endState, limit > 0 ? limit + 1 : Number.MAX_SAFE_INTEGER, foundBlocks, signal);
476
+ const sortedBlocks = Array.from(foundBlocks).sort((a, b) => b - a);
477
+ const blocksToFetch = limit > 0 ? sortedBlocks.slice(0, limit) : sortedBlocks;
478
+ // Fetch transactions
479
+ onProgress?.({
480
+ phase: "fetching",
481
+ current: 0,
482
+ total: blocksToFetch.length,
483
+ message: `Fetching transactions from ${blocksToFetch.length} blocks...`,
484
+ });
485
+ const allEntries = [];
486
+ let fetched = 0;
487
+ for (let i = 0; i < blocksToFetch.length; i += 4) {
488
+ if (signal?.aborted)
489
+ break;
490
+ const batch = blocksToFetch.slice(i, i + 4);
491
+ const tasks = batch.map((block) => () => this.fetchBlockTransactions(block, normalizedAddress, signal));
492
+ const batchResults = await batchExecute(tasks, 4);
493
+ const batchEntries = batchResults.flat();
494
+ allEntries.push(...batchEntries);
495
+ fetched += batch.length;
496
+ if (batchEntries.length > 0) {
497
+ onTransactionsFound?.(batchEntries);
498
+ }
499
+ onProgress?.({
500
+ phase: "fetching",
501
+ current: fetched,
502
+ total: blocksToFetch.length,
503
+ message: `Fetching transactions (${fetched}/${blocksToFetch.length})...`,
504
+ });
505
+ }
506
+ allEntries.sort((a, b) => b.blockNumber - a.blockNumber);
507
+ const stats = {
508
+ totalBlocks: blocksToFetch.length,
509
+ totalTxs: allEntries.length,
510
+ sentCount: allEntries.filter((e) => e.type === "sent").length,
511
+ receivedCount: allEntries.filter((e) => e.type === "received").length,
512
+ internalCount: allEntries.filter((e) => e.type === "internal").length,
513
+ rpcCalls: this.rpcCalls,
514
+ elapsedMs: performance.now() - searchStart,
515
+ };
516
+ return { blocks: blocksToFetch, entries: allEntries, stats };
517
+ }
518
+ // -- Algorithm interface (execute) --
519
+ /**
520
+ * Algorithm interface entry point used by CLI and LangChain adapter.
521
+ * Creates its own client and manages the full lifecycle.
522
+ */
523
+ async execute(params) {
524
+ const startTime = Date.now();
525
+ this.rpcCalls = 0;
526
+ this.clearCache();
527
+ const nc = await import("@openscan/network-connectors");
528
+ const config = {
529
+ type: (params.strategyType ?? "fallback"),
530
+ rpcUrls: params.rpcUrls,
531
+ };
532
+ const client = nc.ClientFactory.createClient(params.chainId, config);
533
+ this.initClient(client);
534
+ try {
535
+ const result = await this.searchAddressActivity(params.address, {
536
+ limit: params.pagination?.pageSize ?? 100,
537
+ fromBlock: params.pagination?.fromBlock !== undefined
538
+ ? Number(params.pagination.fromBlock)
539
+ : undefined,
540
+ toBlock: params.pagination?.cursor
541
+ ? Number(params.pagination.cursor)
542
+ : params.pagination?.toBlock !== undefined
543
+ ? Number(params.pagination.toBlock)
544
+ : undefined,
545
+ });
546
+ // Get latest block for archivalRequired calculation
547
+ const latestResult = await client.execute("eth_blockNumber", []);
548
+ const latestBlock = latestResult.data ? Number(hexToNumber(latestResult.data)) : 0;
549
+ const lowestBlock = result.blocks[result.blocks.length - 1];
550
+ const hasMore = result.blocks.length > (params.pagination?.pageSize ?? 100);
551
+ const pageEntries = hasMore
552
+ ? result.entries.slice(0, params.pagination?.pageSize ?? 100)
553
+ : result.entries;
554
+ const nextCursor = hasMore && lowestBlock !== undefined ? String(lowestBlock - 1) : undefined;
555
+ const fromBlock = result.blocks.length > 0
556
+ ? result.blocks[result.blocks.length - 1]
557
+ : latestBlock;
558
+ return {
559
+ success: true,
560
+ data: {
561
+ entries: pageEntries,
562
+ address: params.address,
563
+ chainId: params.chainId,
564
+ },
565
+ pagination: { hasMore, nextCursor },
566
+ metadata: {
567
+ chainId: params.chainId,
568
+ duration: Date.now() - startTime,
569
+ rpcCalls: this.rpcCalls,
570
+ archivalRequired: fromBlock < latestBlock - 128,
571
+ timestamp: Date.now(),
572
+ },
573
+ };
574
+ }
575
+ catch (err) {
576
+ return {
577
+ success: false,
578
+ error: {
579
+ code: "RPC_ERROR",
580
+ message: err instanceof Error ? err.message : "Unknown error",
581
+ },
582
+ };
583
+ }
584
+ finally {
585
+ await client.close();
586
+ this.client = null;
587
+ }
588
+ }
589
+ }
590
+ //# sourceMappingURL=TransactionHistoryAlgorithm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TransactionHistoryAlgorithm.js","sourceRoot":"","sources":["../../src/tx-history/TransactionHistoryAlgorithm.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@openscan/algorithms",
3
+ "repository": {
4
+ "type": "git",
5
+ "url": "https://github.com/openscan-explorer/ia.git",
6
+ "directory": "packages/algorithms"
7
+ },
8
+ "version": "0.0.1-alpha",
9
+ "type": "module",
10
+ "dependencies": {
11
+ "@openscan/utils": "0.0.1-alpha"
12
+ },
13
+ "peerDependencies": {
14
+ "@openscan/network-connectors": "^1.7.0"
15
+ },
16
+ "devDependencies": {
17
+ "@openscan/network-connectors": "^1.7.0",
18
+ "@types/node": "^24.10.0",
19
+ "tsx": "^4.21.0",
20
+ "typescript": "^5.9.3",
21
+ "@openscan/tsconfig": "0.0.0"
22
+ },
23
+ "main": "dist/index.js",
24
+ "types": "dist/index.d.ts",
25
+ "exports": {
26
+ ".": {
27
+ "import": "./dist/index.js",
28
+ "types": "./dist/index.d.ts"
29
+ }
30
+ },
31
+ "files": [
32
+ "dist"
33
+ ],
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
37
+ "scripts": {
38
+ "build": "tsc -p tsconfig.json",
39
+ "test": "node --experimental-test-module-mocks --import tsx --test tests/**/*.test.ts",
40
+ "typecheck": "tsc --noEmit"
41
+ }
42
+ }