@economicagents/graph 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.
@@ -0,0 +1,329 @@
1
+ /**
2
+ * Query helpers for analytics, credit scoring, and recommendations.
3
+ */
4
+ import { getDatabase } from "./store.js";
5
+ /** Blocks per period (Base ~2s/block). 7d, 30d, 90d. */
6
+ const BLOCKS_PER_PERIOD = {
7
+ "7d": 302_400,
8
+ "30d": 1_296_000,
9
+ "90d": 3_888_000,
10
+ };
11
+ function getMaxBlock(db) {
12
+ const row = db.prepare("SELECT MAX(blockNumber) as maxBlock FROM payments").get();
13
+ return row?.maxBlock ?? 0;
14
+ }
15
+ export function getBlockRangeForPeriod(graphPath, period) {
16
+ const blocks = BLOCKS_PER_PERIOD[period];
17
+ if (!blocks)
18
+ return null;
19
+ const db = getDatabase(graphPath);
20
+ const maxBlock = getMaxBlock(db);
21
+ return { fromBlock: Math.max(0, maxBlock - blocks), toBlock: maxBlock };
22
+ }
23
+ export function getPaymentsFrom(db, address) {
24
+ const rows = db
25
+ .prepare("SELECT fromAddr, toAddr, amount, token, blockNumber, source FROM payments WHERE fromAddr = ? ORDER BY blockNumber")
26
+ .all(address.toLowerCase());
27
+ return rows;
28
+ }
29
+ export function getPaymentsTo(db, address) {
30
+ const rows = db
31
+ .prepare("SELECT fromAddr, toAddr, amount, token, blockNumber, source FROM payments WHERE toAddr = ? ORDER BY blockNumber")
32
+ .all(address.toLowerCase());
33
+ return rows;
34
+ }
35
+ export function getAccountAnalytics(graphPath, address) {
36
+ const db = getDatabase(graphPath);
37
+ const addr = address.toLowerCase();
38
+ const outflows = db
39
+ .prepare("SELECT amount, source FROM payments WHERE fromAddr = ?")
40
+ .all(addr);
41
+ const inflows = db
42
+ .prepare("SELECT amount, source FROM payments WHERE toAddr = ?")
43
+ .all(addr);
44
+ const totalOutflow = outflows.reduce((sum, r) => sum + BigInt(r.amount), 0n);
45
+ const totalInflow = inflows.reduce((sum, r) => sum + BigInt(r.amount), 0n);
46
+ const netPnl = totalInflow - totalOutflow;
47
+ const toAddrs = db
48
+ .prepare("SELECT toAddr FROM payments WHERE fromAddr = ?")
49
+ .all(addr);
50
+ const fromAddrs = db
51
+ .prepare("SELECT fromAddr FROM payments WHERE toAddr = ?")
52
+ .all(addr);
53
+ const uniqueCounterparties = new Set([
54
+ ...toAddrs.map((r) => r.toAddr),
55
+ ...fromAddrs.map((r) => r.fromAddr),
56
+ ]).size;
57
+ const creditDraws = inflows.filter((r) => r.source === "credit_draw").length;
58
+ const creditRepays = outflows.filter((r) => r.source === "credit_repay").length;
59
+ const defaultCount = 0;
60
+ const slaBreachRows = db
61
+ .prepare("SELECT COUNT(*) as cnt FROM sla_events WHERE eventType = 'breach_declared' AND provider = ?")
62
+ .get(addr);
63
+ const slaBreaches = slaBreachRows?.cnt ?? 0;
64
+ const userOps = db
65
+ .prepare("SELECT success FROM user_ops WHERE sender = ?")
66
+ .all(addr);
67
+ const successCount = userOps.filter((r) => r.success === 1).length;
68
+ const successRate = userOps.length > 0 ? successCount / userOps.length : 1;
69
+ return {
70
+ address: addr,
71
+ totalOutflow: totalOutflow.toString(),
72
+ totalInflow: totalInflow.toString(),
73
+ netPnl: netPnl.toString(),
74
+ paymentCount: outflows.length + inflows.length,
75
+ uniqueCounterparties,
76
+ creditDraws,
77
+ creditRepays,
78
+ defaults: defaultCount,
79
+ slaBreaches,
80
+ successRate,
81
+ };
82
+ }
83
+ export function computeCreditScore(graphPath, address) {
84
+ const db = getDatabase(graphPath);
85
+ const addr = address.toLowerCase();
86
+ const outflows = getPaymentsFrom(db, addr);
87
+ const inflows = getPaymentsTo(db, addr);
88
+ const totalOut = outflows.reduce((s, r) => s + BigInt(r.amount), 0n);
89
+ const totalIn = inflows.reduce((s, r) => s + BigInt(r.amount), 0n);
90
+ const defaults = 0;
91
+ const slaBreachRows = db
92
+ .prepare("SELECT COUNT(*) as cnt FROM sla_events WHERE eventType = 'breach_declared' AND provider = ?")
93
+ .get(addr);
94
+ const slaBreaches = slaBreachRows?.cnt ?? 0;
95
+ const paymentConsistency = outflows.length >= 3 ? Math.min(1, outflows.length / 10) : 0.3;
96
+ const revenueStability = totalIn > 0n
97
+ ? Number(Math.min(1, Number(totalIn) / 1e12))
98
+ : 0.2;
99
+ const relationshipStability = new Set([...outflows.map((r) => r.toAddr), ...inflows.map((r) => r.fromAddr)])
100
+ .size >= 2
101
+ ? 0.8
102
+ : 0.4;
103
+ const defaultHistory = defaults === 0 ? 1 : Math.max(0, 1 - defaults * 0.3);
104
+ const slaBreachHistory = slaBreaches === 0 ? 1 : Math.max(0, 1 - slaBreaches * 0.3);
105
+ const score = paymentConsistency * 0.2 +
106
+ revenueStability * 0.2 +
107
+ relationshipStability * 0.2 +
108
+ defaultHistory * 0.2 +
109
+ slaBreachHistory * 0.2;
110
+ return {
111
+ score: Math.min(1, Math.max(0, score)),
112
+ factors: {
113
+ paymentConsistency,
114
+ revenueStability,
115
+ relationshipStability,
116
+ defaultHistory,
117
+ slaBreachHistory,
118
+ },
119
+ };
120
+ }
121
+ export function computeCreditScoreInRange(graphPath, address, fromBlock, toBlock) {
122
+ const db = getDatabase(graphPath);
123
+ const addr = address.toLowerCase();
124
+ const outflows = db
125
+ .prepare("SELECT fromAddr, toAddr, amount, token, blockNumber, source FROM payments WHERE fromAddr = ? AND blockNumber >= ? AND blockNumber <= ? ORDER BY blockNumber")
126
+ .all(addr, fromBlock, toBlock);
127
+ const inflows = db
128
+ .prepare("SELECT fromAddr, toAddr, amount, token, blockNumber, source FROM payments WHERE toAddr = ? AND blockNumber >= ? AND blockNumber <= ? ORDER BY blockNumber")
129
+ .all(addr, fromBlock, toBlock);
130
+ const totalOut = outflows.reduce((s, r) => s + BigInt(r.amount), 0n);
131
+ const totalIn = inflows.reduce((s, r) => s + BigInt(r.amount), 0n);
132
+ const defaults = 0;
133
+ const slaBreachRows = db
134
+ .prepare(`SELECT COUNT(*) as cnt FROM sla_events WHERE eventType = 'breach_declared' AND provider = ?
135
+ AND blockNumber >= ? AND blockNumber <= ?`)
136
+ .get(addr, fromBlock, toBlock);
137
+ const slaBreaches = slaBreachRows?.cnt ?? 0;
138
+ const paymentConsistency = outflows.length >= 3 ? Math.min(1, outflows.length / 10) : 0.3;
139
+ const revenueStability = totalIn > 0n
140
+ ? Number(Math.min(1, Number(totalIn) / 1e12))
141
+ : 0.2;
142
+ const relationshipStability = new Set([...outflows.map((r) => r.toAddr), ...inflows.map((r) => r.fromAddr)])
143
+ .size >= 2
144
+ ? 0.8
145
+ : 0.4;
146
+ const defaultHistory = defaults === 0 ? 1 : Math.max(0, 1 - defaults * 0.3);
147
+ const slaBreachHistory = slaBreaches === 0 ? 1 : Math.max(0, 1 - slaBreaches * 0.3);
148
+ const score = paymentConsistency * 0.2 +
149
+ revenueStability * 0.2 +
150
+ relationshipStability * 0.2 +
151
+ defaultHistory * 0.2 +
152
+ slaBreachHistory * 0.2;
153
+ return {
154
+ score: Math.min(1, Math.max(0, score)),
155
+ factors: {
156
+ paymentConsistency,
157
+ revenueStability,
158
+ relationshipStability,
159
+ defaultHistory,
160
+ slaBreachHistory,
161
+ },
162
+ };
163
+ }
164
+ export function getAccountAnalyticsInRange(graphPath, address, fromBlock, toBlock) {
165
+ const db = getDatabase(graphPath);
166
+ const addr = address.toLowerCase();
167
+ const outflows = db
168
+ .prepare("SELECT amount, source FROM payments WHERE fromAddr = ? AND blockNumber >= ? AND blockNumber <= ?")
169
+ .all(addr, fromBlock, toBlock);
170
+ const inflows = db
171
+ .prepare("SELECT amount, source FROM payments WHERE toAddr = ? AND blockNumber >= ? AND blockNumber <= ?")
172
+ .all(addr, fromBlock, toBlock);
173
+ const totalOutflow = outflows.reduce((sum, r) => sum + BigInt(r.amount), 0n);
174
+ const totalInflow = inflows.reduce((sum, r) => sum + BigInt(r.amount), 0n);
175
+ const netPnl = totalInflow - totalOutflow;
176
+ const toAddrs = db
177
+ .prepare("SELECT toAddr FROM payments WHERE fromAddr = ? AND blockNumber >= ? AND blockNumber <= ?")
178
+ .all(addr, fromBlock, toBlock);
179
+ const fromAddrs = db
180
+ .prepare("SELECT fromAddr FROM payments WHERE toAddr = ? AND blockNumber >= ? AND blockNumber <= ?")
181
+ .all(addr, fromBlock, toBlock);
182
+ const uniqueCounterparties = new Set([
183
+ ...toAddrs.map((r) => r.toAddr),
184
+ ...fromAddrs.map((r) => r.fromAddr),
185
+ ]).size;
186
+ const creditDraws = inflows.filter((r) => r.source === "credit_draw").length;
187
+ const creditRepays = outflows.filter((r) => r.source === "credit_repay").length;
188
+ const slaBreachRows = db
189
+ .prepare(`SELECT COUNT(*) as cnt FROM sla_events WHERE eventType = 'breach_declared' AND provider = ?
190
+ AND blockNumber >= ? AND blockNumber <= ?`)
191
+ .get(addr, fromBlock, toBlock);
192
+ const slaBreaches = slaBreachRows?.cnt ?? 0;
193
+ const userOps = db
194
+ .prepare("SELECT success FROM user_ops WHERE sender = ? AND blockNumber >= ? AND blockNumber <= ?")
195
+ .all(addr, fromBlock, toBlock);
196
+ const successCount = userOps.filter((r) => r.success === 1).length;
197
+ const successRate = userOps.length > 0 ? successCount / userOps.length : 1;
198
+ return {
199
+ address: addr,
200
+ totalOutflow: totalOutflow.toString(),
201
+ totalInflow: totalInflow.toString(),
202
+ netPnl: netPnl.toString(),
203
+ paymentCount: outflows.length + inflows.length,
204
+ uniqueCounterparties,
205
+ creditDraws,
206
+ creditRepays,
207
+ defaults: 0,
208
+ slaBreaches,
209
+ successRate,
210
+ };
211
+ }
212
+ /** Rolling spend/revenue trends. Groups by block bucket (~1 day = 43200 blocks on Base). */
213
+ export function getPaymentTrends(graphPath, address, period) {
214
+ const db = getDatabase(graphPath);
215
+ const addr = address.toLowerCase();
216
+ const maxBlock = getMaxBlock(db);
217
+ const blocks = BLOCKS_PER_PERIOD[period] ?? BLOCKS_PER_PERIOD["30d"];
218
+ const fromBlock = Math.max(0, maxBlock - blocks);
219
+ const BUCKET_SIZE = 43_200;
220
+ const outflows = db
221
+ .prepare(`SELECT blockNumber, amount FROM payments WHERE fromAddr = ? AND blockNumber >= ? AND blockNumber <= ?`)
222
+ .all(addr, fromBlock, maxBlock);
223
+ const inflows = db
224
+ .prepare(`SELECT blockNumber, amount FROM payments WHERE toAddr = ? AND blockNumber >= ? AND blockNumber <= ?`)
225
+ .all(addr, fromBlock, maxBlock);
226
+ const bucketOut = new Map();
227
+ const bucketIn = new Map();
228
+ const bucketCount = new Map();
229
+ for (const r of outflows) {
230
+ const b = Math.floor(r.blockNumber / BUCKET_SIZE) * BUCKET_SIZE;
231
+ bucketOut.set(b, (bucketOut.get(b) ?? 0n) + BigInt(r.amount));
232
+ bucketCount.set(b, (bucketCount.get(b) ?? 0) + 1);
233
+ }
234
+ for (const r of inflows) {
235
+ const b = Math.floor(r.blockNumber / BUCKET_SIZE) * BUCKET_SIZE;
236
+ bucketIn.set(b, (bucketIn.get(b) ?? 0n) + BigInt(r.amount));
237
+ bucketCount.set(b, (bucketCount.get(b) ?? 0) + 1);
238
+ }
239
+ const allBuckets = new Set([...bucketOut.keys(), ...bucketIn.keys()]);
240
+ return Array.from(allBuckets)
241
+ .sort((a, b) => a - b)
242
+ .map((blockBucket) => {
243
+ const out = bucketOut.get(blockBucket) ?? 0n;
244
+ const in_ = bucketIn.get(blockBucket) ?? 0n;
245
+ return {
246
+ blockBucket,
247
+ outflow: out.toString(),
248
+ inflow: in_.toString(),
249
+ net: (in_ - out).toString(),
250
+ paymentCount: bucketCount.get(blockBucket) ?? 0,
251
+ };
252
+ });
253
+ }
254
+ export function exportPaymentsCsv(graphPath, address, fromBlock, toBlock) {
255
+ const db = getDatabase(graphPath);
256
+ const addr = address.toLowerCase();
257
+ let sql = "SELECT fromAddr, toAddr, amount, token, blockNumber, txHash, source FROM payments WHERE (fromAddr = ? OR toAddr = ?)";
258
+ const args = [addr, addr];
259
+ if (fromBlock != null) {
260
+ sql += " AND blockNumber >= ?";
261
+ args.push(fromBlock);
262
+ }
263
+ if (toBlock != null) {
264
+ sql += " AND blockNumber <= ?";
265
+ args.push(toBlock);
266
+ }
267
+ sql += " ORDER BY blockNumber";
268
+ const rows = db.prepare(sql).all(...args);
269
+ function csvEscape(val) {
270
+ const s = String(val);
271
+ if (s.includes(",") || s.includes('"') || s.includes("\n") || s.includes("\r")) {
272
+ return `"${s.replace(/"/g, '""')}"`;
273
+ }
274
+ return s;
275
+ }
276
+ const header = "fromAddr,toAddr,amount,token,blockNumber,txHash,source";
277
+ const lines = rows.map((r) => `${csvEscape(r.fromAddr)},${csvEscape(r.toAddr)},${csvEscape(r.amount)},${csvEscape(r.token)},${csvEscape(r.blockNumber)},${csvEscape(r.txHash)},${csvEscape(r.source)}`);
278
+ return [header, ...lines].join("\n");
279
+ }
280
+ export function getFleetSummary(graphPath, accountAddresses) {
281
+ const db = getDatabase(graphPath);
282
+ const normalized = accountAddresses.map((a) => a.toLowerCase());
283
+ let totalOutflow = 0n;
284
+ let totalInflow = 0n;
285
+ let paymentCount = 0;
286
+ const allCounterparties = new Set();
287
+ const accounts = [];
288
+ for (const addr of normalized) {
289
+ const analytics = getAccountAnalytics(graphPath, addr);
290
+ if (analytics) {
291
+ totalOutflow += BigInt(analytics.totalOutflow);
292
+ totalInflow += BigInt(analytics.totalInflow);
293
+ paymentCount += analytics.paymentCount;
294
+ const outflows = db
295
+ .prepare("SELECT toAddr FROM payments WHERE fromAddr = ?")
296
+ .all(addr);
297
+ const inflows = db
298
+ .prepare("SELECT fromAddr FROM payments WHERE toAddr = ?")
299
+ .all(addr);
300
+ outflows.forEach((r) => allCounterparties.add(r.toAddr));
301
+ inflows.forEach((r) => allCounterparties.add(r.fromAddr));
302
+ accounts.push({
303
+ address: addr,
304
+ totalOutflow: analytics.totalOutflow,
305
+ totalInflow: analytics.totalInflow,
306
+ netPnl: analytics.netPnl,
307
+ paymentCount: analytics.paymentCount,
308
+ });
309
+ }
310
+ else {
311
+ accounts.push({
312
+ address: addr,
313
+ totalOutflow: "0",
314
+ totalInflow: "0",
315
+ netPnl: "0",
316
+ paymentCount: 0,
317
+ });
318
+ }
319
+ }
320
+ return {
321
+ accountCount: accounts.length,
322
+ totalOutflow: totalOutflow.toString(),
323
+ totalInflow: totalInflow.toString(),
324
+ netPnl: (totalInflow - totalOutflow).toString(),
325
+ paymentCount,
326
+ uniqueCounterparties: allCounterparties.size,
327
+ accounts,
328
+ };
329
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Recommendation engine: collaborative filtering for agent services.
3
+ * "Agents like yours also used provider X for task Y."
4
+ * Providers are passed in to avoid graph depending on indexer (breaks cycle).
5
+ */
6
+ export interface ProviderInfo {
7
+ agentId: bigint;
8
+ paymentWallet?: string;
9
+ x402Support: boolean;
10
+ services: Array<{
11
+ name?: string;
12
+ }>;
13
+ name?: string;
14
+ description?: string;
15
+ }
16
+ export interface ProviderRecommendation {
17
+ agentId: bigint;
18
+ paymentWallet: string;
19
+ name?: string;
20
+ description?: string;
21
+ score: number;
22
+ paymentCount: number;
23
+ }
24
+ /**
25
+ * Get provider recommendations for an account based on collaborative filtering.
26
+ * Finds agents that paid similar providers, then recommends providers those agents used.
27
+ * @param providers - Provider list (e.g. from loadProviders(indexPath))
28
+ */
29
+ export declare function getRecommendations(graphPath: string, providers: ProviderInfo[], accountAddress: string, capability?: string, limit?: number): ProviderRecommendation[];
30
+ //# sourceMappingURL=recommendations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommendations.d.ts","sourceRoot":"","sources":["../src/recommendations.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,YAAY,EAAE,EACzB,cAAc,EAAE,MAAM,EACtB,UAAU,CAAC,EAAE,MAAM,EACnB,KAAK,SAAI,GACR,sBAAsB,EAAE,CAmE1B"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Recommendation engine: collaborative filtering for agent services.
3
+ * "Agents like yours also used provider X for task Y."
4
+ * Providers are passed in to avoid graph depending on indexer (breaks cycle).
5
+ */
6
+ import { getDatabase } from "./store.js";
7
+ /**
8
+ * Get provider recommendations for an account based on collaborative filtering.
9
+ * Finds agents that paid similar providers, then recommends providers those agents used.
10
+ * @param providers - Provider list (e.g. from loadProviders(indexPath))
11
+ */
12
+ export function getRecommendations(graphPath, providers, accountAddress, capability, limit = 5) {
13
+ const db = getDatabase(graphPath);
14
+ const addr = accountAddress.toLowerCase();
15
+ const paymentWalletToProvider = new Map();
16
+ for (const p of providers) {
17
+ if (p.paymentWallet && p.x402Support) {
18
+ paymentWalletToProvider.set(p.paymentWallet.toLowerCase(), p);
19
+ }
20
+ }
21
+ const paidByAccount = db
22
+ .prepare("SELECT toAddr FROM payments WHERE fromAddr = ?")
23
+ .all(addr);
24
+ const accountPaidTo = new Set(paidByAccount.map((r) => r.toAddr));
25
+ const similarAgents = new Map();
26
+ for (const payee of accountPaidTo) {
27
+ const payers = db
28
+ .prepare("SELECT fromAddr FROM payments WHERE toAddr = ? AND fromAddr != ?")
29
+ .all(payee, addr);
30
+ for (const r of payers) {
31
+ similarAgents.set(r.fromAddr, (similarAgents.get(r.fromAddr) ?? 0) + 1);
32
+ }
33
+ }
34
+ const providerScores = new Map();
35
+ for (const [agent, _weight] of similarAgents) {
36
+ const paidTo = db
37
+ .prepare("SELECT toAddr FROM payments WHERE fromAddr = ?")
38
+ .all(agent);
39
+ for (const r of paidTo) {
40
+ if (!accountPaidTo.has(r.toAddr)) {
41
+ const key = r.toAddr;
42
+ const existing = providerScores.get(key) ?? {
43
+ count: 0,
44
+ agents: new Set(),
45
+ };
46
+ existing.count += similarAgents.get(agent) ?? 1;
47
+ existing.agents.add(agent);
48
+ providerScores.set(key, existing);
49
+ }
50
+ }
51
+ }
52
+ const results = [];
53
+ for (const [paymentWallet, { count, agents }] of providerScores) {
54
+ const provider = paymentWalletToProvider.get(paymentWallet);
55
+ if (!provider)
56
+ continue;
57
+ if (capability && !provider.services.some((s) => s.name?.toLowerCase().includes(capability.toLowerCase()))) {
58
+ continue;
59
+ }
60
+ results.push({
61
+ agentId: provider.agentId,
62
+ paymentWallet,
63
+ name: provider.name,
64
+ description: provider.description,
65
+ score: count / (agents.size + 1),
66
+ paymentCount: count,
67
+ });
68
+ }
69
+ results.sort((a, b) => b.score - a.score);
70
+ return results.slice(0, limit);
71
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * SQLite store for economic graph. Uses better-sqlite3 (optional dependency).
3
+ * Falls back to sql.js (pure JS) when better-sqlite3 native bindings are unavailable.
4
+ */
5
+ export type SqliteDb = {
6
+ exec: (sql: string) => void;
7
+ prepare: (sql: string) => {
8
+ run: (...args: unknown[]) => {
9
+ changes: number;
10
+ };
11
+ get: (...args: unknown[]) => unknown;
12
+ all: (...args: unknown[]) => unknown[];
13
+ };
14
+ close: () => void;
15
+ };
16
+ /** sql.js native Database shape (run/exec/prepare/close) — differs from SqliteDb. */
17
+ type SqlJsNativeDb = {
18
+ run: (sql: string, params?: unknown[]) => void;
19
+ exec: (sql: string) => void;
20
+ prepare: (sql: string) => {
21
+ bind: (params: unknown[]) => void;
22
+ step: () => boolean;
23
+ getAsObject: () => Record<string, unknown>;
24
+ free: () => void;
25
+ };
26
+ close: () => void;
27
+ };
28
+ /** For tests: set sql.js as fallback when better-sqlite3 native bindings are unavailable. */
29
+ export declare function setSqlJsFallback(SQL: {
30
+ Database: new () => SqlJsNativeDb;
31
+ }): void;
32
+ /** Exported for tests: true when better-sqlite3 (disk persistence) is active; false when using sql.js fallback. */
33
+ export declare function isUsingBetterSqlite3(): boolean;
34
+ /** Exported for tests: whether SQLite (better-sqlite3 or sql.js fallback) is available. */
35
+ export declare function isSqliteAvailable(): boolean;
36
+ export declare function ensureGraphDir(graphPath: string): void;
37
+ export declare function getDatabase(graphPath: string): SqliteDb;
38
+ export declare function closeDatabase(): void;
39
+ export declare function insertAccount(database: SqliteDb, address: string, owner: string, firstSeenBlock: number): void;
40
+ export declare function insertPayment(database: SqliteDb, fromAddr: string, toAddr: string, amount: string, token: string, blockNumber: number, txHash: string, logIndex: number | null, source: string): void;
41
+ export declare function insertUserOp(database: SqliteDb, userOpHash: string, sender: string, success: boolean, actualGasCost: string | null, blockNumber: number | null, txHash: string | null): void;
42
+ export declare function insertFacility(database: SqliteDb, address: string, lender: string, borrower: string, firstSeenBlock: number): void;
43
+ export declare function insertEscrow(database: SqliteDb, address: string, consumer: string, provider: string, firstSeenBlock: number): void;
44
+ export declare function insertSplitter(database: SqliteDb, address: string, token: string, firstSeenBlock: number): void;
45
+ export declare function insertSLA(database: SqliteDb, address: string, provider: string, consumer: string, firstSeenBlock: number): void;
46
+ export declare function getSyncState(database: SqliteDb, key: string): number | null;
47
+ export declare function setSyncState(database: SqliteDb, key: string, lastBlock: number): void;
48
+ export declare function getAccountAddresses(database: SqliteDb): string[];
49
+ export declare function getFacilityAddresses(database: SqliteDb): string[];
50
+ export declare function getEscrowAddresses(database: SqliteDb): string[];
51
+ export declare function getSplitterAddresses(database: SqliteDb): string[];
52
+ export declare function getSLAAddresses(database: SqliteDb): string[];
53
+ export declare function insertSLAEvent(database: SqliteDb, slaAddress: string, eventType: string, provider: string, consumer: string | null, amount: string | null, requestHash: string | null, blockNumber: number, txHash: string): void;
54
+ export {};
55
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}