@secondlayer/shared 7.11.2 → 8.0.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.
Files changed (48) hide show
  1. package/dist/src/archive/range-digest.d.ts +0 -169
  2. package/dist/src/archive/semantic-digest-builder.d.ts +0 -169
  3. package/dist/src/coverage/index.d.ts +0 -169
  4. package/dist/src/crypto/secrets.js +22 -3
  5. package/dist/src/crypto/secrets.js.map +3 -3
  6. package/dist/src/db/index.d.ts +1 -211
  7. package/dist/src/db/index.js +22 -16
  8. package/dist/src/db/index.js.map +4 -4
  9. package/dist/src/db/queries/chain-reorgs.d.ts +0 -169
  10. package/dist/src/db/queries/chain-reorgs.js +22 -16
  11. package/dist/src/db/queries/chain-reorgs.js.map +4 -4
  12. package/dist/src/db/queries/contracts.d.ts +0 -169
  13. package/dist/src/db/queries/instance.d.ts +0 -169
  14. package/dist/src/db/queries/integrity.d.ts +0 -169
  15. package/dist/src/db/queries/subgraph-gaps.d.ts +0 -169
  16. package/dist/src/db/queries/subgraph-operations.d.ts +1 -170
  17. package/dist/src/db/queries/subgraph-operations.js +1 -15
  18. package/dist/src/db/queries/subgraph-operations.js.map +3 -3
  19. package/dist/src/db/queries/subgraphs.d.ts +1 -191
  20. package/dist/src/db/queries/subgraphs.js +30 -1068
  21. package/dist/src/db/queries/subgraphs.js.map +5 -12
  22. package/dist/src/db/queries/subscriptions.d.ts +0 -169
  23. package/dist/src/db/queries/subscriptions.js +22 -3
  24. package/dist/src/db/queries/subscriptions.js.map +3 -3
  25. package/dist/src/db/schema.d.ts +1 -198
  26. package/dist/src/errors.d.ts +1 -22
  27. package/dist/src/errors.js +2 -4
  28. package/dist/src/errors.js.map +3 -3
  29. package/dist/src/index.d.ts +5 -256
  30. package/dist/src/index.js +23 -20
  31. package/dist/src/index.js.map +6 -6
  32. package/dist/src/mode.d.ts +16 -2
  33. package/dist/src/mode.js +25 -4
  34. package/dist/src/mode.js.map +3 -3
  35. package/dist/src/node/local-client.d.ts +0 -169
  36. package/dist/src/schemas/index.d.ts +5 -25
  37. package/dist/src/schemas/index.js +1 -2
  38. package/dist/src/schemas/index.js.map +3 -3
  39. package/dist/src/schemas/subgraphs.d.ts +5 -25
  40. package/dist/src/schemas/subgraphs.js +1 -2
  41. package/dist/src/schemas/subgraphs.js.map +3 -3
  42. package/dist/src/streams-rows/index.d.ts +399 -0
  43. package/dist/src/streams-rows/index.js +336 -0
  44. package/dist/src/streams-rows/index.js.map +17 -0
  45. package/dist/src/subgraphs/spec.d.ts +0 -9
  46. package/migrations/0118_drop_retired_control_tables.ts +53 -0
  47. package/migrations/0119_drop_accounts_plan.ts +29 -0
  48. package/package.json +5 -1
@@ -10,19 +10,11 @@ interface DeploySubgraphRequest {
10
10
  startBlock?: number;
11
11
  /** Original TypeScript source, persisted so chat can read/diff/edit later. */
12
12
  sourceCode?: string;
13
- /**
14
- * BYO data plane: a user-owned Postgres connection string. When set, the
15
- * subgraph's schema, handler writes, and serving reads live in this DB instead
16
- * of the managed one. Stored encrypted at rest, never returned.
17
- */
18
- databaseUrl?: string;
19
- /** Validate the connection + print the DDL/grant plan without deploying. */
13
+ /** Validate the definition + print the DDL plan without deploying. */
20
14
  dryRun?: boolean;
21
15
  /**
22
- * Read visibility. Server-side defaults: managed deploys → public (anon
23
- * reads on /v1/subgraphs, name claimed in the global public namespace);
24
- * BYO-database deploys → private (public reads hit the user's own
25
- * Postgres, so going public is an explicit choice).
16
+ * Read visibility. Server-side default: deploys → public (anon reads on
17
+ * /v1/subgraphs, name claimed in the global public namespace).
26
18
  */
27
19
  visibility?: "public" | "private";
28
20
  }
@@ -33,10 +25,8 @@ interface DeploySubgraphResponse {
33
25
  version: string;
34
26
  visibility?: "public" | "private";
35
27
  message: string;
36
- /** Effective indexing start height after plan policy. */
28
+ /** Effective indexing start height. */
37
29
  start_block?: number;
38
- /** True when the free-tier forward-only policy adjusted the start. */
39
- start_block_clamped?: boolean;
40
30
  operationId?: string;
41
31
  reindexStarted?: boolean;
42
32
  /** Bounded candidate-event denominator for the reindex just started, when the
@@ -67,7 +57,6 @@ interface SubgraphSummary {
67
57
  progress: number;
68
58
  blocksRemaining?: number;
69
59
  syncMode?: "sync" | "reindex";
70
- resourceWarning?: SubgraphResourceWarning;
71
60
  gapCount: number;
72
61
  /** history_filling = expected gaps while a tip-first backfill op runs. */
73
62
  integrity: "complete" | "gaps_detected" | "history_filling";
@@ -115,7 +104,6 @@ interface SubgraphSyncInfo {
115
104
  estimatedEvents?: number;
116
105
  processedEvents?: number;
117
106
  etaSeconds?: number | null;
118
- resourceWarning?: SubgraphResourceWarning;
119
107
  gaps: {
120
108
  count: number
121
109
  totalMissingBlocks: number
@@ -124,14 +112,6 @@ interface SubgraphSyncInfo {
124
112
  /** history_filling = expected gaps while a tip-first backfill op runs. */
125
113
  integrity: "complete" | "gaps_detected" | "history_filling";
126
114
  }
127
- interface SubgraphResourceWarning {
128
- code: string;
129
- message: string;
130
- plan?: string;
131
- blockRange: number;
132
- processorMemoryMb: number;
133
- recommendedPlan: "launch";
134
- }
135
115
  interface SubgraphDetail {
136
116
  name: string;
137
117
  version: string;
@@ -225,4 +205,4 @@ interface SubgraphAggregateResponse {
225
205
  min?: Record<string, string | null>;
226
206
  max?: Record<string, string | null>;
227
207
  }
228
- export { SubgraphSyncInfo, SubgraphSummary, SubgraphResourceWarning, SubgraphQueryParams, SubgraphGapsResponse, SubgraphGapRange, SubgraphGapEntry, SubgraphDetail, SubgraphAggregateResponse, SubgraphAggregateParams, ReindexResponse, DeploySubgraphResponse, DeploySubgraphRequestSchema, DeploySubgraphRequest };
208
+ export { SubgraphSyncInfo, SubgraphSummary, SubgraphQueryParams, SubgraphGapsResponse, SubgraphGapRange, SubgraphGapEntry, SubgraphDetail, SubgraphAggregateResponse, SubgraphAggregateParams, ReindexResponse, DeploySubgraphResponse, DeploySubgraphRequestSchema, DeploySubgraphRequest };
@@ -25,7 +25,6 @@ var DeploySubgraphRequestSchema = z.object({
25
25
  handlerCode: z.string().max(1048576, "handler code exceeds 1MB limit"),
26
26
  startBlock: z.number().int().nonnegative().optional(),
27
27
  sourceCode: z.string().max(1048576, "source code exceeds 1MB limit").optional(),
28
- databaseUrl: z.string().url().refine((u) => u.startsWith("postgres://") || u.startsWith("postgresql://"), "must be a postgres:// connection string").optional(),
29
28
  dryRun: z.boolean().optional(),
30
29
  visibility: z.enum(["public", "private"]).optional()
31
30
  });
@@ -33,5 +32,5 @@ export {
33
32
  DeploySubgraphRequestSchema
34
33
  };
35
34
 
36
- //# debugId=7E8BA3E1297C5EB664756E2164756E21
35
+ //# debugId=1268F6D27AF0DE3364756E2164756E21
37
36
  //# sourceMappingURL=subgraphs.js.map
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/schemas/subgraphs.ts"],
4
4
  "sourcesContent": [
5
- "import { z } from \"zod\";\n\n// ── Deploy Subgraph Request ─────────────────────────────────────────────────\n\nexport interface DeploySubgraphRequest {\n\tname: string;\n\tversion?: string;\n\tdescription?: string;\n\tsources: Record<string, Record<string, unknown>>;\n\tschema: Record<string, unknown>;\n\thandlerCode: string;\n\t/** Override the definition's startBlock for this deploy only. */\n\tstartBlock?: number;\n\t/** Original TypeScript source, persisted so chat can read/diff/edit later. */\n\tsourceCode?: string;\n\t/**\n\t * BYO data plane: a user-owned Postgres connection string. When set, the\n\t * subgraph's schema, handler writes, and serving reads live in this DB instead\n\t * of the managed one. Stored encrypted at rest, never returned.\n\t */\n\tdatabaseUrl?: string;\n\t/** Validate the connection + print the DDL/grant plan without deploying. */\n\tdryRun?: boolean;\n\t/**\n\t * Read visibility. Server-side defaults: managed deploys → public (anon\n\t * reads on /v1/subgraphs, name claimed in the global public namespace);\n\t * BYO-database deploys → private (public reads hit the user's own\n\t * Postgres, so going public is an explicit choice).\n\t */\n\tvisibility?: \"public\" | \"private\";\n}\n\nexport const DeploySubgraphRequestSchema: z.ZodType<DeploySubgraphRequest> =\n\tz.object({\n\t\tname: z\n\t\t\t.string()\n\t\t\t.regex(/^[a-z0-9-]+$/, \"lowercase alphanumeric + hyphens only\")\n\t\t\t.max(63),\n\t\tversion: z.string().optional(),\n\t\tdescription: z.string().optional(),\n\t\tsources: z\n\t\t\t.record(z.string(), z.record(z.string(), z.unknown()))\n\t\t\t.refine(\n\t\t\t\t(s) => Object.keys(s).length > 0,\n\t\t\t\t\"Must have at least one source\",\n\t\t\t),\n\t\tschema: z.record(z.string(), z.unknown()),\n\t\thandlerCode: z.string().max(1_048_576, \"handler code exceeds 1MB limit\"),\n\t\tstartBlock: z.number().int().nonnegative().optional(),\n\t\tsourceCode: z\n\t\t\t.string()\n\t\t\t.max(1_048_576, \"source code exceeds 1MB limit\")\n\t\t\t.optional(),\n\t\tdatabaseUrl: z\n\t\t\t.string()\n\t\t\t.url()\n\t\t\t.refine(\n\t\t\t\t(u) => u.startsWith(\"postgres://\") || u.startsWith(\"postgresql://\"),\n\t\t\t\t\"must be a postgres:// connection string\",\n\t\t\t)\n\t\t\t.optional(),\n\t\tdryRun: z.boolean().optional(),\n\t\tvisibility: z.enum([\"public\", \"private\"]).optional(),\n\t});\n\nexport interface DeploySubgraphResponse {\n\taction: \"created\" | \"unchanged\" | \"handler_updated\" | \"updated\" | \"reindexed\";\n\tsubgraphId: string;\n\tversion: string;\n\tvisibility?: \"public\" | \"private\";\n\tmessage: string;\n\t/** Effective indexing start height after plan policy. */\n\tstart_block?: number;\n\t/** True when the free-tier forward-only policy adjusted the start. */\n\tstart_block_clamped?: boolean;\n\toperationId?: string;\n\treindexStarted?: boolean;\n\t/** Bounded candidate-event denominator for the reindex just started, when the\n\t * op was classifiable as sparse/light. Absent for heavy ops (no upfront estimate\n\t * possible) — check `sl subgraphs status` after ~30s for a rate-based ETA instead. */\n\testimatedEvents?: number;\n\t/** Non-blocking deploy lints (e.g. handler reads a print field never observed on-chain). */\n\twarnings?: string[];\n\tdiff?: {\n\t\taddedTables: string[];\n\t\tremovedTables: string[];\n\t\taddedColumns: Record<string, string[]>;\n\t\tbreakingChanges: string[];\n\t};\n}\n\n// Subgraph API response types\n\nexport interface SubgraphSummary {\n\tname: string;\n\tversion: string;\n\tstatus: string;\n\tlastProcessedBlock: number;\n\ttotalProcessed: number;\n\ttotalRows?: number;\n\ttotalErrors: number;\n\ttables: string[];\n\tchainTip: number;\n\tsourceChainTip?: number;\n\ttargetBlock?: number;\n\tprogress: number;\n\tblocksRemaining?: number;\n\tsyncMode?: \"sync\" | \"reindex\";\n\tresourceWarning?: SubgraphResourceWarning;\n\tgapCount: number;\n\t/** history_filling = expected gaps while a tip-first backfill op runs. */\n\tintegrity: \"complete\" | \"gaps_detected\" | \"history_filling\";\n\tvisibility?: \"public\" | \"private\";\n\t/** Most recent indexing error reason + when it occurred, if any. */\n\tlastError?: string | null;\n\tlastErrorAt?: string | null;\n\t/** Last row mutation timestamp; powers per-card freshness. */\n\tupdatedAt?: string | null;\n\t/** Number of subscriptions attached to this subgraph. */\n\tsubscriptionCount?: number;\n\tcreatedAt: string;\n}\n\nexport interface SubgraphGapRange {\n\tstart: number;\n\tend: number;\n\tsize: number;\n\treason: string;\n}\n\nexport interface SubgraphSyncInfo {\n\tstatus: \"synced\" | \"catching_up\" | \"reindexing\" | \"error\";\n\tmode?: \"sync\" | \"reindex\";\n\tstartBlock: number;\n\tlastProcessedBlock: number;\n\t/**\n\t * Backward-compatible denominator for progress displays. During reindexing,\n\t * this is the reindex target block rather than the live source chain tip.\n\t */\n\tchainTip: number;\n\tsourceChainTip?: number;\n\ttargetBlock?: number;\n\tblocksRemaining: number;\n\tprocessedBlocks?: number;\n\ttotalBlocks?: number;\n\tprogress: number;\n\t/** Present while the populating operation is queued: approximate claim\n\t * position + honest event denominator + naive start estimate. */\n\tqueue?: {\n\t\tposition: number | null;\n\t\testimatedEvents: number | null;\n\t\testimatedStartSeconds: number | null;\n\t};\n\t/** Event-based progress for sparse syncs (block pct is meaningless when\n\t * most heights are skipped). */\n\testimatedEvents?: number;\n\tprocessedEvents?: number;\n\tetaSeconds?: number | null;\n\tresourceWarning?: SubgraphResourceWarning;\n\tgaps: {\n\t\tcount: number;\n\t\ttotalMissingBlocks: number;\n\t\tranges: SubgraphGapRange[];\n\t};\n\t/** history_filling = expected gaps while a tip-first backfill op runs. */\n\tintegrity: \"complete\" | \"gaps_detected\" | \"history_filling\";\n}\n\nexport interface SubgraphResourceWarning {\n\tcode: string;\n\tmessage: string;\n\tplan?: string;\n\tblockRange: number;\n\tprocessorMemoryMb: number;\n\trecommendedPlan: \"launch\";\n}\n\nexport interface SubgraphDetail {\n\tname: string;\n\tversion: string;\n\tschemaHash?: string;\n\tstatus: string;\n\tvisibility?: \"public\" | \"private\";\n\tlastProcessedBlock: number;\n\tdescription?: string;\n\tsources?: Record<string, unknown>;\n\tdefinition?: Record<string, unknown>;\n\thealth: {\n\t\ttotalProcessed: number;\n\t\ttotalErrors: number;\n\t\terrorRate: number;\n\t\tlastError: string | null;\n\t\tlastErrorAt: string | null;\n\t};\n\tsync: SubgraphSyncInfo;\n\ttables: Record<\n\t\tstring,\n\t\t{\n\t\t\tendpoint: string;\n\t\t\tcolumns: Record<\n\t\t\t\tstring,\n\t\t\t\t{\n\t\t\t\t\ttype: string;\n\t\t\t\t\tnullable?: boolean;\n\t\t\t\t\tindexed?: boolean;\n\t\t\t\t\tsearchable?: boolean;\n\t\t\t\t\tdefault?: string | number | boolean;\n\t\t\t\t}\n\t\t\t>;\n\t\t\trowCount: number;\n\t\t\texample: string;\n\t\t\tindexes?: readonly (readonly string[])[];\n\t\t\tuniqueKeys?: readonly (readonly string[])[];\n\t\t}\n\t>;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface SubgraphGapEntry {\n\tstart: number;\n\tend: number;\n\tsize: number;\n\treason: string;\n\tdetectedAt: string;\n\tresolvedAt: string | null;\n}\n\nexport interface SubgraphGapsResponse {\n\tdata: SubgraphGapEntry[];\n\tmeta: {\n\t\ttotal: number;\n\t\ttotalMissingBlocks: number;\n\t\tlimit: number;\n\t\toffset: number;\n\t};\n}\n\nexport interface ReindexResponse {\n\tmessage: string;\n\tfromBlock: number;\n\ttoBlock: number | string;\n\toperationId?: string;\n\tstatus?: \"queued\" | \"running\" | \"cancel_requested\";\n}\n\nexport interface SubgraphQueryParams {\n\tsort?: string;\n\torder?: string;\n\tlimit?: number;\n\toffset?: number;\n\tfields?: string;\n\tfilters?: Record<string, string>;\n}\n\n/**\n * Request shape for `GET /api/subgraphs/:subgraphName/:tableName/aggregate`.\n * `filters` reuses the list/count where-surface; the rest name the columns to\n * aggregate. SUM/MIN/MAX columns must be numeric (uint/int, plus `_block_height`).\n */\nexport interface SubgraphAggregateParams {\n\tfilters?: Record<string, string>;\n\tcount?: boolean;\n\tcountDistinct?: string[];\n\tsum?: string[];\n\tmin?: string[];\n\tmax?: string[];\n}\n\n/**\n * Aggregate response. Keys are present only for requested aggregates.\n * `count`/`countDistinct` are JSON numbers (counts << 2^53); `sum`/`min`/`max`\n * are lossless strings (NUMERIC `::text`). `sum` of an empty set is `\"0\"`;\n * `min`/`max` are `null` when the filtered set is empty or all-null.\n */\nexport interface SubgraphAggregateResponse {\n\tcount?: number;\n\tcountDistinct?: Record<string, number>;\n\tsum?: Record<string, string>;\n\tmin?: Record<string, string | null>;\n\tmax?: Record<string, string | null>;\n}\n"
5
+ "import { z } from \"zod\";\n\n// ── Deploy Subgraph Request ─────────────────────────────────────────────────\n\nexport interface DeploySubgraphRequest {\n\tname: string;\n\tversion?: string;\n\tdescription?: string;\n\tsources: Record<string, Record<string, unknown>>;\n\tschema: Record<string, unknown>;\n\thandlerCode: string;\n\t/** Override the definition's startBlock for this deploy only. */\n\tstartBlock?: number;\n\t/** Original TypeScript source, persisted so chat can read/diff/edit later. */\n\tsourceCode?: string;\n\t/** Validate the definition + print the DDL plan without deploying. */\n\tdryRun?: boolean;\n\t/**\n\t * Read visibility. Server-side default: deploys → public (anon reads on\n\t * /v1/subgraphs, name claimed in the global public namespace).\n\t */\n\tvisibility?: \"public\" | \"private\";\n}\n\nexport const DeploySubgraphRequestSchema: z.ZodType<DeploySubgraphRequest> =\n\tz.object({\n\t\tname: z\n\t\t\t.string()\n\t\t\t.regex(/^[a-z0-9-]+$/, \"lowercase alphanumeric + hyphens only\")\n\t\t\t.max(63),\n\t\tversion: z.string().optional(),\n\t\tdescription: z.string().optional(),\n\t\tsources: z\n\t\t\t.record(z.string(), z.record(z.string(), z.unknown()))\n\t\t\t.refine(\n\t\t\t\t(s) => Object.keys(s).length > 0,\n\t\t\t\t\"Must have at least one source\",\n\t\t\t),\n\t\tschema: z.record(z.string(), z.unknown()),\n\t\thandlerCode: z.string().max(1_048_576, \"handler code exceeds 1MB limit\"),\n\t\tstartBlock: z.number().int().nonnegative().optional(),\n\t\tsourceCode: z\n\t\t\t.string()\n\t\t\t.max(1_048_576, \"source code exceeds 1MB limit\")\n\t\t\t.optional(),\n\t\tdryRun: z.boolean().optional(),\n\t\tvisibility: z.enum([\"public\", \"private\"]).optional(),\n\t});\n\nexport interface DeploySubgraphResponse {\n\taction: \"created\" | \"unchanged\" | \"handler_updated\" | \"updated\" | \"reindexed\";\n\tsubgraphId: string;\n\tversion: string;\n\tvisibility?: \"public\" | \"private\";\n\tmessage: string;\n\t/** Effective indexing start height. */\n\tstart_block?: number;\n\toperationId?: string;\n\treindexStarted?: boolean;\n\t/** Bounded candidate-event denominator for the reindex just started, when the\n\t * op was classifiable as sparse/light. Absent for heavy ops (no upfront estimate\n\t * possible) — check `sl subgraphs status` after ~30s for a rate-based ETA instead. */\n\testimatedEvents?: number;\n\t/** Non-blocking deploy lints (e.g. handler reads a print field never observed on-chain). */\n\twarnings?: string[];\n\tdiff?: {\n\t\taddedTables: string[];\n\t\tremovedTables: string[];\n\t\taddedColumns: Record<string, string[]>;\n\t\tbreakingChanges: string[];\n\t};\n}\n\n// Subgraph API response types\n\nexport interface SubgraphSummary {\n\tname: string;\n\tversion: string;\n\tstatus: string;\n\tlastProcessedBlock: number;\n\ttotalProcessed: number;\n\ttotalRows?: number;\n\ttotalErrors: number;\n\ttables: string[];\n\tchainTip: number;\n\tsourceChainTip?: number;\n\ttargetBlock?: number;\n\tprogress: number;\n\tblocksRemaining?: number;\n\tsyncMode?: \"sync\" | \"reindex\";\n\tgapCount: number;\n\t/** history_filling = expected gaps while a tip-first backfill op runs. */\n\tintegrity: \"complete\" | \"gaps_detected\" | \"history_filling\";\n\tvisibility?: \"public\" | \"private\";\n\t/** Most recent indexing error reason + when it occurred, if any. */\n\tlastError?: string | null;\n\tlastErrorAt?: string | null;\n\t/** Last row mutation timestamp; powers per-card freshness. */\n\tupdatedAt?: string | null;\n\t/** Number of subscriptions attached to this subgraph. */\n\tsubscriptionCount?: number;\n\tcreatedAt: string;\n}\n\nexport interface SubgraphGapRange {\n\tstart: number;\n\tend: number;\n\tsize: number;\n\treason: string;\n}\n\nexport interface SubgraphSyncInfo {\n\tstatus: \"synced\" | \"catching_up\" | \"reindexing\" | \"error\";\n\tmode?: \"sync\" | \"reindex\";\n\tstartBlock: number;\n\tlastProcessedBlock: number;\n\t/**\n\t * Backward-compatible denominator for progress displays. During reindexing,\n\t * this is the reindex target block rather than the live source chain tip.\n\t */\n\tchainTip: number;\n\tsourceChainTip?: number;\n\ttargetBlock?: number;\n\tblocksRemaining: number;\n\tprocessedBlocks?: number;\n\ttotalBlocks?: number;\n\tprogress: number;\n\t/** Present while the populating operation is queued: approximate claim\n\t * position + honest event denominator + naive start estimate. */\n\tqueue?: {\n\t\tposition: number | null;\n\t\testimatedEvents: number | null;\n\t\testimatedStartSeconds: number | null;\n\t};\n\t/** Event-based progress for sparse syncs (block pct is meaningless when\n\t * most heights are skipped). */\n\testimatedEvents?: number;\n\tprocessedEvents?: number;\n\tetaSeconds?: number | null;\n\tgaps: {\n\t\tcount: number;\n\t\ttotalMissingBlocks: number;\n\t\tranges: SubgraphGapRange[];\n\t};\n\t/** history_filling = expected gaps while a tip-first backfill op runs. */\n\tintegrity: \"complete\" | \"gaps_detected\" | \"history_filling\";\n}\n\nexport interface SubgraphDetail {\n\tname: string;\n\tversion: string;\n\tschemaHash?: string;\n\tstatus: string;\n\tvisibility?: \"public\" | \"private\";\n\tlastProcessedBlock: number;\n\tdescription?: string;\n\tsources?: Record<string, unknown>;\n\tdefinition?: Record<string, unknown>;\n\thealth: {\n\t\ttotalProcessed: number;\n\t\ttotalErrors: number;\n\t\terrorRate: number;\n\t\tlastError: string | null;\n\t\tlastErrorAt: string | null;\n\t};\n\tsync: SubgraphSyncInfo;\n\ttables: Record<\n\t\tstring,\n\t\t{\n\t\t\tendpoint: string;\n\t\t\tcolumns: Record<\n\t\t\t\tstring,\n\t\t\t\t{\n\t\t\t\t\ttype: string;\n\t\t\t\t\tnullable?: boolean;\n\t\t\t\t\tindexed?: boolean;\n\t\t\t\t\tsearchable?: boolean;\n\t\t\t\t\tdefault?: string | number | boolean;\n\t\t\t\t}\n\t\t\t>;\n\t\t\trowCount: number;\n\t\t\texample: string;\n\t\t\tindexes?: readonly (readonly string[])[];\n\t\t\tuniqueKeys?: readonly (readonly string[])[];\n\t\t}\n\t>;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface SubgraphGapEntry {\n\tstart: number;\n\tend: number;\n\tsize: number;\n\treason: string;\n\tdetectedAt: string;\n\tresolvedAt: string | null;\n}\n\nexport interface SubgraphGapsResponse {\n\tdata: SubgraphGapEntry[];\n\tmeta: {\n\t\ttotal: number;\n\t\ttotalMissingBlocks: number;\n\t\tlimit: number;\n\t\toffset: number;\n\t};\n}\n\nexport interface ReindexResponse {\n\tmessage: string;\n\tfromBlock: number;\n\ttoBlock: number | string;\n\toperationId?: string;\n\tstatus?: \"queued\" | \"running\" | \"cancel_requested\";\n}\n\nexport interface SubgraphQueryParams {\n\tsort?: string;\n\torder?: string;\n\tlimit?: number;\n\toffset?: number;\n\tfields?: string;\n\tfilters?: Record<string, string>;\n}\n\n/**\n * Request shape for `GET /api/subgraphs/:subgraphName/:tableName/aggregate`.\n * `filters` reuses the list/count where-surface; the rest name the columns to\n * aggregate. SUM/MIN/MAX columns must be numeric (uint/int, plus `_block_height`).\n */\nexport interface SubgraphAggregateParams {\n\tfilters?: Record<string, string>;\n\tcount?: boolean;\n\tcountDistinct?: string[];\n\tsum?: string[];\n\tmin?: string[];\n\tmax?: string[];\n}\n\n/**\n * Aggregate response. Keys are present only for requested aggregates.\n * `count`/`countDistinct` are JSON numbers (counts << 2^53); `sum`/`min`/`max`\n * are lossless strings (NUMERIC `::text`). `sum` of an empty set is `\"0\"`;\n * `min`/`max` are `null` when the filtered set is empty or all-null.\n */\nexport interface SubgraphAggregateResponse {\n\tcount?: number;\n\tcountDistinct?: Record<string, number>;\n\tsum?: Record<string, string>;\n\tmin?: Record<string, string | null>;\n\tmax?: Record<string, string | null>;\n}\n"
6
6
  ],
7
- "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAgCO,IAAM,8BACZ,EAAE,OAAO;AAAA,EACR,MAAM,EACJ,OAAO,EACP,MAAM,gBAAgB,uCAAuC,EAC7D,IAAI,EAAE;AAAA,EACR,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,SAAS,EACP,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,EACpD,OACA,CAAC,MAAM,OAAO,KAAK,CAAC,EAAE,SAAS,GAC/B,+BACD;AAAA,EACD,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;AAAA,EACxC,aAAa,EAAE,OAAO,EAAE,IAAI,SAAW,gCAAgC;AAAA,EACvE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAAA,EACpD,YAAY,EACV,OAAO,EACP,IAAI,SAAW,+BAA+B,EAC9C,SAAS;AAAA,EACX,aAAa,EACX,OAAO,EACP,IAAI,EACJ,OACA,CAAC,MAAM,EAAE,WAAW,aAAa,KAAK,EAAE,WAAW,eAAe,GAClE,yCACD,EACC,SAAS;AAAA,EACX,QAAQ,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC7B,YAAY,EAAE,KAAK,CAAC,UAAU,SAAS,CAAC,EAAE,SAAS;AACpD,CAAC;",
8
- "debugId": "7E8BA3E1297C5EB664756E2164756E21",
7
+ "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAwBO,IAAM,8BACZ,EAAE,OAAO;AAAA,EACR,MAAM,EACJ,OAAO,EACP,MAAM,gBAAgB,uCAAuC,EAC7D,IAAI,EAAE;AAAA,EACR,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,SAAS,EACP,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,EACpD,OACA,CAAC,MAAM,OAAO,KAAK,CAAC,EAAE,SAAS,GAC/B,+BACD;AAAA,EACD,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;AAAA,EACxC,aAAa,EAAE,OAAO,EAAE,IAAI,SAAW,gCAAgC;AAAA,EACvE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAAA,EACpD,YAAY,EACV,OAAO,EACP,IAAI,SAAW,+BAA+B,EAC9C,SAAS;AAAA,EACX,QAAQ,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC7B,YAAY,EAAE,KAAK,CAAC,UAAU,SAAS,CAAC,EAAE,SAAS;AACpD,CAAC;",
8
+ "debugId": "1268F6D27AF0DE3364756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -0,0 +1,399 @@
1
+ /** Make a cvToValue result JSON-serializable: Clarity (u)ints decode to bigint,
2
+ * which JSON.stringify can't handle — convert recursively to strings. */
3
+ declare function toJsonSafe(value: unknown): unknown;
4
+ /** Decode a hex-encoded Clarity value to JSON-safe JS (uints as strings,
5
+ * buffers as `0x…` hex, tuples as objects). Returns the input hex on failure. */
6
+ declare function decodeClarityValue(hex: string): unknown;
7
+ import { DECODED_EVENT_TYPES } from "@secondlayer/stacks/filters";
8
+ import { DecodedEventType } from "@secondlayer/stacks/filters";
9
+ /** Alias kept for the Streams surface (identical to {@link DECODED_EVENT_TYPES}).
10
+ * Explicit type annotation required — isolatedDeclarations emits `unknown` for
11
+ * a bare const-to-const alias. */
12
+ declare const STREAMS_EVENT_TYPES: typeof DECODED_EVENT_TYPES;
13
+ type StreamsEventType = DecodedEventType;
14
+ /** A Clarity value as Streams serves it: the canonical hex string, a typed
15
+ * object carrying that hex (`{ hex }`), or a decoded Clarity-JSON object.
16
+ * Decode helpers (`decodeNftTransfer`, etc.) resolve it to a concrete value. */
17
+ type StreamsClarityValue = string | {
18
+ hex: string
19
+ } | Record<string, unknown>;
20
+ type StxTransferPayload = {
21
+ sender: string
22
+ recipient: string
23
+ amount: string
24
+ memo?: string
25
+ };
26
+ type StxMintPayload = {
27
+ recipient: string
28
+ amount: string
29
+ };
30
+ type StxBurnPayload = {
31
+ sender: string
32
+ amount: string
33
+ };
34
+ type StxLockPayload = {
35
+ locked_address: string
36
+ locked_amount: string
37
+ unlock_height: string
38
+ };
39
+ type FtTransferPayload = {
40
+ asset_identifier: string
41
+ sender: string
42
+ recipient: string
43
+ amount: string
44
+ };
45
+ type FtMintPayload = {
46
+ asset_identifier: string
47
+ recipient: string
48
+ amount: string
49
+ };
50
+ type FtBurnPayload = {
51
+ asset_identifier: string
52
+ sender: string
53
+ amount: string
54
+ };
55
+ type NftTransferPayload = {
56
+ asset_identifier: string
57
+ sender: string
58
+ recipient: string
59
+ value: StreamsClarityValue
60
+ /** Canonical serialized hex of `value`, when the stream carries it. */
61
+ raw_value?: string
62
+ };
63
+ type NftMintPayload = {
64
+ asset_identifier: string
65
+ recipient: string
66
+ value: StreamsClarityValue
67
+ raw_value?: string
68
+ };
69
+ type NftBurnPayload = {
70
+ asset_identifier: string
71
+ sender: string
72
+ value: StreamsClarityValue
73
+ raw_value?: string
74
+ };
75
+ type PrintPayload = {
76
+ contract_id?: string | null
77
+ topic?: string
78
+ value?: unknown
79
+ raw_value?: string
80
+ };
81
+ /** Union of every Streams payload shape, discriminated by `event_type` on the
82
+ * parent `StreamsEvent`. */
83
+ type StreamsEventPayload = StxTransferPayload | StxMintPayload | StxBurnPayload | StxLockPayload | FtTransferPayload | FtMintPayload | FtBurnPayload | NftTransferPayload | NftMintPayload | NftBurnPayload | PrintPayload;
84
+ type StreamsEventBase = {
85
+ /**
86
+ * Globally unique, monotonic position of this event (`<block>:<index>`). Use
87
+ * it as the primary key of your projection rows — replaying a batch then
88
+ * upserts cleanly. Don't synthesize your own id from `tx_id`/`event_index`.
89
+ */
90
+ cursor: string
91
+ block_height: number
92
+ block_hash: string
93
+ burn_block_height: number
94
+ tx_id: string
95
+ tx_index: number
96
+ event_index: number
97
+ contract_id: string | null
98
+ ts: string
99
+ /**
100
+ * True when this event's block is past the finality boundary (immutable).
101
+ * Optional for back-compat; the API always sets it on Streams responses.
102
+ */
103
+ finalized?: boolean
104
+ /**
105
+ * Labels whose filter group this event satisfied, present only when the
106
+ * request used a labelled `filters` map. The SDK dispatches on it for you
107
+ * (`on.<label>`), so handlers rarely read it directly.
108
+ */
109
+ matched?: string[]
110
+ };
111
+ type StreamsEventOf<
112
+ T extends StreamsEventType,
113
+ P
114
+ > = StreamsEventBase & {
115
+ event_type: T
116
+ payload: P
117
+ };
118
+ /** A raw Streams event. Discriminated on `event_type`, so `event.payload`
119
+ * narrows to the matching payload shape once the type is checked. */
120
+ type StreamsEvent = StreamsEventOf<"stx_transfer", StxTransferPayload> | StreamsEventOf<"stx_mint", StxMintPayload> | StreamsEventOf<"stx_burn", StxBurnPayload> | StreamsEventOf<"stx_lock", StxLockPayload> | StreamsEventOf<"ft_transfer", FtTransferPayload> | StreamsEventOf<"ft_mint", FtMintPayload> | StreamsEventOf<"ft_burn", FtBurnPayload> | StreamsEventOf<"nft_transfer", NftTransferPayload> | StreamsEventOf<"nft_mint", NftMintPayload> | StreamsEventOf<"nft_burn", NftBurnPayload> | StreamsEventOf<"print", PrintPayload>;
121
+ /** Superset of the columns the decoded_events table holds. Every decoded
122
+ * event's `decoded_payload` is assignable to this, so the indexer's writer
123
+ * can map columns generically instead of per-event-type. */
124
+ type DecodedEventColumns = {
125
+ contract_id?: string | null
126
+ asset_identifier?: string | null
127
+ sender?: string | null
128
+ recipient?: string | null
129
+ amount?: string | null
130
+ value?: string | null
131
+ memo?: string | null
132
+ /** JSONB overflow for non-flat types (e.g. print's decoded value). */
133
+ payload?: unknown
134
+ };
135
+ declare function requireString(payload: Record<string, unknown>, field: string, eventType: string): string;
136
+ declare function optionalString(value: unknown): string | null;
137
+ declare function requireAmountField(payload: Record<string, unknown>, field: string, eventType: string): string;
138
+ declare function requireAmount(payload: Record<string, unknown>, eventType: string): string;
139
+ declare function parseAssetIdentifier(assetIdentifier: string, eventType: string): {
140
+ contract_id: string
141
+ token_name: string | null
142
+ };
143
+ /** NFT token id: live streams emits a typed Clarity value at `value` and the
144
+ * canonical hex at `raw_value`; prefer raw_value when present. */
145
+ declare function requireHexValue(payload: Record<string, unknown>, eventType: string): string;
146
+ /** Common envelope fields shared by every decoded event, lifted off the
147
+ * source StreamsEvent. The decoder supplies event_type + decoded_payload. */
148
+ declare function decodedRow<
149
+ T extends string,
150
+ P
151
+ >(event: StreamsEvent, eventType: T, decoded_payload: P): {
152
+ cursor: string
153
+ block_height: number
154
+ tx_id: string
155
+ tx_index: number
156
+ event_index: number
157
+ event_type: T
158
+ decoded_payload: P
159
+ source_cursor: string
160
+ };
161
+ type FtTransferEvent = Extract<StreamsEvent, {
162
+ event_type: "ft_transfer"
163
+ }>;
164
+ type DecodedFtTransferPayload = {
165
+ asset_identifier: string
166
+ contract_id: string
167
+ token_name: string | null
168
+ sender: string
169
+ recipient: string
170
+ amount: string
171
+ };
172
+ type DecodedFtTransfer = {
173
+ cursor: string
174
+ block_height: number
175
+ tx_id: string
176
+ tx_index: number
177
+ event_index: number
178
+ event_type: "ft_transfer"
179
+ decoded_payload: DecodedFtTransferPayload
180
+ source_cursor: string
181
+ };
182
+ declare function isFtTransfer(event: StreamsEvent): event is FtTransferEvent;
183
+ declare function decodeFtTransfer(event: StreamsEvent): DecodedFtTransfer;
184
+ type NftTransferEvent = Extract<StreamsEvent, {
185
+ event_type: "nft_transfer"
186
+ }>;
187
+ type DecodedNftTransferPayload = {
188
+ asset_identifier: string
189
+ contract_id: string
190
+ token_name: string | null
191
+ sender: string
192
+ recipient: string
193
+ value: string
194
+ };
195
+ type DecodedNftTransfer = {
196
+ cursor: string
197
+ block_height: number
198
+ tx_id: string
199
+ tx_index: number
200
+ event_index: number
201
+ event_type: "nft_transfer"
202
+ decoded_payload: DecodedNftTransferPayload
203
+ source_cursor: string
204
+ };
205
+ declare function isNftTransfer(event: StreamsEvent): event is NftTransferEvent;
206
+ declare function decodeNftTransfer(event: StreamsEvent): DecodedNftTransfer;
207
+ /** Decoded form of a Clarity `print` event:
208
+ * - `topic`: the print topic, when the contract emits a `{ topic, ... }` tuple
209
+ * - `value`: the Clarity value decoded to JSON (uints as strings, buffers as
210
+ * `0x…` hex, tuples as objects)
211
+ * - `raw_value`: the canonical serialized hex, for byte-exact consumers */
212
+ type DecodedPrintValue = {
213
+ topic: string | null
214
+ value: unknown
215
+ raw_value: string | null
216
+ };
217
+ type DecodedPrintPayload = {
218
+ contract_id: string | null
219
+ payload: DecodedPrintValue
220
+ };
221
+ type DecodedPrint = {
222
+ cursor: string
223
+ block_height: number
224
+ tx_id: string
225
+ tx_index: number
226
+ event_index: number
227
+ event_type: "print"
228
+ decoded_payload: DecodedPrintPayload
229
+ source_cursor: string
230
+ };
231
+ declare function isPrint(event: StreamsEvent): event is StreamsEvent & {
232
+ event_type: "print"
233
+ };
234
+ declare function decodePrint(event: StreamsEvent): DecodedPrint;
235
+ type DecodedStxTransferPayload = {
236
+ sender: string
237
+ recipient: string
238
+ amount: string
239
+ memo: string | null
240
+ };
241
+ type DecodedStxTransfer = {
242
+ cursor: string
243
+ block_height: number
244
+ tx_id: string
245
+ tx_index: number
246
+ event_index: number
247
+ event_type: "stx_transfer"
248
+ decoded_payload: DecodedStxTransferPayload
249
+ source_cursor: string
250
+ };
251
+ type DecodedStxMintPayload = {
252
+ recipient: string
253
+ amount: string
254
+ };
255
+ type DecodedStxMint = {
256
+ cursor: string
257
+ block_height: number
258
+ tx_id: string
259
+ tx_index: number
260
+ event_index: number
261
+ event_type: "stx_mint"
262
+ decoded_payload: DecodedStxMintPayload
263
+ source_cursor: string
264
+ };
265
+ type DecodedStxBurnPayload = {
266
+ sender: string
267
+ amount: string
268
+ };
269
+ type DecodedStxBurn = {
270
+ cursor: string
271
+ block_height: number
272
+ tx_id: string
273
+ tx_index: number
274
+ event_index: number
275
+ event_type: "stx_burn"
276
+ decoded_payload: DecodedStxBurnPayload
277
+ source_cursor: string
278
+ };
279
+ declare function isStxTransfer(event: StreamsEvent): event is StreamsEvent & {
280
+ event_type: "stx_transfer"
281
+ };
282
+ declare function decodeStxTransfer(event: StreamsEvent): DecodedStxTransfer;
283
+ declare function isStxMint(event: StreamsEvent): event is StreamsEvent & {
284
+ event_type: "stx_mint"
285
+ };
286
+ declare function decodeStxMint(event: StreamsEvent): DecodedStxMint;
287
+ declare function isStxBurn(event: StreamsEvent): event is StreamsEvent & {
288
+ event_type: "stx_burn"
289
+ };
290
+ declare function decodeStxBurn(event: StreamsEvent): DecodedStxBurn;
291
+ type DecodedStxLockPayload = {
292
+ sender: string
293
+ amount: string
294
+ payload: {
295
+ unlock_height: string | null
296
+ }
297
+ };
298
+ type DecodedStxLock = {
299
+ cursor: string
300
+ block_height: number
301
+ tx_id: string
302
+ tx_index: number
303
+ event_index: number
304
+ event_type: "stx_lock"
305
+ decoded_payload: DecodedStxLockPayload
306
+ source_cursor: string
307
+ };
308
+ declare function isStxLock(event: StreamsEvent): event is StreamsEvent & {
309
+ event_type: "stx_lock"
310
+ };
311
+ declare function decodeStxLock(event: StreamsEvent): DecodedStxLock;
312
+ type DecodedFtMintPayload = {
313
+ asset_identifier: string
314
+ contract_id: string
315
+ token_name: string | null
316
+ recipient: string
317
+ amount: string
318
+ };
319
+ type DecodedFtMint = {
320
+ cursor: string
321
+ block_height: number
322
+ tx_id: string
323
+ tx_index: number
324
+ event_index: number
325
+ event_type: "ft_mint"
326
+ decoded_payload: DecodedFtMintPayload
327
+ source_cursor: string
328
+ };
329
+ type DecodedFtBurnPayload = {
330
+ asset_identifier: string
331
+ contract_id: string
332
+ token_name: string | null
333
+ sender: string
334
+ amount: string
335
+ };
336
+ type DecodedFtBurn = {
337
+ cursor: string
338
+ block_height: number
339
+ tx_id: string
340
+ tx_index: number
341
+ event_index: number
342
+ event_type: "ft_burn"
343
+ decoded_payload: DecodedFtBurnPayload
344
+ source_cursor: string
345
+ };
346
+ type DecodedNftMintPayload = {
347
+ asset_identifier: string
348
+ contract_id: string
349
+ token_name: string | null
350
+ recipient: string
351
+ value: string
352
+ };
353
+ type DecodedNftMint = {
354
+ cursor: string
355
+ block_height: number
356
+ tx_id: string
357
+ tx_index: number
358
+ event_index: number
359
+ event_type: "nft_mint"
360
+ decoded_payload: DecodedNftMintPayload
361
+ source_cursor: string
362
+ };
363
+ type DecodedNftBurnPayload = {
364
+ asset_identifier: string
365
+ contract_id: string
366
+ token_name: string | null
367
+ sender: string
368
+ value: string
369
+ };
370
+ type DecodedNftBurn = {
371
+ cursor: string
372
+ block_height: number
373
+ tx_id: string
374
+ tx_index: number
375
+ event_index: number
376
+ event_type: "nft_burn"
377
+ decoded_payload: DecodedNftBurnPayload
378
+ source_cursor: string
379
+ };
380
+ declare function isFtMint(event: StreamsEvent): event is StreamsEvent & {
381
+ event_type: "ft_mint"
382
+ };
383
+ declare function decodeFtMint(event: StreamsEvent): DecodedFtMint;
384
+ declare function isFtBurn(event: StreamsEvent): event is StreamsEvent & {
385
+ event_type: "ft_burn"
386
+ };
387
+ declare function decodeFtBurn(event: StreamsEvent): DecodedFtBurn;
388
+ declare function isNftMint(event: StreamsEvent): event is StreamsEvent & {
389
+ event_type: "nft_mint"
390
+ };
391
+ declare function decodeNftMint(event: StreamsEvent): DecodedNftMint;
392
+ declare function isNftBurn(event: StreamsEvent): event is StreamsEvent & {
393
+ event_type: "nft_burn"
394
+ };
395
+ declare function decodeNftBurn(event: StreamsEvent): DecodedNftBurn;
396
+ /** Union of every decoded DB-row shape the guard+decode pairs produce —
397
+ * exactly what the `decoded_events` table stores. */
398
+ type DecodedEventRow = DecodedFtTransfer | DecodedNftTransfer | DecodedStxTransfer | DecodedStxMint | DecodedStxBurn | DecodedStxLock | DecodedFtMint | DecodedFtBurn | DecodedNftMint | DecodedNftBurn | DecodedPrint;
399
+ export { toJsonSafe, requireString, requireHexValue, requireAmountField, requireAmount, parseAssetIdentifier, optionalString, isStxTransfer, isStxMint, isStxLock, isStxBurn, isPrint, isNftTransfer, isNftMint, isNftBurn, isFtTransfer, isFtMint, isFtBurn, decodedRow, decodeStxTransfer, decodeStxMint, decodeStxLock, decodeStxBurn, decodePrint, decodeNftTransfer, decodeNftMint, decodeNftBurn, decodeFtTransfer, decodeFtMint, decodeFtBurn, decodeClarityValue, StxTransferPayload, StxMintPayload, StxLockPayload, StxBurnPayload, StreamsEventType, StreamsEventPayload, StreamsEventBase, StreamsEvent, StreamsClarityValue, STREAMS_EVENT_TYPES, PrintPayload, NftTransferPayload, NftTransferEvent, NftMintPayload, NftBurnPayload, FtTransferPayload, FtTransferEvent, FtMintPayload, FtBurnPayload, DecodedStxTransferPayload, DecodedStxTransfer, DecodedStxMintPayload, DecodedStxMint, DecodedStxLockPayload, DecodedStxLock, DecodedStxBurnPayload, DecodedStxBurn, DecodedPrintValue, DecodedPrintPayload, DecodedPrint, DecodedNftTransferPayload, DecodedNftTransfer, DecodedNftMintPayload, DecodedNftMint, DecodedNftBurnPayload, DecodedNftBurn, DecodedFtTransferPayload, DecodedFtTransfer, DecodedFtMintPayload, DecodedFtMint, DecodedFtBurnPayload, DecodedFtBurn, DecodedEventRow, DecodedEventColumns };