@secondlayer/shared 6.2.0 → 6.3.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.
@@ -316,6 +316,208 @@ interface ChainReorgsTable {
316
316
  new_canonical_event_index: number;
317
317
  created_at: Generated<Date>;
318
318
  }
319
+ type Pox4FunctionName = "stack-stx" | "delegate-stx" | "stack-extend" | "stack-increase" | "revoke-delegate-stx" | "delegate-stack-stx" | "delegate-stack-extend" | "delegate-stack-increase" | "stack-aggregation-commit" | "stack-aggregation-commit-indexed" | "stack-aggregation-increase" | "set-signer-key-authorization";
320
+ interface Pox4CallsTable {
321
+ cursor: string;
322
+ block_height: number;
323
+ block_time: Date;
324
+ burn_block_height: number;
325
+ tx_id: string;
326
+ tx_index: number;
327
+ function_name: Pox4FunctionName;
328
+ caller: string;
329
+ stacker: string | null;
330
+ delegate_to: string | null;
331
+ amount_ustx: string | null;
332
+ lock_period: number | null;
333
+ pox_addr_version: number | null;
334
+ pox_addr_hashbytes: string | null;
335
+ pox_addr_btc: string | null;
336
+ start_cycle: number | null;
337
+ end_cycle: number | null;
338
+ signer_key: string | null;
339
+ signer_signature: string | null;
340
+ auth_id: string | null;
341
+ max_amount: string | null;
342
+ reward_cycle: number | null;
343
+ aggregated_amount_ustx: string | null;
344
+ aggregated_signer_index: number | null;
345
+ auth_period: number | null;
346
+ auth_topic: string | null;
347
+ auth_allowed: boolean | null;
348
+ result_ok: boolean;
349
+ result_raw: string;
350
+ canonical: Generated<boolean>;
351
+ source_cursor: string;
352
+ created_at: Generated<Date>;
353
+ }
354
+ interface Pox4CyclesDailyTable {
355
+ date: string;
356
+ reward_cycle: number;
357
+ total_stacked_ustx: Generated<string>;
358
+ solo_stackers: Generated<number>;
359
+ delegated_principals: Generated<number>;
360
+ unique_pools: Generated<number>;
361
+ unique_signers: Generated<number>;
362
+ calls_today: Generated<number>;
363
+ updated_at: Generated<Date>;
364
+ }
365
+ interface Pox4SignersDailyTable {
366
+ date: string;
367
+ reward_cycle: number;
368
+ signer_key: string;
369
+ weight_ustx: Generated<string>;
370
+ stacker_count: Generated<number>;
371
+ aggregation_calls: Generated<number>;
372
+ updated_at: Generated<Date>;
373
+ }
374
+ type SbtcEventTopic = "completed-deposit" | "withdrawal-create" | "withdrawal-accept" | "withdrawal-reject" | "key-rotation" | "update-protocol-contract";
375
+ interface SbtcEventsTable {
376
+ cursor: string;
377
+ block_height: number;
378
+ block_time: Date;
379
+ tx_id: string;
380
+ tx_index: number;
381
+ event_index: number;
382
+ topic: SbtcEventTopic;
383
+ request_id: number | null;
384
+ amount: string | null;
385
+ sender: string | null;
386
+ recipient_btc_version: number | null;
387
+ recipient_btc_hashbytes: string | null;
388
+ bitcoin_txid: string | null;
389
+ output_index: number | null;
390
+ sweep_txid: string | null;
391
+ burn_hash: string | null;
392
+ burn_height: number | null;
393
+ signer_bitmap: string | null;
394
+ max_fee: string | null;
395
+ fee: string | null;
396
+ block_height_at_request: number | null;
397
+ governance_contract_type: number | null;
398
+ governance_new_contract: string | null;
399
+ signer_aggregate_pubkey: string | null;
400
+ signer_threshold: number | null;
401
+ signer_address: string | null;
402
+ signer_keys_count: number | null;
403
+ canonical: Generated<boolean>;
404
+ source_cursor: string;
405
+ created_at: Generated<Date>;
406
+ }
407
+ type SbtcTokenEventType = "transfer" | "mint" | "burn";
408
+ interface SbtcTokenEventsTable {
409
+ cursor: string;
410
+ block_height: number;
411
+ block_time: Date;
412
+ tx_id: string;
413
+ tx_index: number;
414
+ event_index: number;
415
+ event_type: SbtcTokenEventType;
416
+ sender: string | null;
417
+ recipient: string | null;
418
+ amount: string;
419
+ memo: string | null;
420
+ canonical: Generated<boolean>;
421
+ source_cursor: string;
422
+ created_at: Generated<Date>;
423
+ }
424
+ interface SbtcSupplySnapshotsTable {
425
+ date: string;
426
+ total_supply: Generated<string>;
427
+ mints_today: Generated<string>;
428
+ burns_today: Generated<string>;
429
+ deposit_count: Generated<number>;
430
+ withdrawal_create_count: Generated<number>;
431
+ withdrawal_accept_count: Generated<number>;
432
+ withdrawal_reject_count: Generated<number>;
433
+ updated_at: Generated<Date>;
434
+ }
435
+ type BnsNameEventTopic = "new-name" | "transfer-name" | "renew-name" | "burn-name" | "new-airdrop";
436
+ interface BnsNameEventsTable {
437
+ cursor: string;
438
+ block_height: number;
439
+ block_time: Date;
440
+ tx_id: string;
441
+ tx_index: number;
442
+ event_index: number;
443
+ topic: BnsNameEventTopic;
444
+ namespace: string;
445
+ name: string;
446
+ fqn: string;
447
+ owner: string | null;
448
+ bns_id: string;
449
+ registered_at: number | null;
450
+ imported_at: number | null;
451
+ renewal_height: number | null;
452
+ stx_burn: string | null;
453
+ preordered_by: string | null;
454
+ hashed_salted_fqn_preorder: string | null;
455
+ canonical: Generated<boolean>;
456
+ source_cursor: string;
457
+ created_at: Generated<Date>;
458
+ }
459
+ type BnsNamespaceEventStatus = "launch" | "transfer-manager" | "freeze-manager" | "update-price-manager" | "freeze-price-manager" | "turn-off-manager-transfers";
460
+ interface BnsNamespaceEventsTable {
461
+ cursor: string;
462
+ block_height: number;
463
+ block_time: Date;
464
+ tx_id: string;
465
+ tx_index: number;
466
+ event_index: number;
467
+ status: BnsNamespaceEventStatus;
468
+ namespace: string;
469
+ manager: string | null;
470
+ manager_frozen: boolean | null;
471
+ manager_transfers_disabled: boolean | null;
472
+ price_function: string | null;
473
+ price_frozen: boolean | null;
474
+ lifetime: number | null;
475
+ revealed_at: number | null;
476
+ launched_at: number | null;
477
+ canonical: Generated<boolean>;
478
+ source_cursor: string;
479
+ created_at: Generated<Date>;
480
+ }
481
+ type BnsMarketplaceAction = "list-in-ustx" | "unlist-in-ustx" | "buy-in-ustx";
482
+ interface BnsMarketplaceEventsTable {
483
+ cursor: string;
484
+ block_height: number;
485
+ block_time: Date;
486
+ tx_id: string;
487
+ tx_index: number;
488
+ event_index: number;
489
+ action: BnsMarketplaceAction;
490
+ bns_id: string;
491
+ price_ustx: string | null;
492
+ commission: string | null;
493
+ canonical: Generated<boolean>;
494
+ source_cursor: string;
495
+ created_at: Generated<Date>;
496
+ }
497
+ interface BnsNamesTable {
498
+ fqn: string;
499
+ namespace: string;
500
+ name: string;
501
+ owner: string;
502
+ bns_id: string;
503
+ registered_at: number | null;
504
+ renewal_height: number | null;
505
+ last_event_cursor: string;
506
+ last_event_at: Date;
507
+ updated_at: Generated<Date>;
508
+ }
509
+ interface BnsNamespacesTable {
510
+ namespace: string;
511
+ manager: string | null;
512
+ manager_frozen: Generated<boolean>;
513
+ price_frozen: Generated<boolean>;
514
+ lifetime: number | null;
515
+ launched_at: number | null;
516
+ last_event_cursor: string;
517
+ last_event_at: Date;
518
+ name_count: Generated<number>;
519
+ updated_at: Generated<Date>;
520
+ }
319
521
  interface Database {
320
522
  blocks: BlocksTable;
321
523
  transactions: TransactionsTable;
@@ -354,6 +556,17 @@ interface Database {
354
556
  decoded_events: DecodedEventsTable;
355
557
  l2_decoder_checkpoints: L2DecoderCheckpointsTable;
356
558
  chain_reorgs: ChainReorgsTable;
559
+ pox4_calls: Pox4CallsTable;
560
+ pox4_cycles_daily: Pox4CyclesDailyTable;
561
+ pox4_signers_daily: Pox4SignersDailyTable;
562
+ sbtc_events: SbtcEventsTable;
563
+ sbtc_token_events: SbtcTokenEventsTable;
564
+ sbtc_supply_snapshots: SbtcSupplySnapshotsTable;
565
+ bns_name_events: BnsNameEventsTable;
566
+ bns_namespace_events: BnsNamespaceEventsTable;
567
+ bns_marketplace_events: BnsMarketplaceEventsTable;
568
+ bns_names: BnsNamesTable;
569
+ bns_namespaces: BnsNamespacesTable;
357
570
  }
358
571
  type TenantStatus = "provisioning" | "active" | "limit_warning" | "paused_limit" | "suspended" | "error" | "deleted";
359
572
  interface TenantsTable {
@@ -0,0 +1,128 @@
1
+ import { type Kysely, sql } from "kysely";
2
+
3
+ export async function up(db: Kysely<unknown>): Promise<void> {
4
+ await sql`SET lock_timeout = '30s'`.execute(db);
5
+
6
+ // Per-call decoded view of pox-4 contract calls. The PoX-4 contract emits
7
+ // no print events; we decode tx-grain rows from the indexer's transactions
8
+ // table when contract_id = pox-4 and the call succeeded.
9
+ await sql`
10
+ CREATE TABLE IF NOT EXISTS pox4_calls (
11
+ cursor TEXT PRIMARY KEY,
12
+ block_height BIGINT NOT NULL,
13
+ block_time TIMESTAMPTZ NOT NULL,
14
+ burn_block_height BIGINT NOT NULL,
15
+ tx_id TEXT NOT NULL,
16
+ tx_index INTEGER NOT NULL,
17
+ function_name TEXT NOT NULL,
18
+ caller TEXT NOT NULL,
19
+ stacker TEXT,
20
+ delegate_to TEXT,
21
+ amount_ustx TEXT,
22
+ lock_period INTEGER,
23
+ pox_addr_version INTEGER,
24
+ pox_addr_hashbytes TEXT,
25
+ pox_addr_btc TEXT,
26
+ start_cycle INTEGER,
27
+ end_cycle INTEGER,
28
+ signer_key TEXT,
29
+ signer_signature TEXT,
30
+ auth_id TEXT,
31
+ max_amount TEXT,
32
+ reward_cycle INTEGER,
33
+ aggregated_amount_ustx TEXT,
34
+ aggregated_signer_index INTEGER,
35
+ auth_period INTEGER,
36
+ auth_topic TEXT,
37
+ auth_allowed BOOLEAN,
38
+ result_ok BOOLEAN NOT NULL,
39
+ result_raw TEXT NOT NULL,
40
+ canonical BOOLEAN NOT NULL DEFAULT true,
41
+ source_cursor TEXT NOT NULL,
42
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
43
+ CONSTRAINT pox4_calls_function_check CHECK (function_name IN (
44
+ 'stack-stx',
45
+ 'delegate-stx',
46
+ 'stack-extend',
47
+ 'stack-increase',
48
+ 'revoke-delegate-stx',
49
+ 'delegate-stack-stx',
50
+ 'delegate-stack-extend',
51
+ 'delegate-stack-increase',
52
+ 'stack-aggregation-commit',
53
+ 'stack-aggregation-commit-indexed',
54
+ 'stack-aggregation-increase',
55
+ 'set-signer-key-authorization'
56
+ ))
57
+ )
58
+ `.execute(db);
59
+
60
+ await sql`CREATE INDEX IF NOT EXISTS pox4_calls_canonical_height_idx ON pox4_calls (canonical, block_height)`.execute(
61
+ db,
62
+ );
63
+ await sql`CREATE INDEX IF NOT EXISTS pox4_calls_stacker_height_idx ON pox4_calls (stacker, block_height) WHERE stacker IS NOT NULL`.execute(
64
+ db,
65
+ );
66
+ await sql`CREATE INDEX IF NOT EXISTS pox4_calls_delegate_to_height_idx ON pox4_calls (delegate_to, block_height) WHERE delegate_to IS NOT NULL`.execute(
67
+ db,
68
+ );
69
+ await sql`CREATE INDEX IF NOT EXISTS pox4_calls_signer_key_height_idx ON pox4_calls (signer_key, block_height) WHERE signer_key IS NOT NULL`.execute(
70
+ db,
71
+ );
72
+ await sql`CREATE INDEX IF NOT EXISTS pox4_calls_reward_cycle_function_idx ON pox4_calls (reward_cycle, function_name) WHERE reward_cycle IS NOT NULL`.execute(
73
+ db,
74
+ );
75
+ await sql`CREATE INDEX IF NOT EXISTS pox4_calls_cycle_range_idx ON pox4_calls (start_cycle, end_cycle) WHERE start_cycle IS NOT NULL`.execute(
76
+ db,
77
+ );
78
+ await sql`CREATE INDEX IF NOT EXISTS pox4_calls_function_height_idx ON pox4_calls (function_name, block_height)`.execute(
79
+ db,
80
+ );
81
+
82
+ // Daily rollup per (date, reward_cycle) — derived from pox4_calls.
83
+ await sql`
84
+ CREATE TABLE IF NOT EXISTS pox4_cycles_daily (
85
+ date TEXT NOT NULL,
86
+ reward_cycle INTEGER NOT NULL,
87
+ total_stacked_ustx TEXT NOT NULL DEFAULT '0',
88
+ solo_stackers INTEGER NOT NULL DEFAULT 0,
89
+ delegated_principals INTEGER NOT NULL DEFAULT 0,
90
+ unique_pools INTEGER NOT NULL DEFAULT 0,
91
+ unique_signers INTEGER NOT NULL DEFAULT 0,
92
+ calls_today INTEGER NOT NULL DEFAULT 0,
93
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
94
+ PRIMARY KEY (date, reward_cycle)
95
+ )
96
+ `.execute(db);
97
+
98
+ await sql`CREATE INDEX IF NOT EXISTS pox4_cycles_daily_cycle_idx ON pox4_cycles_daily (reward_cycle, date)`.execute(
99
+ db,
100
+ );
101
+
102
+ // Daily rollup per (date, reward_cycle, signer_key).
103
+ await sql`
104
+ CREATE TABLE IF NOT EXISTS pox4_signers_daily (
105
+ date TEXT NOT NULL,
106
+ reward_cycle INTEGER NOT NULL,
107
+ signer_key TEXT NOT NULL,
108
+ weight_ustx TEXT NOT NULL DEFAULT '0',
109
+ stacker_count INTEGER NOT NULL DEFAULT 0,
110
+ aggregation_calls INTEGER NOT NULL DEFAULT 0,
111
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
112
+ PRIMARY KEY (date, reward_cycle, signer_key)
113
+ )
114
+ `.execute(db);
115
+
116
+ await sql`CREATE INDEX IF NOT EXISTS pox4_signers_daily_cycle_idx ON pox4_signers_daily (reward_cycle, date)`.execute(
117
+ db,
118
+ );
119
+ await sql`CREATE INDEX IF NOT EXISTS pox4_signers_daily_signer_idx ON pox4_signers_daily (signer_key, date)`.execute(
120
+ db,
121
+ );
122
+ }
123
+
124
+ export async function down(db: Kysely<unknown>): Promise<void> {
125
+ await sql`DROP TABLE IF EXISTS pox4_signers_daily`.execute(db);
126
+ await sql`DROP TABLE IF EXISTS pox4_cycles_daily`.execute(db);
127
+ await sql`DROP TABLE IF EXISTS pox4_calls`.execute(db);
128
+ }
@@ -0,0 +1,126 @@
1
+ import { type Kysely, sql } from "kysely";
2
+
3
+ export async function up(db: Kysely<unknown>): Promise<void> {
4
+ await sql`SET lock_timeout = '30s'`.execute(db);
5
+
6
+ // Protocol-state events from sbtc-registry: completed-deposit,
7
+ // withdrawal-create, withdrawal-accept, withdrawal-reject, key-rotation,
8
+ // update-protocol-contract.
9
+ await sql`
10
+ CREATE TABLE IF NOT EXISTS sbtc_events (
11
+ cursor TEXT PRIMARY KEY,
12
+ block_height BIGINT NOT NULL,
13
+ block_time TIMESTAMPTZ NOT NULL,
14
+ tx_id TEXT NOT NULL,
15
+ tx_index INTEGER NOT NULL,
16
+ event_index INTEGER NOT NULL,
17
+ topic TEXT NOT NULL,
18
+ request_id BIGINT,
19
+ amount TEXT,
20
+ sender TEXT,
21
+ recipient_btc_version INTEGER,
22
+ recipient_btc_hashbytes TEXT,
23
+ bitcoin_txid TEXT,
24
+ output_index INTEGER,
25
+ sweep_txid TEXT,
26
+ burn_hash TEXT,
27
+ burn_height BIGINT,
28
+ signer_bitmap TEXT,
29
+ max_fee TEXT,
30
+ fee TEXT,
31
+ block_height_at_request BIGINT,
32
+ governance_contract_type INTEGER,
33
+ governance_new_contract TEXT,
34
+ signer_aggregate_pubkey TEXT,
35
+ signer_threshold INTEGER,
36
+ signer_address TEXT,
37
+ signer_keys_count INTEGER,
38
+ canonical BOOLEAN NOT NULL DEFAULT true,
39
+ source_cursor TEXT NOT NULL,
40
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
41
+ CONSTRAINT sbtc_events_topic_check CHECK (topic IN (
42
+ 'completed-deposit',
43
+ 'withdrawal-create',
44
+ 'withdrawal-accept',
45
+ 'withdrawal-reject',
46
+ 'key-rotation',
47
+ 'update-protocol-contract'
48
+ ))
49
+ )
50
+ `.execute(db);
51
+
52
+ await sql`CREATE INDEX IF NOT EXISTS sbtc_events_canonical_height_idx ON sbtc_events (canonical, block_height)`.execute(
53
+ db,
54
+ );
55
+ await sql`CREATE INDEX IF NOT EXISTS sbtc_events_topic_height_idx ON sbtc_events (topic, block_height)`.execute(
56
+ db,
57
+ );
58
+ await sql`CREATE INDEX IF NOT EXISTS sbtc_events_request_id_idx ON sbtc_events (request_id) WHERE request_id IS NOT NULL`.execute(
59
+ db,
60
+ );
61
+ await sql`CREATE INDEX IF NOT EXISTS sbtc_events_bitcoin_txid_idx ON sbtc_events (bitcoin_txid) WHERE bitcoin_txid IS NOT NULL`.execute(
62
+ db,
63
+ );
64
+ await sql`CREATE INDEX IF NOT EXISTS sbtc_events_sender_height_idx ON sbtc_events (sender, block_height) WHERE sender IS NOT NULL`.execute(
65
+ db,
66
+ );
67
+
68
+ // SIP-010 events on sbtc-token: transfer / mint / burn.
69
+ await sql`
70
+ CREATE TABLE IF NOT EXISTS sbtc_token_events (
71
+ cursor TEXT PRIMARY KEY,
72
+ block_height BIGINT NOT NULL,
73
+ block_time TIMESTAMPTZ NOT NULL,
74
+ tx_id TEXT NOT NULL,
75
+ tx_index INTEGER NOT NULL,
76
+ event_index INTEGER NOT NULL,
77
+ event_type TEXT NOT NULL,
78
+ sender TEXT,
79
+ recipient TEXT,
80
+ amount TEXT NOT NULL,
81
+ memo TEXT,
82
+ canonical BOOLEAN NOT NULL DEFAULT true,
83
+ source_cursor TEXT NOT NULL,
84
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
85
+ CONSTRAINT sbtc_token_events_type_check CHECK (event_type IN (
86
+ 'transfer',
87
+ 'mint',
88
+ 'burn'
89
+ ))
90
+ )
91
+ `.execute(db);
92
+
93
+ await sql`CREATE INDEX IF NOT EXISTS sbtc_token_events_canonical_height_idx ON sbtc_token_events (canonical, block_height)`.execute(
94
+ db,
95
+ );
96
+ await sql`CREATE INDEX IF NOT EXISTS sbtc_token_events_type_height_idx ON sbtc_token_events (event_type, block_height)`.execute(
97
+ db,
98
+ );
99
+ await sql`CREATE INDEX IF NOT EXISTS sbtc_token_events_sender_height_idx ON sbtc_token_events (sender, block_height) WHERE sender IS NOT NULL`.execute(
100
+ db,
101
+ );
102
+ await sql`CREATE INDEX IF NOT EXISTS sbtc_token_events_recipient_height_idx ON sbtc_token_events (recipient, block_height) WHERE recipient IS NOT NULL`.execute(
103
+ db,
104
+ );
105
+
106
+ // Daily supply rollup. Computed by the aggregator job.
107
+ await sql`
108
+ CREATE TABLE IF NOT EXISTS sbtc_supply_snapshots (
109
+ date TEXT PRIMARY KEY,
110
+ total_supply TEXT NOT NULL DEFAULT '0',
111
+ mints_today TEXT NOT NULL DEFAULT '0',
112
+ burns_today TEXT NOT NULL DEFAULT '0',
113
+ deposit_count INTEGER NOT NULL DEFAULT 0,
114
+ withdrawal_create_count INTEGER NOT NULL DEFAULT 0,
115
+ withdrawal_accept_count INTEGER NOT NULL DEFAULT 0,
116
+ withdrawal_reject_count INTEGER NOT NULL DEFAULT 0,
117
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
118
+ )
119
+ `.execute(db);
120
+ }
121
+
122
+ export async function down(db: Kysely<unknown>): Promise<void> {
123
+ await sql`DROP TABLE IF EXISTS sbtc_supply_snapshots`.execute(db);
124
+ await sql`DROP TABLE IF EXISTS sbtc_token_events`.execute(db);
125
+ await sql`DROP TABLE IF EXISTS sbtc_events`.execute(db);
126
+ }
@@ -0,0 +1,177 @@
1
+ import { type Kysely, sql } from "kysely";
2
+
3
+ export async function up(db: Kysely<unknown>): Promise<void> {
4
+ await sql`SET lock_timeout = '30s'`.execute(db);
5
+
6
+ // Name-lifecycle events from BNS-V2 (the `topic`-discriminated payloads):
7
+ // new-name, transfer-name, renew-name, burn-name, new-airdrop.
8
+ await sql`
9
+ CREATE TABLE IF NOT EXISTS bns_name_events (
10
+ cursor TEXT PRIMARY KEY,
11
+ block_height BIGINT NOT NULL,
12
+ block_time TIMESTAMPTZ NOT NULL,
13
+ tx_id TEXT NOT NULL,
14
+ tx_index INTEGER NOT NULL,
15
+ event_index INTEGER NOT NULL,
16
+ topic TEXT NOT NULL,
17
+ namespace TEXT NOT NULL,
18
+ name TEXT NOT NULL,
19
+ fqn TEXT NOT NULL,
20
+ owner TEXT,
21
+ bns_id TEXT NOT NULL,
22
+ registered_at BIGINT,
23
+ imported_at BIGINT,
24
+ renewal_height BIGINT,
25
+ stx_burn TEXT,
26
+ preordered_by TEXT,
27
+ hashed_salted_fqn_preorder TEXT,
28
+ canonical BOOLEAN NOT NULL DEFAULT true,
29
+ source_cursor TEXT NOT NULL,
30
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
31
+ CONSTRAINT bns_name_events_topic_check CHECK (topic IN (
32
+ 'new-name',
33
+ 'transfer-name',
34
+ 'renew-name',
35
+ 'burn-name',
36
+ 'new-airdrop'
37
+ ))
38
+ )
39
+ `.execute(db);
40
+
41
+ await sql`CREATE INDEX IF NOT EXISTS bns_name_events_canonical_height_idx ON bns_name_events (canonical, block_height)`.execute(
42
+ db,
43
+ );
44
+ await sql`CREATE INDEX IF NOT EXISTS bns_name_events_namespace_name_idx ON bns_name_events (namespace, name)`.execute(
45
+ db,
46
+ );
47
+ await sql`CREATE INDEX IF NOT EXISTS bns_name_events_owner_height_idx ON bns_name_events (owner, block_height) WHERE owner IS NOT NULL`.execute(
48
+ db,
49
+ );
50
+ await sql`CREATE INDEX IF NOT EXISTS bns_name_events_topic_height_idx ON bns_name_events (topic, block_height)`.execute(
51
+ db,
52
+ );
53
+ await sql`CREATE INDEX IF NOT EXISTS bns_name_events_bns_id_idx ON bns_name_events (bns_id)`.execute(
54
+ db,
55
+ );
56
+
57
+ // Namespace-lifecycle events (the `status`-discriminated payloads).
58
+ await sql`
59
+ CREATE TABLE IF NOT EXISTS bns_namespace_events (
60
+ cursor TEXT PRIMARY KEY,
61
+ block_height BIGINT NOT NULL,
62
+ block_time TIMESTAMPTZ NOT NULL,
63
+ tx_id TEXT NOT NULL,
64
+ tx_index INTEGER NOT NULL,
65
+ event_index INTEGER NOT NULL,
66
+ status TEXT NOT NULL,
67
+ namespace TEXT NOT NULL,
68
+ manager TEXT,
69
+ manager_frozen BOOLEAN,
70
+ manager_transfers_disabled BOOLEAN,
71
+ price_function TEXT,
72
+ price_frozen BOOLEAN,
73
+ lifetime BIGINT,
74
+ revealed_at BIGINT,
75
+ launched_at BIGINT,
76
+ canonical BOOLEAN NOT NULL DEFAULT true,
77
+ source_cursor TEXT NOT NULL,
78
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
79
+ CONSTRAINT bns_namespace_events_status_check CHECK (status IN (
80
+ 'launch',
81
+ 'transfer-manager',
82
+ 'freeze-manager',
83
+ 'update-price-manager',
84
+ 'freeze-price-manager',
85
+ 'turn-off-manager-transfers'
86
+ ))
87
+ )
88
+ `.execute(db);
89
+
90
+ await sql`CREATE INDEX IF NOT EXISTS bns_namespace_events_canonical_height_idx ON bns_namespace_events (canonical, block_height)`.execute(
91
+ db,
92
+ );
93
+ await sql`CREATE INDEX IF NOT EXISTS bns_namespace_events_namespace_status_idx ON bns_namespace_events (namespace, status)`.execute(
94
+ db,
95
+ );
96
+
97
+ // Marketplace events (the `a`-discriminated payloads on the BNS-V2 NFT).
98
+ await sql`
99
+ CREATE TABLE IF NOT EXISTS bns_marketplace_events (
100
+ cursor TEXT PRIMARY KEY,
101
+ block_height BIGINT NOT NULL,
102
+ block_time TIMESTAMPTZ NOT NULL,
103
+ tx_id TEXT NOT NULL,
104
+ tx_index INTEGER NOT NULL,
105
+ event_index INTEGER NOT NULL,
106
+ action TEXT NOT NULL,
107
+ bns_id TEXT NOT NULL,
108
+ price_ustx TEXT,
109
+ commission TEXT,
110
+ canonical BOOLEAN NOT NULL DEFAULT true,
111
+ source_cursor TEXT NOT NULL,
112
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
113
+ CONSTRAINT bns_marketplace_events_action_check CHECK (action IN (
114
+ 'list-in-ustx',
115
+ 'unlist-in-ustx',
116
+ 'buy-in-ustx'
117
+ ))
118
+ )
119
+ `.execute(db);
120
+
121
+ await sql`CREATE INDEX IF NOT EXISTS bns_marketplace_events_canonical_height_idx ON bns_marketplace_events (canonical, block_height)`.execute(
122
+ db,
123
+ );
124
+ await sql`CREATE INDEX IF NOT EXISTS bns_marketplace_events_bns_id_idx ON bns_marketplace_events (bns_id)`.execute(
125
+ db,
126
+ );
127
+
128
+ // Current-state projection of names (decoder maintains via upsert).
129
+ await sql`
130
+ CREATE TABLE IF NOT EXISTS bns_names (
131
+ fqn TEXT PRIMARY KEY,
132
+ namespace TEXT NOT NULL,
133
+ name TEXT NOT NULL,
134
+ owner TEXT NOT NULL,
135
+ bns_id TEXT NOT NULL,
136
+ registered_at BIGINT,
137
+ renewal_height BIGINT,
138
+ last_event_cursor TEXT NOT NULL,
139
+ last_event_at TIMESTAMPTZ NOT NULL,
140
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
141
+ )
142
+ `.execute(db);
143
+
144
+ await sql`CREATE INDEX IF NOT EXISTS bns_names_owner_idx ON bns_names (owner)`.execute(
145
+ db,
146
+ );
147
+ await sql`CREATE INDEX IF NOT EXISTS bns_names_namespace_registered_idx ON bns_names (namespace, registered_at)`.execute(
148
+ db,
149
+ );
150
+ await sql`CREATE INDEX IF NOT EXISTS bns_names_renewal_height_idx ON bns_names (renewal_height) WHERE renewal_height IS NOT NULL`.execute(
151
+ db,
152
+ );
153
+
154
+ // Current-state projection of namespaces.
155
+ await sql`
156
+ CREATE TABLE IF NOT EXISTS bns_namespaces (
157
+ namespace TEXT PRIMARY KEY,
158
+ manager TEXT,
159
+ manager_frozen BOOLEAN NOT NULL DEFAULT false,
160
+ price_frozen BOOLEAN NOT NULL DEFAULT false,
161
+ lifetime BIGINT,
162
+ launched_at BIGINT,
163
+ last_event_cursor TEXT NOT NULL,
164
+ last_event_at TIMESTAMPTZ NOT NULL,
165
+ name_count INTEGER NOT NULL DEFAULT 0,
166
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
167
+ )
168
+ `.execute(db);
169
+ }
170
+
171
+ export async function down(db: Kysely<unknown>): Promise<void> {
172
+ await sql`DROP TABLE IF EXISTS bns_namespaces`.execute(db);
173
+ await sql`DROP TABLE IF EXISTS bns_names`.execute(db);
174
+ await sql`DROP TABLE IF EXISTS bns_marketplace_events`.execute(db);
175
+ await sql`DROP TABLE IF EXISTS bns_namespace_events`.execute(db);
176
+ await sql`DROP TABLE IF EXISTS bns_name_events`.execute(db);
177
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@secondlayer/shared",
3
- "version": "6.2.0",
3
+ "version": "6.3.0",
4
4
  "type": "module",
5
5
  "main": "./dist/src/index.js",
6
6
  "types": "./dist/src/index.d.ts",
@@ -188,7 +188,7 @@
188
188
  "prepublishOnly": "bun run build"
189
189
  },
190
190
  "dependencies": {
191
- "@secondlayer/stacks": "^2.0.1",
191
+ "@secondlayer/stacks": "^2.1.0",
192
192
  "kysely": "0.28.15",
193
193
  "kysely-postgres-js": "3.0.0",
194
194
  "postgres": "^3.4.6",