@oobe-protocol-labs/synapse-sap-sdk 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/LICENSE +21 -0
- package/README.md +882 -0
- package/dist/cjs/constants/index.js +43 -0
- package/dist/cjs/constants/index.js.map +1 -0
- package/dist/cjs/constants/limits.js +161 -0
- package/dist/cjs/constants/limits.js.map +1 -0
- package/dist/cjs/constants/programs.js +78 -0
- package/dist/cjs/constants/programs.js.map +1 -0
- package/dist/cjs/constants/seeds.js +57 -0
- package/dist/cjs/constants/seeds.js.map +1 -0
- package/dist/cjs/core/client.js +391 -0
- package/dist/cjs/core/client.js.map +1 -0
- package/dist/cjs/core/connection.js +319 -0
- package/dist/cjs/core/connection.js.map +1 -0
- package/dist/cjs/core/index.js +24 -0
- package/dist/cjs/core/index.js.map +1 -0
- package/dist/cjs/errors/index.js +334 -0
- package/dist/cjs/errors/index.js.map +1 -0
- package/dist/cjs/events/index.js +136 -0
- package/dist/cjs/events/index.js.map +1 -0
- package/dist/cjs/idl/index.js +63 -0
- package/dist/cjs/idl/index.js.map +1 -0
- package/dist/cjs/idl/synapse_agent_sap.json +9710 -0
- package/dist/cjs/index.js +147 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/modules/agent.js +272 -0
- package/dist/cjs/modules/agent.js.map +1 -0
- package/dist/cjs/modules/attestation.js +147 -0
- package/dist/cjs/modules/attestation.js.map +1 -0
- package/dist/cjs/modules/base.js +128 -0
- package/dist/cjs/modules/base.js.map +1 -0
- package/dist/cjs/modules/escrow.js +246 -0
- package/dist/cjs/modules/escrow.js.map +1 -0
- package/dist/cjs/modules/feedback.js +166 -0
- package/dist/cjs/modules/feedback.js.map +1 -0
- package/dist/cjs/modules/index.js +35 -0
- package/dist/cjs/modules/index.js.map +1 -0
- package/dist/cjs/modules/indexing.js +375 -0
- package/dist/cjs/modules/indexing.js.map +1 -0
- package/dist/cjs/modules/ledger.js +234 -0
- package/dist/cjs/modules/ledger.js.map +1 -0
- package/dist/cjs/modules/tools.js +319 -0
- package/dist/cjs/modules/tools.js.map +1 -0
- package/dist/cjs/modules/vault.js +410 -0
- package/dist/cjs/modules/vault.js.map +1 -0
- package/dist/cjs/pda/index.js +377 -0
- package/dist/cjs/pda/index.js.map +1 -0
- package/dist/cjs/plugin/index.js +934 -0
- package/dist/cjs/plugin/index.js.map +1 -0
- package/dist/cjs/plugin/protocols.js +282 -0
- package/dist/cjs/plugin/protocols.js.map +1 -0
- package/dist/cjs/plugin/schemas.js +831 -0
- package/dist/cjs/plugin/schemas.js.map +1 -0
- package/dist/cjs/postgres/adapter.js +715 -0
- package/dist/cjs/postgres/adapter.js.map +1 -0
- package/dist/cjs/postgres/index.js +50 -0
- package/dist/cjs/postgres/index.js.map +1 -0
- package/dist/cjs/postgres/serializers.js +381 -0
- package/dist/cjs/postgres/serializers.js.map +1 -0
- package/dist/cjs/postgres/sync.js +221 -0
- package/dist/cjs/postgres/sync.js.map +1 -0
- package/dist/cjs/postgres/types.js +44 -0
- package/dist/cjs/postgres/types.js.map +1 -0
- package/dist/cjs/registries/builder.js +414 -0
- package/dist/cjs/registries/builder.js.map +1 -0
- package/dist/cjs/registries/discovery.js +362 -0
- package/dist/cjs/registries/discovery.js.map +1 -0
- package/dist/cjs/registries/index.js +51 -0
- package/dist/cjs/registries/index.js.map +1 -0
- package/dist/cjs/registries/session.js +433 -0
- package/dist/cjs/registries/session.js.map +1 -0
- package/dist/cjs/registries/x402.js +577 -0
- package/dist/cjs/registries/x402.js.map +1 -0
- package/dist/cjs/types/accounts.js +13 -0
- package/dist/cjs/types/accounts.js.map +1 -0
- package/dist/cjs/types/common.js +13 -0
- package/dist/cjs/types/common.js.map +1 -0
- package/dist/cjs/types/enums.js +174 -0
- package/dist/cjs/types/enums.js.map +1 -0
- package/dist/cjs/types/index.js +36 -0
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/cjs/types/instructions.js +92 -0
- package/dist/cjs/types/instructions.js.map +1 -0
- package/dist/cjs/utils/hash.js +58 -0
- package/dist/cjs/utils/hash.js.map +1 -0
- package/dist/cjs/utils/index.js +27 -0
- package/dist/cjs/utils/index.js.map +1 -0
- package/dist/cjs/utils/serialization.js +105 -0
- package/dist/cjs/utils/serialization.js.map +1 -0
- package/dist/cjs/utils/validation.js +36 -0
- package/dist/cjs/utils/validation.js.map +1 -0
- package/dist/esm/constants/index.js +29 -0
- package/dist/esm/constants/index.js.map +1 -0
- package/dist/esm/constants/limits.js +158 -0
- package/dist/esm/constants/limits.js.map +1 -0
- package/dist/esm/constants/programs.js +75 -0
- package/dist/esm/constants/programs.js.map +1 -0
- package/dist/esm/constants/seeds.js +54 -0
- package/dist/esm/constants/seeds.js.map +1 -0
- package/dist/esm/core/client.js +384 -0
- package/dist/esm/core/client.js.map +1 -0
- package/dist/esm/core/connection.js +315 -0
- package/dist/esm/core/connection.js.map +1 -0
- package/dist/esm/core/index.js +19 -0
- package/dist/esm/core/index.js.map +1 -0
- package/dist/esm/errors/index.js +325 -0
- package/dist/esm/errors/index.js.map +1 -0
- package/dist/esm/events/index.js +132 -0
- package/dist/esm/events/index.js.map +1 -0
- package/dist/esm/idl/index.js +57 -0
- package/dist/esm/idl/index.js.map +1 -0
- package/dist/esm/idl/synapse_agent_sap.json +9710 -0
- package/dist/esm/index.js +70 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/modules/agent.js +268 -0
- package/dist/esm/modules/agent.js.map +1 -0
- package/dist/esm/modules/attestation.js +143 -0
- package/dist/esm/modules/attestation.js.map +1 -0
- package/dist/esm/modules/base.js +124 -0
- package/dist/esm/modules/base.js.map +1 -0
- package/dist/esm/modules/escrow.js +242 -0
- package/dist/esm/modules/escrow.js.map +1 -0
- package/dist/esm/modules/feedback.js +162 -0
- package/dist/esm/modules/feedback.js.map +1 -0
- package/dist/esm/modules/index.js +23 -0
- package/dist/esm/modules/index.js.map +1 -0
- package/dist/esm/modules/indexing.js +371 -0
- package/dist/esm/modules/indexing.js.map +1 -0
- package/dist/esm/modules/ledger.js +230 -0
- package/dist/esm/modules/ledger.js.map +1 -0
- package/dist/esm/modules/tools.js +315 -0
- package/dist/esm/modules/tools.js.map +1 -0
- package/dist/esm/modules/vault.js +406 -0
- package/dist/esm/modules/vault.js.map +1 -0
- package/dist/esm/pda/index.js +357 -0
- package/dist/esm/pda/index.js.map +1 -0
- package/dist/esm/plugin/index.js +927 -0
- package/dist/esm/plugin/index.js.map +1 -0
- package/dist/esm/plugin/protocols.js +279 -0
- package/dist/esm/plugin/protocols.js.map +1 -0
- package/dist/esm/plugin/schemas.js +828 -0
- package/dist/esm/plugin/schemas.js.map +1 -0
- package/dist/esm/postgres/adapter.js +678 -0
- package/dist/esm/postgres/adapter.js.map +1 -0
- package/dist/esm/postgres/index.js +27 -0
- package/dist/esm/postgres/index.js.map +1 -0
- package/dist/esm/postgres/serializers.js +362 -0
- package/dist/esm/postgres/serializers.js.map +1 -0
- package/dist/esm/postgres/sync.js +217 -0
- package/dist/esm/postgres/sync.js.map +1 -0
- package/dist/esm/postgres/types.js +41 -0
- package/dist/esm/postgres/types.js.map +1 -0
- package/dist/esm/registries/builder.js +410 -0
- package/dist/esm/registries/builder.js.map +1 -0
- package/dist/esm/registries/discovery.js +358 -0
- package/dist/esm/registries/discovery.js.map +1 -0
- package/dist/esm/registries/index.js +44 -0
- package/dist/esm/registries/index.js.map +1 -0
- package/dist/esm/registries/session.js +429 -0
- package/dist/esm/registries/session.js.map +1 -0
- package/dist/esm/registries/x402.js +573 -0
- package/dist/esm/registries/x402.js.map +1 -0
- package/dist/esm/types/accounts.js +12 -0
- package/dist/esm/types/accounts.js.map +1 -0
- package/dist/esm/types/common.js +12 -0
- package/dist/esm/types/common.js.map +1 -0
- package/dist/esm/types/enums.js +171 -0
- package/dist/esm/types/enums.js.map +1 -0
- package/dist/esm/types/index.js +25 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/esm/types/instructions.js +89 -0
- package/dist/esm/types/instructions.js.map +1 -0
- package/dist/esm/utils/hash.js +53 -0
- package/dist/esm/utils/hash.js.map +1 -0
- package/dist/esm/utils/index.js +19 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/esm/utils/serialization.js +98 -0
- package/dist/esm/utils/serialization.js.map +1 -0
- package/dist/esm/utils/validation.js +33 -0
- package/dist/esm/utils/validation.js.map +1 -0
- package/dist/types/constants/index.d.ts +27 -0
- package/dist/types/constants/index.d.ts.map +1 -0
- package/dist/types/constants/limits.d.ts +149 -0
- package/dist/types/constants/limits.d.ts.map +1 -0
- package/dist/types/constants/programs.d.ts +69 -0
- package/dist/types/constants/programs.d.ts.map +1 -0
- package/dist/types/constants/seeds.d.ts +61 -0
- package/dist/types/constants/seeds.d.ts.map +1 -0
- package/dist/types/core/client.d.ts +323 -0
- package/dist/types/core/client.d.ts.map +1 -0
- package/dist/types/core/connection.d.ts +279 -0
- package/dist/types/core/connection.d.ts.map +1 -0
- package/dist/types/core/index.d.ts +20 -0
- package/dist/types/core/index.d.ts.map +1 -0
- package/dist/types/errors/index.d.ts +276 -0
- package/dist/types/errors/index.d.ts.map +1 -0
- package/dist/types/events/index.d.ts +248 -0
- package/dist/types/events/index.d.ts.map +1 -0
- package/dist/types/idl/index.d.ts +70 -0
- package/dist/types/idl/index.d.ts.map +1 -0
- package/dist/types/index.d.ts +68 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/modules/agent.d.ts +166 -0
- package/dist/types/modules/agent.d.ts.map +1 -0
- package/dist/types/modules/attestation.d.ts +96 -0
- package/dist/types/modules/attestation.d.ts.map +1 -0
- package/dist/types/modules/base.d.ts +126 -0
- package/dist/types/modules/base.d.ts.map +1 -0
- package/dist/types/modules/escrow.d.ts +151 -0
- package/dist/types/modules/escrow.d.ts.map +1 -0
- package/dist/types/modules/feedback.d.ts +105 -0
- package/dist/types/modules/feedback.d.ts.map +1 -0
- package/dist/types/modules/index.d.ts +24 -0
- package/dist/types/modules/index.d.ts.map +1 -0
- package/dist/types/modules/indexing.d.ts +200 -0
- package/dist/types/modules/indexing.d.ts.map +1 -0
- package/dist/types/modules/ledger.d.ts +150 -0
- package/dist/types/modules/ledger.d.ts.map +1 -0
- package/dist/types/modules/tools.d.ts +182 -0
- package/dist/types/modules/tools.d.ts.map +1 -0
- package/dist/types/modules/vault.d.ts +240 -0
- package/dist/types/modules/vault.d.ts.map +1 -0
- package/dist/types/pda/index.d.ts +296 -0
- package/dist/types/pda/index.d.ts.map +1 -0
- package/dist/types/plugin/index.d.ts +171 -0
- package/dist/types/plugin/index.d.ts.map +1 -0
- package/dist/types/plugin/protocols.d.ts +152 -0
- package/dist/types/plugin/protocols.d.ts.map +1 -0
- package/dist/types/plugin/schemas.d.ts +823 -0
- package/dist/types/plugin/schemas.d.ts.map +1 -0
- package/dist/types/postgres/adapter.d.ts +355 -0
- package/dist/types/postgres/adapter.d.ts.map +1 -0
- package/dist/types/postgres/index.d.ts +24 -0
- package/dist/types/postgres/index.d.ts.map +1 -0
- package/dist/types/postgres/serializers.d.ts +30 -0
- package/dist/types/postgres/serializers.d.ts.map +1 -0
- package/dist/types/postgres/sync.d.ts +132 -0
- package/dist/types/postgres/sync.d.ts.map +1 -0
- package/dist/types/postgres/types.d.ts +167 -0
- package/dist/types/postgres/types.d.ts.map +1 -0
- package/dist/types/registries/builder.d.ts +340 -0
- package/dist/types/registries/builder.d.ts.map +1 -0
- package/dist/types/registries/discovery.d.ts +333 -0
- package/dist/types/registries/discovery.d.ts.map +1 -0
- package/dist/types/registries/index.d.ts +48 -0
- package/dist/types/registries/index.d.ts.map +1 -0
- package/dist/types/registries/session.d.ts +323 -0
- package/dist/types/registries/session.d.ts.map +1 -0
- package/dist/types/registries/x402.d.ts +463 -0
- package/dist/types/registries/x402.d.ts.map +1 -0
- package/dist/types/types/accounts.d.ts +565 -0
- package/dist/types/types/accounts.d.ts.map +1 -0
- package/dist/types/types/common.d.ts +166 -0
- package/dist/types/types/common.d.ts.map +1 -0
- package/dist/types/types/enums.d.ts +238 -0
- package/dist/types/types/enums.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +28 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/types/types/instructions.d.ts +366 -0
- package/dist/types/types/instructions.d.ts.map +1 -0
- package/dist/types/utils/hash.d.ts +48 -0
- package/dist/types/utils/hash.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +19 -0
- package/dist/types/utils/index.d.ts.map +1 -0
- package/dist/types/utils/serialization.d.ts +69 -0
- package/dist/types/utils/serialization.d.ts.map +1 -0
- package/dist/types/utils/validation.d.ts +29 -0
- package/dist/types/utils/validation.d.ts.map +1 -0
- package/package.json +178 -0
- package/src/constants/index.ts +44 -0
- package/src/constants/limits.ts +165 -0
- package/src/constants/programs.ts +83 -0
- package/src/constants/seeds.ts +66 -0
- package/src/core/client.ts +416 -0
- package/src/core/connection.ts +409 -0
- package/src/core/index.ts +20 -0
- package/src/errors/index.ts +346 -0
- package/src/events/index.ts +335 -0
- package/src/idl/index.ts +76 -0
- package/src/idl/synapse_agent_sap.json +9710 -0
- package/src/index.ts +253 -0
- package/src/modules/agent.ts +319 -0
- package/src/modules/attestation.ts +168 -0
- package/src/modules/base.ts +158 -0
- package/src/modules/escrow.ts +308 -0
- package/src/modules/feedback.ts +186 -0
- package/src/modules/index.ts +24 -0
- package/src/modules/indexing.ts +444 -0
- package/src/modules/ledger.ts +262 -0
- package/src/modules/tools.ts +411 -0
- package/src/modules/vault.ts +533 -0
- package/src/pda/index.ts +512 -0
- package/src/plugin/index.ts +1202 -0
- package/src/plugin/protocols.ts +404 -0
- package/src/plugin/schemas.ts +909 -0
- package/src/postgres/adapter.ts +904 -0
- package/src/postgres/index.ts +59 -0
- package/src/postgres/schema.sql +683 -0
- package/src/postgres/serializers.ts +485 -0
- package/src/postgres/sync.ts +254 -0
- package/src/postgres/types.ts +245 -0
- package/src/registries/builder.ts +607 -0
- package/src/registries/discovery.ts +572 -0
- package/src/registries/index.ts +77 -0
- package/src/registries/session.ts +613 -0
- package/src/registries/x402.ts +906 -0
- package/src/types/accounts.ts +618 -0
- package/src/types/common.ts +187 -0
- package/src/types/enums.ts +214 -0
- package/src/types/index.ts +92 -0
- package/src/types/instructions.ts +413 -0
- package/src/utils/hash.ts +57 -0
- package/src/utils/index.ts +19 -0
- package/src/utils/serialization.ts +98 -0
- package/src/utils/validation.ts +36 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module postgres/sync
|
|
3
|
+
* @description Real-time and scheduled sync engine for the SAP PostgreSQL
|
|
4
|
+
* adapter. Provides cron-like periodic sync and WebSocket-based
|
|
5
|
+
* live event streaming.
|
|
6
|
+
*
|
|
7
|
+
* @category Postgres
|
|
8
|
+
* @since v0.1.0
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { SapSyncEngine } from "@synapse-sap/sdk/postgres";
|
|
13
|
+
* import { SapPostgres } from "@synapse-sap/sdk/postgres";
|
|
14
|
+
* import { SapClient } from "@synapse-sap/sdk";
|
|
15
|
+
* import { Pool } from "pg";
|
|
16
|
+
*
|
|
17
|
+
* const pool = new Pool({ connectionString: "postgresql://..." });
|
|
18
|
+
* const sap = SapClient.from(provider);
|
|
19
|
+
* const pg = new SapPostgres(pool, sap);
|
|
20
|
+
* const sync = new SapSyncEngine(pg, sap);
|
|
21
|
+
*
|
|
22
|
+
* // One-shot full sync
|
|
23
|
+
* await sync.run();
|
|
24
|
+
*
|
|
25
|
+
* // Periodic sync (every 60 seconds)
|
|
26
|
+
* sync.start(60_000);
|
|
27
|
+
*
|
|
28
|
+
* // Live event streaming via WebSocket
|
|
29
|
+
* await sync.startEventStream();
|
|
30
|
+
*
|
|
31
|
+
* // Graceful shutdown
|
|
32
|
+
* await sync.stop();
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
import type { SapClient } from "../core/client";
|
|
37
|
+
import { EventParser } from "../events";
|
|
38
|
+
import type { SapPostgres, SyncAllResult } from "./adapter";
|
|
39
|
+
import type { SyncOptions } from "./types";
|
|
40
|
+
|
|
41
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
42
|
+
// Sync Engine
|
|
43
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @name SapSyncEngine
|
|
47
|
+
* @description Orchestrates periodic and real-time sync between
|
|
48
|
+
* Solana on-chain state and the PostgreSQL mirror.
|
|
49
|
+
*
|
|
50
|
+
* Two operational modes:
|
|
51
|
+
*
|
|
52
|
+
* 1. **Periodic sync** — polls all account types at a configurable
|
|
53
|
+
* interval and upserts into PostgreSQL.
|
|
54
|
+
*
|
|
55
|
+
* 2. **Event streaming** — subscribes to SAP program logs via
|
|
56
|
+
* WebSocket and inserts events in real-time.
|
|
57
|
+
*
|
|
58
|
+
* Both modes can run simultaneously.
|
|
59
|
+
*
|
|
60
|
+
* @category Postgres
|
|
61
|
+
* @since v0.1.0
|
|
62
|
+
*/
|
|
63
|
+
export class SapSyncEngine {
|
|
64
|
+
private readonly pg: SapPostgres;
|
|
65
|
+
private readonly client: SapClient;
|
|
66
|
+
private readonly debug: boolean;
|
|
67
|
+
|
|
68
|
+
private intervalId: ReturnType<typeof setInterval> | null = null;
|
|
69
|
+
private logSubId: number | null = null;
|
|
70
|
+
private running = false;
|
|
71
|
+
|
|
72
|
+
constructor(pg: SapPostgres, client: SapClient, debug = false) {
|
|
73
|
+
this.pg = pg;
|
|
74
|
+
this.client = client;
|
|
75
|
+
this.debug = debug;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// ═════════════════════════════════════════════
|
|
79
|
+
// One-shot Sync
|
|
80
|
+
// ═════════════════════════════════════════════
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @name run
|
|
84
|
+
* @description Execute a single full sync cycle.
|
|
85
|
+
* @param options - Optional sync configuration.
|
|
86
|
+
* @returns Sync result summary.
|
|
87
|
+
* @since v0.1.0
|
|
88
|
+
*/
|
|
89
|
+
async run(options?: SyncOptions): Promise<SyncAllResult> {
|
|
90
|
+
this.log("Starting one-shot sync...");
|
|
91
|
+
const result = await this.pg.syncAll(options);
|
|
92
|
+
this.log(`One-shot sync complete: ${result.totalRecords} records`);
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ═════════════════════════════════════════════
|
|
97
|
+
// Periodic Sync
|
|
98
|
+
// ═════════════════════════════════════════════
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @name start
|
|
102
|
+
* @description Start periodic sync at the given interval.
|
|
103
|
+
* Safe to call when already running — resets the interval.
|
|
104
|
+
*
|
|
105
|
+
* @param intervalMs - Sync interval in milliseconds (default: 60_000).
|
|
106
|
+
* @param options - Optional sync configuration.
|
|
107
|
+
* @since v0.1.0
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* // Sync every 30 seconds
|
|
112
|
+
* sync.start(30_000);
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
start(intervalMs = 60_000, options?: SyncOptions): void {
|
|
116
|
+
this.stopInterval();
|
|
117
|
+
this.running = true;
|
|
118
|
+
this.log(`Starting periodic sync every ${intervalMs}ms`);
|
|
119
|
+
|
|
120
|
+
// Run immediately, then repeat
|
|
121
|
+
this.pg.syncAll(options).catch((err) => this.log(`Sync error: ${err}`));
|
|
122
|
+
|
|
123
|
+
this.intervalId = setInterval(() => {
|
|
124
|
+
if (!this.running) return;
|
|
125
|
+
this.pg.syncAll(options).catch((err) => this.log(`Sync error: ${err}`));
|
|
126
|
+
}, intervalMs);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @name stop
|
|
131
|
+
* @description Stop all sync activity (periodic + event stream).
|
|
132
|
+
* @since v0.1.0
|
|
133
|
+
*/
|
|
134
|
+
async stop(): Promise<void> {
|
|
135
|
+
this.running = false;
|
|
136
|
+
this.stopInterval();
|
|
137
|
+
await this.stopEventStream();
|
|
138
|
+
this.log("Sync engine stopped");
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private stopInterval(): void {
|
|
142
|
+
if (this.intervalId) {
|
|
143
|
+
clearInterval(this.intervalId);
|
|
144
|
+
this.intervalId = null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// ═════════════════════════════════════════════
|
|
149
|
+
// Real-time Event Stream
|
|
150
|
+
// ═════════════════════════════════════════════
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* @name startEventStream
|
|
154
|
+
* @description Subscribe to SAP program logs via WebSocket and
|
|
155
|
+
* insert parsed events into the `sap_events` table in real-time.
|
|
156
|
+
*
|
|
157
|
+
* @since v0.1.0
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```ts
|
|
161
|
+
* // Start streaming events
|
|
162
|
+
* await sync.startEventStream();
|
|
163
|
+
*
|
|
164
|
+
* // Later, stop the stream
|
|
165
|
+
* await sync.stopEventStream();
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
async startEventStream(): Promise<void> {
|
|
169
|
+
if (this.logSubId !== null) {
|
|
170
|
+
this.log("Event stream already running");
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const connection = this.client.program.provider.connection;
|
|
175
|
+
const programId = this.client.program.programId;
|
|
176
|
+
const eventParser = new EventParser(this.client.program);
|
|
177
|
+
|
|
178
|
+
this.logSubId = connection.onLogs(
|
|
179
|
+
programId,
|
|
180
|
+
async (logInfo) => {
|
|
181
|
+
try {
|
|
182
|
+
const events = eventParser.parseLogs(logInfo.logs);
|
|
183
|
+
for (const event of events) {
|
|
184
|
+
const data = event.data as Record<string, unknown>;
|
|
185
|
+
const agentPda =
|
|
186
|
+
(data.agent as string) ?? (data.agentPda as string) ?? undefined;
|
|
187
|
+
const wallet =
|
|
188
|
+
(data.wallet as string) ?? (data.owner as string) ?? undefined;
|
|
189
|
+
|
|
190
|
+
await this.pg.syncEvent(
|
|
191
|
+
event.name,
|
|
192
|
+
logInfo.signature,
|
|
193
|
+
0, // slot populated from getSlot if needed
|
|
194
|
+
data,
|
|
195
|
+
agentPda,
|
|
196
|
+
wallet,
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
} catch (err) {
|
|
200
|
+
this.log(`Event parse error: ${err}`);
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
"confirmed",
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
this.log("Event stream started");
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* @name stopEventStream
|
|
211
|
+
* @description Unsubscribe from the program log stream.
|
|
212
|
+
* @since v0.1.0
|
|
213
|
+
*/
|
|
214
|
+
async stopEventStream(): Promise<void> {
|
|
215
|
+
if (this.logSubId !== null) {
|
|
216
|
+
const connection = this.client.program.provider.connection;
|
|
217
|
+
await connection.removeOnLogsListener(this.logSubId);
|
|
218
|
+
this.logSubId = null;
|
|
219
|
+
this.log("Event stream stopped");
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// ═════════════════════════════════════════════
|
|
224
|
+
// Status
|
|
225
|
+
// ═════════════════════════════════════════════
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* @name isRunning
|
|
229
|
+
* @description Check whether the periodic sync is active.
|
|
230
|
+
* @since v0.1.0
|
|
231
|
+
*/
|
|
232
|
+
isRunning(): boolean {
|
|
233
|
+
return this.running;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* @name isStreaming
|
|
238
|
+
* @description Check whether the event stream is active.
|
|
239
|
+
* @since v0.1.0
|
|
240
|
+
*/
|
|
241
|
+
isStreaming(): boolean {
|
|
242
|
+
return this.logSubId !== null;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// ═════════════════════════════════════════════
|
|
246
|
+
// Internal
|
|
247
|
+
// ═════════════════════════════════════════════
|
|
248
|
+
|
|
249
|
+
private log(msg: string): void {
|
|
250
|
+
if (this.debug) {
|
|
251
|
+
console.log(`[SapSyncEngine] ${msg}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module postgres/types
|
|
3
|
+
* @description PostgreSQL adapter type definitions for SAP v2.
|
|
4
|
+
*
|
|
5
|
+
* Defines configuration, row shapes, and query result types
|
|
6
|
+
* for the PostgreSQL off-chain mirror.
|
|
7
|
+
*
|
|
8
|
+
* @category Postgres
|
|
9
|
+
* @since v0.1.0
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
13
|
+
// Configuration
|
|
14
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @name SapPostgresConfig
|
|
18
|
+
* @description Configuration for the SAP PostgreSQL adapter.
|
|
19
|
+
* @category Postgres
|
|
20
|
+
* @since v0.1.0
|
|
21
|
+
*/
|
|
22
|
+
export interface SapPostgresConfig {
|
|
23
|
+
/**
|
|
24
|
+
* PostgreSQL connection string.
|
|
25
|
+
* @example "postgresql://user:pass@localhost:5432/sap"
|
|
26
|
+
*/
|
|
27
|
+
readonly connectionString: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Whether to automatically run schema migrations on connect.
|
|
31
|
+
* @default false
|
|
32
|
+
*/
|
|
33
|
+
readonly autoMigrate?: boolean;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Table name prefix (default: "sap_").
|
|
37
|
+
* @default "sap_"
|
|
38
|
+
*/
|
|
39
|
+
readonly tablePrefix?: string;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Enable verbose query logging.
|
|
43
|
+
* @default false
|
|
44
|
+
*/
|
|
45
|
+
readonly debug?: boolean;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
49
|
+
// Account Type Registry
|
|
50
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @name SapAccountType
|
|
54
|
+
* @description All syncable on-chain account types.
|
|
55
|
+
* @category Postgres
|
|
56
|
+
* @since v0.1.0
|
|
57
|
+
*/
|
|
58
|
+
export type SapAccountType =
|
|
59
|
+
| "global_registry"
|
|
60
|
+
| "agents"
|
|
61
|
+
| "agent_stats"
|
|
62
|
+
| "feedbacks"
|
|
63
|
+
| "capability_indexes"
|
|
64
|
+
| "protocol_indexes"
|
|
65
|
+
| "plugin_slots"
|
|
66
|
+
| "memory_entries"
|
|
67
|
+
| "memory_chunks"
|
|
68
|
+
| "memory_vaults"
|
|
69
|
+
| "sessions"
|
|
70
|
+
| "epoch_pages"
|
|
71
|
+
| "vault_delegates"
|
|
72
|
+
| "tools"
|
|
73
|
+
| "checkpoints"
|
|
74
|
+
| "escrows"
|
|
75
|
+
| "tool_category_indexes"
|
|
76
|
+
| "attestations"
|
|
77
|
+
| "memory_buffers"
|
|
78
|
+
| "memory_digests"
|
|
79
|
+
| "memory_ledgers"
|
|
80
|
+
| "ledger_pages";
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @name SapTableName
|
|
84
|
+
* @description Mapping of account types to PostgreSQL table names.
|
|
85
|
+
* @category Postgres
|
|
86
|
+
* @since v0.1.0
|
|
87
|
+
*/
|
|
88
|
+
export const SAP_TABLE_MAP: Record<SapAccountType, string> = {
|
|
89
|
+
global_registry: "sap_global_registry",
|
|
90
|
+
agents: "sap_agents",
|
|
91
|
+
agent_stats: "sap_agent_stats",
|
|
92
|
+
feedbacks: "sap_feedbacks",
|
|
93
|
+
capability_indexes: "sap_capability_indexes",
|
|
94
|
+
protocol_indexes: "sap_protocol_indexes",
|
|
95
|
+
plugin_slots: "sap_plugin_slots",
|
|
96
|
+
memory_entries: "sap_memory_entries",
|
|
97
|
+
memory_chunks: "sap_memory_chunks",
|
|
98
|
+
memory_vaults: "sap_memory_vaults",
|
|
99
|
+
sessions: "sap_sessions",
|
|
100
|
+
epoch_pages: "sap_epoch_pages",
|
|
101
|
+
vault_delegates: "sap_vault_delegates",
|
|
102
|
+
tools: "sap_tools",
|
|
103
|
+
checkpoints: "sap_checkpoints",
|
|
104
|
+
escrows: "sap_escrows",
|
|
105
|
+
tool_category_indexes: "sap_tool_category_indexes",
|
|
106
|
+
attestations: "sap_attestations",
|
|
107
|
+
memory_buffers: "sap_memory_buffers",
|
|
108
|
+
memory_digests: "sap_memory_digests",
|
|
109
|
+
memory_ledgers: "sap_memory_ledgers",
|
|
110
|
+
ledger_pages: "sap_ledger_pages",
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
114
|
+
// Row Types (PostgreSQL ↔ TypeScript)
|
|
115
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
116
|
+
|
|
117
|
+
/** Base fields present on every synced row. */
|
|
118
|
+
export interface SyncMeta {
|
|
119
|
+
readonly pda: string;
|
|
120
|
+
readonly slot: number;
|
|
121
|
+
readonly synced_at: Date;
|
|
122
|
+
readonly raw_data: Record<string, unknown> | null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** sap_agents row. */
|
|
126
|
+
export interface AgentRow extends SyncMeta {
|
|
127
|
+
readonly bump: number;
|
|
128
|
+
readonly version: number;
|
|
129
|
+
readonly wallet: string;
|
|
130
|
+
readonly name: string;
|
|
131
|
+
readonly description: string;
|
|
132
|
+
readonly agent_id: string | null;
|
|
133
|
+
readonly agent_uri: string | null;
|
|
134
|
+
readonly x402_endpoint: string | null;
|
|
135
|
+
readonly is_active: boolean;
|
|
136
|
+
readonly created_at: string;
|
|
137
|
+
readonly updated_at: string;
|
|
138
|
+
readonly reputation_score: number;
|
|
139
|
+
readonly total_feedbacks: number;
|
|
140
|
+
readonly reputation_sum: string;
|
|
141
|
+
readonly total_calls_served: string;
|
|
142
|
+
readonly avg_latency_ms: number;
|
|
143
|
+
readonly uptime_percent: number;
|
|
144
|
+
readonly capabilities: unknown[];
|
|
145
|
+
readonly pricing: unknown[];
|
|
146
|
+
readonly protocols: string[];
|
|
147
|
+
readonly active_plugins: unknown[];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** sap_escrows row. */
|
|
151
|
+
export interface EscrowRow extends SyncMeta {
|
|
152
|
+
readonly bump: number;
|
|
153
|
+
readonly agent: string;
|
|
154
|
+
readonly depositor: string;
|
|
155
|
+
readonly agent_wallet: string;
|
|
156
|
+
readonly balance: string;
|
|
157
|
+
readonly total_deposited: string;
|
|
158
|
+
readonly total_settled: string;
|
|
159
|
+
readonly total_calls_settled: string;
|
|
160
|
+
readonly price_per_call: string;
|
|
161
|
+
readonly max_calls: string;
|
|
162
|
+
readonly created_at: string;
|
|
163
|
+
readonly last_settled_at: string | null;
|
|
164
|
+
readonly expires_at: string | null;
|
|
165
|
+
readonly volume_curve: unknown[];
|
|
166
|
+
readonly token_mint: string | null;
|
|
167
|
+
readonly token_decimals: number;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** sap_tools row. */
|
|
171
|
+
export interface ToolRow extends SyncMeta {
|
|
172
|
+
readonly bump: number;
|
|
173
|
+
readonly agent: string;
|
|
174
|
+
readonly tool_name: string;
|
|
175
|
+
readonly version: number;
|
|
176
|
+
readonly http_method: string;
|
|
177
|
+
readonly category: string;
|
|
178
|
+
readonly params_count: number;
|
|
179
|
+
readonly required_params: number;
|
|
180
|
+
readonly is_compound: boolean;
|
|
181
|
+
readonly is_active: boolean;
|
|
182
|
+
readonly total_invocations: string;
|
|
183
|
+
readonly created_at: string;
|
|
184
|
+
readonly updated_at: string;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** sap_memory_ledgers row. */
|
|
188
|
+
export interface LedgerRow extends SyncMeta {
|
|
189
|
+
readonly bump: number;
|
|
190
|
+
readonly session: string;
|
|
191
|
+
readonly authority: string;
|
|
192
|
+
readonly num_entries: number;
|
|
193
|
+
readonly total_data_size: string;
|
|
194
|
+
readonly created_at: string;
|
|
195
|
+
readonly updated_at: string;
|
|
196
|
+
readonly num_pages: number;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** sap_events row. */
|
|
200
|
+
export interface EventRow {
|
|
201
|
+
readonly id: number;
|
|
202
|
+
readonly event_name: string;
|
|
203
|
+
readonly tx_signature: string;
|
|
204
|
+
readonly slot: number;
|
|
205
|
+
readonly block_time: number | null;
|
|
206
|
+
readonly data: Record<string, unknown>;
|
|
207
|
+
readonly agent_pda: string | null;
|
|
208
|
+
readonly wallet: string | null;
|
|
209
|
+
readonly synced_at: Date;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** sap_sync_cursors row. */
|
|
213
|
+
export interface SyncCursorRow {
|
|
214
|
+
readonly account_type: string;
|
|
215
|
+
readonly last_slot: number;
|
|
216
|
+
readonly last_signature: string | null;
|
|
217
|
+
readonly updated_at: Date;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
221
|
+
// Sync Options
|
|
222
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* @name SyncOptions
|
|
226
|
+
* @description Options for the sync engine.
|
|
227
|
+
* @category Postgres
|
|
228
|
+
* @since v0.1.0
|
|
229
|
+
*/
|
|
230
|
+
export interface SyncOptions {
|
|
231
|
+
/** Account types to sync. Default: all. */
|
|
232
|
+
readonly accountTypes?: SapAccountType[];
|
|
233
|
+
|
|
234
|
+
/** Sync events from TX logs. @default true */
|
|
235
|
+
readonly syncEvents?: boolean;
|
|
236
|
+
|
|
237
|
+
/** Batch size for account fetching. @default 100 */
|
|
238
|
+
readonly batchSize?: number;
|
|
239
|
+
|
|
240
|
+
/** Callback invoked after each batch. */
|
|
241
|
+
readonly onProgress?: (synced: number, total: number, type: string) => void;
|
|
242
|
+
|
|
243
|
+
/** Skip accounts that haven't changed since last sync. @default true */
|
|
244
|
+
readonly incremental?: boolean;
|
|
245
|
+
}
|