chunktech 0.1.0
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/README.md +250 -0
- package/dist/assembler.d.ts +58 -0
- package/dist/assembler.d.ts.map +1 -0
- package/dist/assembler.js +158 -0
- package/dist/assembler.js.map +1 -0
- package/dist/chunker.d.ts +65 -0
- package/dist/chunker.d.ts.map +1 -0
- package/dist/chunker.js +220 -0
- package/dist/chunker.js.map +1 -0
- package/dist/crypto.d.ts +38 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +242 -0
- package/dist/crypto.js.map +1 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +180 -0
- package/dist/index.js.map +1 -0
- package/dist/sender.d.ts +30 -0
- package/dist/sender.d.ts.map +1 -0
- package/dist/sender.js +79 -0
- package/dist/sender.js.map +1 -0
- package/dist/tracker.d.ts +63 -0
- package/dist/tracker.d.ts.map +1 -0
- package/dist/tracker.js +199 -0
- package/dist/tracker.js.map +1 -0
- package/dist/types.d.ts +138 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +21 -0
- package/dist/types.js.map +1 -0
- package/package.json +47 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChunkTech - On-chain file storage via chunked transactions
|
|
3
|
+
*
|
|
4
|
+
* Store and retrieve files on EVM chains (Ethereum, Base, Arbitrum)
|
|
5
|
+
* using transaction calldata.
|
|
6
|
+
*/
|
|
7
|
+
import { createPublicClient, http } from 'viem';
|
|
8
|
+
import { mainnet, base, arbitrum, sepolia, baseSepolia, arbitrumSepolia } from 'viem/chains';
|
|
9
|
+
import { chunkData } from './chunker.js';
|
|
10
|
+
import { sendChunks } from './sender.js';
|
|
11
|
+
import { waitForTransactions, TransactionMonitor } from './tracker.js';
|
|
12
|
+
import { assembleFromHashes, StreamingAssembler } from './assembler.js';
|
|
13
|
+
import { encryptForRecipients } from './crypto.js';
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// Chain Registry
|
|
16
|
+
// ============================================================================
|
|
17
|
+
const CHAINS = {
|
|
18
|
+
1: mainnet,
|
|
19
|
+
8453: base,
|
|
20
|
+
42161: arbitrum,
|
|
21
|
+
11155111: sepolia,
|
|
22
|
+
84532: baseSepolia,
|
|
23
|
+
421614: arbitrumSepolia,
|
|
24
|
+
};
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// ChunkTech Class
|
|
27
|
+
// ============================================================================
|
|
28
|
+
export class ChunkTech {
|
|
29
|
+
walletClient;
|
|
30
|
+
publicClient;
|
|
31
|
+
chain;
|
|
32
|
+
constructor(config) {
|
|
33
|
+
this.walletClient = config.walletClient;
|
|
34
|
+
this.chain = config.chain || this.detectChain();
|
|
35
|
+
this.publicClient =
|
|
36
|
+
config.publicClient ||
|
|
37
|
+
createPublicClient({
|
|
38
|
+
chain: this.chain,
|
|
39
|
+
transport: http(config.rpcUrl),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
detectChain() {
|
|
43
|
+
const chainId = this.walletClient.chain?.id;
|
|
44
|
+
if (chainId && CHAINS[chainId]) {
|
|
45
|
+
return CHAINS[chainId];
|
|
46
|
+
}
|
|
47
|
+
return base; // Default to Base
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Upload data to chain
|
|
51
|
+
*/
|
|
52
|
+
async upload(data, options = {}) {
|
|
53
|
+
// Convert input to Uint8Array
|
|
54
|
+
let bytes;
|
|
55
|
+
if (typeof data === 'string') {
|
|
56
|
+
bytes = new TextEncoder().encode(data);
|
|
57
|
+
}
|
|
58
|
+
else if (data instanceof ArrayBuffer) {
|
|
59
|
+
bytes = new Uint8Array(data);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
bytes = data;
|
|
63
|
+
}
|
|
64
|
+
// Encrypt if requested
|
|
65
|
+
let payload = bytes;
|
|
66
|
+
let encrypted = false;
|
|
67
|
+
if (options.encrypt && options.keys) {
|
|
68
|
+
const recipients = options.recipients || [];
|
|
69
|
+
const encryptedPayload = await encryptForRecipients(options.keys, recipients, bytes);
|
|
70
|
+
payload = new TextEncoder().encode(JSON.stringify(encryptedPayload));
|
|
71
|
+
encrypted = true;
|
|
72
|
+
}
|
|
73
|
+
// Chunk the data
|
|
74
|
+
const chunked = chunkData(payload);
|
|
75
|
+
// Send chunks
|
|
76
|
+
const results = await sendChunks(this.walletClient, chunked.chunks, {
|
|
77
|
+
onProgress: options.onProgress,
|
|
78
|
+
encrypted,
|
|
79
|
+
});
|
|
80
|
+
// Wait for confirmations
|
|
81
|
+
const confirmations = options.confirmations ?? 1;
|
|
82
|
+
if (confirmations > 0) {
|
|
83
|
+
await waitForTransactions(this.publicClient, results, { confirmations });
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
chunkId: chunked.id,
|
|
87
|
+
txHashes: results.map((r) => r.hash),
|
|
88
|
+
totalChunks: chunked.total,
|
|
89
|
+
totalBytes: bytes.length,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Download data from chain
|
|
94
|
+
*/
|
|
95
|
+
async download(txHashes, options = {}) {
|
|
96
|
+
const data = await assembleFromHashes(this.publicClient, txHashes, options);
|
|
97
|
+
if (!data) {
|
|
98
|
+
throw new Error('Failed to assemble data from transactions');
|
|
99
|
+
}
|
|
100
|
+
// Extract chunk ID from first chunk (if available)
|
|
101
|
+
let chunkId = '';
|
|
102
|
+
try {
|
|
103
|
+
const tx = await this.publicClient.getTransaction({ hash: txHashes[0] });
|
|
104
|
+
if (tx?.input) {
|
|
105
|
+
const calldata = hexToString(tx.input);
|
|
106
|
+
const match = calldata.match(/"id":"([^"]+)"/);
|
|
107
|
+
if (match) {
|
|
108
|
+
chunkId = match[1];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// Ignore - chunkId is optional
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
data,
|
|
117
|
+
chunkId,
|
|
118
|
+
totalChunks: txHashes.length,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get a streaming assembler for progressive downloads
|
|
123
|
+
*/
|
|
124
|
+
getStreamingAssembler(options = {}) {
|
|
125
|
+
return new StreamingAssembler(this.publicClient, options);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get a transaction monitor for tracking uploads
|
|
129
|
+
*/
|
|
130
|
+
getTransactionMonitor(options = {}) {
|
|
131
|
+
return new TransactionMonitor(this.publicClient, options);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Estimate chunks needed for data
|
|
135
|
+
*/
|
|
136
|
+
estimateChunks(dataSize) {
|
|
137
|
+
return Math.ceil(dataSize / 33333);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Get the current chain
|
|
141
|
+
*/
|
|
142
|
+
getChain() {
|
|
143
|
+
return this.chain;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get the public client
|
|
147
|
+
*/
|
|
148
|
+
getPublicClient() {
|
|
149
|
+
return this.publicClient;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// ============================================================================
|
|
153
|
+
// Exports
|
|
154
|
+
// ============================================================================
|
|
155
|
+
// Main class
|
|
156
|
+
export { ChunkTech as default };
|
|
157
|
+
// Chunking utilities
|
|
158
|
+
export { chunkData, encodeChunk, decodeChunk, reassembleChunks, isChunk, isEncryptedChunk, generateChunkId, estimateChunks, estimateCalldataSize, ChunkTracker, } from './chunker.js';
|
|
159
|
+
// Sender utilities
|
|
160
|
+
export { sendChunk, sendChunks, sendChunksParallel } from './sender.js';
|
|
161
|
+
// Tracker utilities
|
|
162
|
+
export { waitForTransaction, waitForTransactions, checkTransactionStatus, TransactionMonitor, } from './tracker.js';
|
|
163
|
+
// Assembler utilities
|
|
164
|
+
export { fetchTransaction, fetchChunk, fetchChunks, fetchChunksParallel, assembleFromHashes, StreamingAssembler, } from './assembler.js';
|
|
165
|
+
// Crypto utilities (optional)
|
|
166
|
+
export { generateKeyPair, generateEncryptionKeys, deriveKeysFromSignature, encryptForRecipients, decryptForRecipient, toHex, fromHex, bundleToHex, bundleFromHex, } from './crypto.js';
|
|
167
|
+
// Constants
|
|
168
|
+
export { MAX_CHUNK_SIZE, CHUNK_PREFIX, CHUNK_ENCRYPTED_PREFIX, SUPPORTED_CHAINS } from './types.js';
|
|
169
|
+
// ============================================================================
|
|
170
|
+
// Utilities
|
|
171
|
+
// ============================================================================
|
|
172
|
+
function hexToString(hex) {
|
|
173
|
+
const cleanHex = hex.startsWith('0x') ? hex.slice(2) : hex;
|
|
174
|
+
const bytes = new Uint8Array(cleanHex.length / 2);
|
|
175
|
+
for (let i = 0; i < cleanHex.length; i += 2) {
|
|
176
|
+
bytes[i / 2] = parseInt(cleanHex.substr(i, 2), 16);
|
|
177
|
+
}
|
|
178
|
+
return new TextDecoder().decode(bytes);
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/sender.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChunkTech - Transaction Sender
|
|
3
|
+
* Broadcast chunks as calldata transactions
|
|
4
|
+
*/
|
|
5
|
+
import type { WalletClient, Hash } from 'viem';
|
|
6
|
+
import type { Chunk } from './types.js';
|
|
7
|
+
export interface SendResult {
|
|
8
|
+
hash: Hash;
|
|
9
|
+
part: number;
|
|
10
|
+
total: number;
|
|
11
|
+
}
|
|
12
|
+
export interface SendOptions {
|
|
13
|
+
/** Progress callback */
|
|
14
|
+
onProgress?: (sent: number, total: number) => void;
|
|
15
|
+
/** Whether chunks are encrypted */
|
|
16
|
+
encrypted?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Send a single chunk as a transaction
|
|
20
|
+
*/
|
|
21
|
+
export declare function sendChunk(walletClient: WalletClient, chunk: Chunk, encrypted?: boolean): Promise<Hash>;
|
|
22
|
+
/**
|
|
23
|
+
* Send all chunks as transactions
|
|
24
|
+
*/
|
|
25
|
+
export declare function sendChunks(walletClient: WalletClient, chunks: Chunk[], options?: SendOptions): Promise<SendResult[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Send chunks in parallel (faster but may cause nonce issues)
|
|
28
|
+
*/
|
|
29
|
+
export declare function sendChunksParallel(walletClient: WalletClient, chunks: Chunk[], options?: SendOptions): Promise<SendResult[]>;
|
|
30
|
+
//# sourceMappingURL=sender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sender.d.ts","sourceRoot":"","sources":["../src/sender.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,IAAI,EAAkB,MAAM,MAAM,CAAC;AAC/D,OAAO,KAAK,EAAE,KAAK,EAAiB,MAAM,YAAY,CAAC;AAOvD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,wBAAwB;IACxB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,mCAAmC;IACnC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAMD;;GAEG;AACH,wBAAsB,SAAS,CAC7B,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,KAAK,EACZ,SAAS,UAAQ,GAChB,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,KAAK,EAAE,EACf,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,EAAE,CAAC,CAoBvB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,KAAK,EAAE,EACf,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,EAAE,CAAC,CAoBvB"}
|
package/dist/sender.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChunkTech - Transaction Sender
|
|
3
|
+
* Broadcast chunks as calldata transactions
|
|
4
|
+
*/
|
|
5
|
+
import { encodeChunk } from './chunker.js';
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Sender
|
|
8
|
+
// ============================================================================
|
|
9
|
+
/**
|
|
10
|
+
* Send a single chunk as a transaction
|
|
11
|
+
*/
|
|
12
|
+
export async function sendChunk(walletClient, chunk, encrypted = false) {
|
|
13
|
+
const calldata = encodeChunk(chunk, encrypted);
|
|
14
|
+
const hexData = stringToHex(calldata);
|
|
15
|
+
const account = walletClient.account;
|
|
16
|
+
if (!account) {
|
|
17
|
+
throw new Error('WalletClient must have an account');
|
|
18
|
+
}
|
|
19
|
+
// Self-transfer with calldata
|
|
20
|
+
const hash = await walletClient.sendTransaction({
|
|
21
|
+
account,
|
|
22
|
+
chain: walletClient.chain,
|
|
23
|
+
to: account.address,
|
|
24
|
+
value: 0n,
|
|
25
|
+
data: hexData,
|
|
26
|
+
});
|
|
27
|
+
return hash;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Send all chunks as transactions
|
|
31
|
+
*/
|
|
32
|
+
export async function sendChunks(walletClient, chunks, options = {}) {
|
|
33
|
+
const { onProgress, encrypted = false } = options;
|
|
34
|
+
const results = [];
|
|
35
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
36
|
+
const chunk = chunks[i];
|
|
37
|
+
const hash = await sendChunk(walletClient, chunk, encrypted);
|
|
38
|
+
results.push({
|
|
39
|
+
hash,
|
|
40
|
+
part: chunk.part,
|
|
41
|
+
total: chunk.total,
|
|
42
|
+
});
|
|
43
|
+
if (onProgress) {
|
|
44
|
+
onProgress(i + 1, chunks.length);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return results;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Send chunks in parallel (faster but may cause nonce issues)
|
|
51
|
+
*/
|
|
52
|
+
export async function sendChunksParallel(walletClient, chunks, options = {}) {
|
|
53
|
+
const { onProgress, encrypted = false } = options;
|
|
54
|
+
let completed = 0;
|
|
55
|
+
const promises = chunks.map(async (chunk) => {
|
|
56
|
+
const hash = await sendChunk(walletClient, chunk, encrypted);
|
|
57
|
+
completed++;
|
|
58
|
+
if (onProgress) {
|
|
59
|
+
onProgress(completed, chunks.length);
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
hash,
|
|
63
|
+
part: chunk.part,
|
|
64
|
+
total: chunk.total,
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
return Promise.all(promises);
|
|
68
|
+
}
|
|
69
|
+
// ============================================================================
|
|
70
|
+
// Utilities
|
|
71
|
+
// ============================================================================
|
|
72
|
+
function stringToHex(str) {
|
|
73
|
+
const bytes = new TextEncoder().encode(str);
|
|
74
|
+
const hex = Array.from(bytes)
|
|
75
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
76
|
+
.join('');
|
|
77
|
+
return `0x${hex}`;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=sender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sender.js","sourceRoot":"","sources":["../src/sender.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAmB3C,+EAA+E;AAC/E,SAAS;AACT,+EAA+E;AAE/E;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,YAA0B,EAC1B,KAAY,EACZ,SAAS,GAAG,KAAK;IAEjB,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IAEtC,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC;IACrC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IAED,8BAA8B;IAC9B,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,eAAe,CAAC;QAC9C,OAAO;QACP,KAAK,EAAE,YAAY,CAAC,KAAK;QACzB,EAAE,EAAE,OAAO,CAAC,OAAO;QACnB,KAAK,EAAE,EAAE;QACT,IAAI,EAAE,OAAwB;KAC/B,CAAC,CAAC;IAEH,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,YAA0B,EAC1B,MAAe,EACf,UAAuB,EAAE;IAEzB,MAAM,EAAE,UAAU,EAAE,SAAS,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAClD,MAAM,OAAO,GAAiB,EAAE,CAAC;IAEjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,YAAY,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAE7D,OAAO,CAAC,IAAI,CAAC;YACX,IAAI;YACJ,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,KAAK,EAAE,KAAK,CAAC,KAAK;SACnB,CAAC,CAAC;QAEH,IAAI,UAAU,EAAE,CAAC;YACf,UAAU,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,YAA0B,EAC1B,MAAe,EACf,UAAuB,EAAE;IAEzB,MAAM,EAAE,UAAU,EAAE,SAAS,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAClD,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC1C,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,YAAY,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAE7D,SAAS,EAAE,CAAC;QACZ,IAAI,UAAU,EAAE,CAAC;YACf,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;QAED,OAAO;YACL,IAAI;YACJ,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,KAAK,EAAE,KAAK,CAAC,KAAK;SACnB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC;AAED,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;SAC1B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SAC3C,IAAI,CAAC,EAAE,CAAC,CAAC;IACZ,OAAO,KAAK,GAAG,EAAE,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChunkTech - Transaction Tracker
|
|
3
|
+
* Monitor transaction confirmations
|
|
4
|
+
*/
|
|
5
|
+
import type { PublicClient, Hash } from 'viem';
|
|
6
|
+
import type { TxStatus, TrackerOptions } from './types.js';
|
|
7
|
+
import type { SendResult } from './sender.js';
|
|
8
|
+
/**
|
|
9
|
+
* Wait for a single transaction to be confirmed
|
|
10
|
+
*/
|
|
11
|
+
export declare function waitForTransaction(publicClient: PublicClient, hash: Hash, confirmations?: number): Promise<TxStatus>;
|
|
12
|
+
/**
|
|
13
|
+
* Wait for multiple transactions to be confirmed
|
|
14
|
+
*/
|
|
15
|
+
export declare function waitForTransactions(publicClient: PublicClient, results: SendResult[], options?: TrackerOptions): Promise<TxStatus[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Poll transaction status without blocking
|
|
18
|
+
*/
|
|
19
|
+
export declare function checkTransactionStatus(publicClient: PublicClient, hash: Hash): Promise<TxStatus>;
|
|
20
|
+
export declare class TransactionMonitor {
|
|
21
|
+
private publicClient;
|
|
22
|
+
private pending;
|
|
23
|
+
private confirmed;
|
|
24
|
+
private pollInterval;
|
|
25
|
+
private requiredConfirmations;
|
|
26
|
+
constructor(publicClient: PublicClient, options?: {
|
|
27
|
+
pollInterval?: number;
|
|
28
|
+
confirmations?: number;
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* Add transactions to monitor
|
|
32
|
+
*/
|
|
33
|
+
add(results: SendResult[]): void;
|
|
34
|
+
/**
|
|
35
|
+
* Check all pending transactions once
|
|
36
|
+
*/
|
|
37
|
+
poll(): Promise<{
|
|
38
|
+
pending: SendResult[];
|
|
39
|
+
confirmed: TxStatus[];
|
|
40
|
+
failed: TxStatus[];
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Wait for all transactions to confirm
|
|
44
|
+
*/
|
|
45
|
+
waitForAll(onStatus?: (status: TxStatus) => void, timeout?: number): Promise<TxStatus[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Get current status
|
|
48
|
+
*/
|
|
49
|
+
getStatus(): {
|
|
50
|
+
pending: number;
|
|
51
|
+
confirmed: number;
|
|
52
|
+
total: number;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Get all confirmed transactions
|
|
56
|
+
*/
|
|
57
|
+
getConfirmed(): TxStatus[];
|
|
58
|
+
/**
|
|
59
|
+
* Clear all tracking
|
|
60
|
+
*/
|
|
61
|
+
clear(): void;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../src/tracker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAM9C;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAE,IAAI,EACV,aAAa,SAAI,GAChB,OAAO,CAAC,QAAQ,CAAC,CAanB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,QAAQ,EAAE,CAAC,CAoDrB;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAE,IAAI,GACT,OAAO,CAAC,QAAQ,CAAC,CA6BnB;AAMD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,qBAAqB,CAAS;gBAGpC,YAAY,EAAE,YAAY,EAC1B,OAAO,GAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAO;IAOjE;;OAEG;IACH,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI;IAMhC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC;QACpB,OAAO,EAAE,UAAU,EAAE,CAAC;QACtB,SAAS,EAAE,QAAQ,EAAE,CAAC;QACtB,MAAM,EAAE,QAAQ,EAAE,CAAC;KACpB,CAAC;IAwBF;;OAEG;IACG,UAAU,CACd,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,KAAK,IAAI,EACrC,OAAO,SAAS,GACf,OAAO,CAAC,QAAQ,EAAE,CAAC;IA0BtB;;OAEG;IACH,SAAS,IAAI;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;KACf;IAQD;;OAEG;IACH,YAAY,IAAI,QAAQ,EAAE;IAI1B;;OAEG;IACH,KAAK,IAAI,IAAI;CAId"}
|
package/dist/tracker.js
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChunkTech - Transaction Tracker
|
|
3
|
+
* Monitor transaction confirmations
|
|
4
|
+
*/
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// Tracker
|
|
7
|
+
// ============================================================================
|
|
8
|
+
/**
|
|
9
|
+
* Wait for a single transaction to be confirmed
|
|
10
|
+
*/
|
|
11
|
+
export async function waitForTransaction(publicClient, hash, confirmations = 1) {
|
|
12
|
+
const receipt = await publicClient.waitForTransactionReceipt({
|
|
13
|
+
hash,
|
|
14
|
+
confirmations,
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
hash,
|
|
18
|
+
part: 0, // Will be set by caller if needed
|
|
19
|
+
status: receipt.status === 'success' ? 'confirmed' : 'failed',
|
|
20
|
+
blockNumber: receipt.blockNumber,
|
|
21
|
+
confirmations,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Wait for multiple transactions to be confirmed
|
|
26
|
+
*/
|
|
27
|
+
export async function waitForTransactions(publicClient, results, options = {}) {
|
|
28
|
+
const { confirmations = 1, onStatus, timeout = 300000, } = options;
|
|
29
|
+
const startTime = Date.now();
|
|
30
|
+
const statuses = [];
|
|
31
|
+
for (const result of results) {
|
|
32
|
+
// Check timeout
|
|
33
|
+
if (Date.now() - startTime > timeout) {
|
|
34
|
+
throw new Error('Transaction confirmation timeout');
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const receipt = await publicClient.waitForTransactionReceipt({
|
|
38
|
+
hash: result.hash,
|
|
39
|
+
confirmations,
|
|
40
|
+
timeout,
|
|
41
|
+
});
|
|
42
|
+
const status = {
|
|
43
|
+
hash: result.hash,
|
|
44
|
+
part: result.part,
|
|
45
|
+
status: receipt.status === 'success' ? 'confirmed' : 'failed',
|
|
46
|
+
blockNumber: receipt.blockNumber,
|
|
47
|
+
confirmations,
|
|
48
|
+
};
|
|
49
|
+
statuses.push(status);
|
|
50
|
+
if (onStatus) {
|
|
51
|
+
onStatus(status);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
const status = {
|
|
56
|
+
hash: result.hash,
|
|
57
|
+
part: result.part,
|
|
58
|
+
status: 'failed',
|
|
59
|
+
};
|
|
60
|
+
statuses.push(status);
|
|
61
|
+
if (onStatus) {
|
|
62
|
+
onStatus(status);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return statuses;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Poll transaction status without blocking
|
|
70
|
+
*/
|
|
71
|
+
export async function checkTransactionStatus(publicClient, hash) {
|
|
72
|
+
try {
|
|
73
|
+
const receipt = await publicClient.getTransactionReceipt({ hash });
|
|
74
|
+
if (receipt) {
|
|
75
|
+
const currentBlock = await publicClient.getBlockNumber();
|
|
76
|
+
const confirmations = Number(currentBlock - receipt.blockNumber);
|
|
77
|
+
return {
|
|
78
|
+
hash,
|
|
79
|
+
part: 0,
|
|
80
|
+
status: receipt.status === 'success' ? 'confirmed' : 'failed',
|
|
81
|
+
blockNumber: receipt.blockNumber,
|
|
82
|
+
confirmations,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
hash,
|
|
87
|
+
part: 0,
|
|
88
|
+
status: 'pending',
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return {
|
|
93
|
+
hash,
|
|
94
|
+
part: 0,
|
|
95
|
+
status: 'pending',
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// ============================================================================
|
|
100
|
+
// Transaction Monitor
|
|
101
|
+
// ============================================================================
|
|
102
|
+
export class TransactionMonitor {
|
|
103
|
+
publicClient;
|
|
104
|
+
pending = new Map();
|
|
105
|
+
confirmed = new Map();
|
|
106
|
+
pollInterval;
|
|
107
|
+
requiredConfirmations;
|
|
108
|
+
constructor(publicClient, options = {}) {
|
|
109
|
+
this.publicClient = publicClient;
|
|
110
|
+
this.pollInterval = options.pollInterval || 2000;
|
|
111
|
+
this.requiredConfirmations = options.confirmations || 1;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Add transactions to monitor
|
|
115
|
+
*/
|
|
116
|
+
add(results) {
|
|
117
|
+
for (const result of results) {
|
|
118
|
+
this.pending.set(result.hash, result);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Check all pending transactions once
|
|
123
|
+
*/
|
|
124
|
+
async poll() {
|
|
125
|
+
const pending = [];
|
|
126
|
+
const confirmed = [];
|
|
127
|
+
const failed = [];
|
|
128
|
+
for (const [hash, result] of this.pending) {
|
|
129
|
+
const status = await checkTransactionStatus(this.publicClient, hash);
|
|
130
|
+
status.part = result.part;
|
|
131
|
+
if (status.status === 'confirmed' && (status.confirmations || 0) >= this.requiredConfirmations) {
|
|
132
|
+
this.pending.delete(hash);
|
|
133
|
+
this.confirmed.set(hash, status);
|
|
134
|
+
confirmed.push(status);
|
|
135
|
+
}
|
|
136
|
+
else if (status.status === 'failed') {
|
|
137
|
+
this.pending.delete(hash);
|
|
138
|
+
failed.push(status);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
pending.push(result);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return { pending, confirmed, failed };
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Wait for all transactions to confirm
|
|
148
|
+
*/
|
|
149
|
+
async waitForAll(onStatus, timeout = 300000) {
|
|
150
|
+
const startTime = Date.now();
|
|
151
|
+
const results = [];
|
|
152
|
+
while (this.pending.size > 0) {
|
|
153
|
+
if (Date.now() - startTime > timeout) {
|
|
154
|
+
throw new Error('Transaction confirmation timeout');
|
|
155
|
+
}
|
|
156
|
+
const { confirmed, failed } = await this.poll();
|
|
157
|
+
for (const status of [...confirmed, ...failed]) {
|
|
158
|
+
results.push(status);
|
|
159
|
+
if (onStatus) {
|
|
160
|
+
onStatus(status);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (this.pending.size > 0) {
|
|
164
|
+
await sleep(this.pollInterval);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return results;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get current status
|
|
171
|
+
*/
|
|
172
|
+
getStatus() {
|
|
173
|
+
return {
|
|
174
|
+
pending: this.pending.size,
|
|
175
|
+
confirmed: this.confirmed.size,
|
|
176
|
+
total: this.pending.size + this.confirmed.size,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Get all confirmed transactions
|
|
181
|
+
*/
|
|
182
|
+
getConfirmed() {
|
|
183
|
+
return Array.from(this.confirmed.values());
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Clear all tracking
|
|
187
|
+
*/
|
|
188
|
+
clear() {
|
|
189
|
+
this.pending.clear();
|
|
190
|
+
this.confirmed.clear();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// ============================================================================
|
|
194
|
+
// Utilities
|
|
195
|
+
// ============================================================================
|
|
196
|
+
function sleep(ms) {
|
|
197
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracker.js","sourceRoot":"","sources":["../src/tracker.ts"],"names":[],"mappings":"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"}
|