@hyperbridge/simplex 0.16.12 → 0.17.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/dist/sqlite.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as ActivityStore, L as LoggerContext, c as ActivityInsert, d as ActivityEvent, z as OrderSummary, O as OrderHistoryPage, W as WalletTx, B as BidStore, n as BidInsert, i as StoredBid, p as LimitOrderHold, k as BidStats, e as LimitOrderStore, q as LimitOrderInsert, f as LimitOrder, g as LimitOrderFilter, r as LimitOrderPosting, t as LimitOrderStatus, o as LimitOrderFillInsert, h as LimitOrderFill, l as StateStore, R as RuntimeState, S as SimplexDataStore } from './types-B5zkFhxR.js';
1
+ import { A as ActivityStore, L as LoggerContext, c as ActivityInsert, d as ActivityEvent, D as OrderSummary, O as OrderHistoryPage, W as WalletTx, B as BidStore, n as BidInsert, i as StoredBid, r as LimitOrderHold, k as BidStats, I as InventoryStore, o as InventorySnapshot, e as LimitOrderStore, s as LimitOrderInsert, f as LimitOrder, g as LimitOrderFilter, t as LimitOrderPosting, v as LimitOrderStatus, p as LimitOrderFillInsert, q as LimitOrderFillRecord, h as LimitOrderFill, l as StateStore, R as RuntimeState, S as SimplexDataStore } from './types-BPyUX8qu.js';
2
2
  import { DatabaseSync } from 'node:sqlite';
3
3
  import 'pino';
4
4
 
@@ -51,6 +51,22 @@ declare class SqliteBidStore implements BidStore {
51
51
  recent(limit?: number): Promise<StoredBid[]>;
52
52
  }
53
53
 
54
+ /**
55
+ * SQLite-backed {@link InventoryStore}, in `activity.db` beside the rest of the history.
56
+ *
57
+ * One row per snapshot, with the balances as a JSON object rather than a row per token: a
58
+ * snapshot is only ever read whole, and the set of tokens a solver holds changes over time.
59
+ * A database written before snapshots existed simply gains the table, with nothing in it.
60
+ */
61
+ declare class SqliteInventoryStore implements InventoryStore {
62
+ private db;
63
+ constructor(db: DatabaseSync);
64
+ private toSnapshot;
65
+ record(balances: Record<string, number>): Promise<void>;
66
+ latest(): Promise<InventorySnapshot | null>;
67
+ since(from: Date): Promise<InventorySnapshot[]>;
68
+ }
69
+
54
70
  declare class SqliteLimitOrderStore implements LimitOrderStore {
55
71
  private db;
56
72
  private logger;
@@ -67,6 +83,7 @@ declare class SqliteLimitOrderStore implements LimitOrderStore {
67
83
  reserve(id: string, amount: string): Promise<boolean>;
68
84
  transaction<T>(settle: () => Promise<T>): Promise<T>;
69
85
  recordFill(fill: LimitOrderFillInsert): Promise<void>;
86
+ fillHistory(): Promise<LimitOrderFillRecord[]>;
70
87
  fills(limitOrderId: string, limit?: number): Promise<LimitOrderFill[]>;
71
88
  drawDown(id: string, amount: string): Promise<LimitOrder | null>;
72
89
  clampRemaining(id: string, room: string): Promise<LimitOrder | null>;
@@ -134,6 +151,7 @@ declare class SqliteStateStore implements StateStore {
134
151
  * `activity.db`) so an existing data directory written by an earlier version is
135
152
  * picked up unchanged. Operator state and limit orders ride in `bids.db` beside
136
153
  * the bids; a `runtime-state.json` from before that is imported once and deleted.
154
+ * Inventory snapshots ride in `activity.db`, which is the history.
137
155
  *
138
156
  * Built on `node:sqlite`, so there is nothing to install and nothing to
139
157
  * compile — the engine ships inside the Node runtime. That is why the package
@@ -145,6 +163,7 @@ declare class SqliteDataStore implements SimplexDataStore {
145
163
  readonly activity: ActivityStore;
146
164
  readonly state: StateStore;
147
165
  readonly limitOrders: LimitOrderStore;
166
+ readonly inventory: InventoryStore;
148
167
  private databases;
149
168
  private logger;
150
169
  constructor(dataDir: string, loggers?: LoggerContext);
@@ -168,4 +187,4 @@ declare class SqliteDataStore implements SimplexDataStore {
168
187
  close(): Promise<void>;
169
188
  }
170
189
 
171
- export { SqliteActivityStore, SqliteBidStore, SqliteDataStore, SqliteLimitOrderStore, SqliteStateStore };
190
+ export { SqliteActivityStore, SqliteBidStore, SqliteDataStore, SqliteInventoryStore, SqliteLimitOrderStore, SqliteStateStore };
package/dist/sqlite.js CHANGED
@@ -616,6 +616,39 @@ var SqliteBidStore = class {
616
616
  }
617
617
  };
618
618
 
619
+ // src/data/sqlite/inventory.ts
620
+ var SqliteInventoryStore = class {
621
+ constructor(db) {
622
+ this.db = db;
623
+ this.db.exec(`
624
+ CREATE TABLE IF NOT EXISTS inventory_snapshots (
625
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
626
+ taken_at TEXT NOT NULL DEFAULT (datetime('now')),
627
+ balances TEXT NOT NULL
628
+ );
629
+
630
+ CREATE INDEX IF NOT EXISTS idx_inventory_snapshots_taken_at ON inventory_snapshots(taken_at);
631
+ `);
632
+ }
633
+ toSnapshot(row) {
634
+ return { id: row.id, takenAt: row.takenAt, balances: JSON.parse(row.balances) };
635
+ }
636
+ async record(balances) {
637
+ this.db.prepare("INSERT INTO inventory_snapshots (balances) VALUES (?)").run(JSON.stringify(balances));
638
+ }
639
+ async latest() {
640
+ const row = this.db.prepare("SELECT id, taken_at as takenAt, balances FROM inventory_snapshots ORDER BY id DESC LIMIT 1").get();
641
+ return row ? this.toSnapshot(row) : null;
642
+ }
643
+ async since(from) {
644
+ const cutoff = from.toISOString().replace("T", " ").replace(/\.\d{3}Z$/, "");
645
+ const rows = this.db.prepare(
646
+ "SELECT id, taken_at as takenAt, balances FROM inventory_snapshots WHERE taken_at >= ? ORDER BY taken_at, id"
647
+ ).all(cutoff);
648
+ return rows.map((row) => this.toSnapshot(row));
649
+ }
650
+ };
651
+
619
652
  // src/data/sqlite/limit-orders.ts
620
653
  var LIMIT_ORDER_COLUMNS = `
621
654
  id,
@@ -634,6 +667,7 @@ var LIMIT_ORDER_COLUMNS = `
634
667
  status,
635
668
  commitment,
636
669
  order_nonce as orderNonce,
670
+ entry_point as entryPoint,
637
671
  book_expires_at as bookExpiresAt,
638
672
  book_price as bookPrice,
639
673
  last_error as lastError,
@@ -670,6 +704,7 @@ var SqliteLimitOrderStore = class {
670
704
  status TEXT NOT NULL,
671
705
  commitment TEXT,
672
706
  order_nonce TEXT NOT NULL DEFAULT '0',
707
+ entry_point TEXT,
673
708
  book_expires_at TEXT,
674
709
  book_price TEXT,
675
710
  last_error TEXT,
@@ -687,12 +722,21 @@ var SqliteLimitOrderStore = class {
687
722
  commitment TEXT NOT NULL,
688
723
  bid TEXT,
689
724
  amount TEXT NOT NULL,
725
+ amount_in TEXT,
690
726
  transaction_hash TEXT,
691
727
  filled_at TEXT NOT NULL DEFAULT (datetime('now'))
692
728
  );
693
729
 
694
730
  CREATE INDEX IF NOT EXISTS idx_limit_order_fills_order ON limit_order_fills(limit_order_id);
695
731
  `);
732
+ if (!columnNames(this.db, "limit_orders").has("entry_point")) {
733
+ this.db.exec("ALTER TABLE limit_orders ADD COLUMN entry_point TEXT");
734
+ this.logger.info({ column: "entry_point" }, "Migrated limit order storage schema");
735
+ }
736
+ if (!columnNames(this.db, "limit_order_fills").has("amount_in")) {
737
+ this.db.exec("ALTER TABLE limit_order_fills ADD COLUMN amount_in TEXT");
738
+ this.logger.info({ column: "amount_in" }, "Migrated limit order fill schema");
739
+ }
696
740
  }
697
741
  // biome-ignore lint/suspicious/noExplicitAny: raw sqlite row
698
742
  toLimitOrder(row) {
@@ -753,13 +797,14 @@ var SqliteLimitOrderStore = class {
753
797
  const result = this.db.prepare(`
754
798
  UPDATE limit_orders
755
799
  SET commitment = ?, book_expires_at = ?, book_price = ?, order_nonce = ?,
756
- status = ?, last_error = ?, updated_at = datetime('now')
800
+ entry_point = ?, status = ?, last_error = ?, updated_at = datetime('now')
757
801
  WHERE id = ?${statusGuard(only)}
758
802
  `).run(
759
803
  posting.commitment,
760
804
  posting.bookExpiresAt,
761
805
  posting.bookPrice,
762
806
  posting.orderNonce,
807
+ posting.entryPoint,
763
808
  posting.status,
764
809
  posting.lastError,
765
810
  id,
@@ -802,12 +847,27 @@ var SqliteLimitOrderStore = class {
802
847
  }
803
848
  async recordFill(fill) {
804
849
  this.db.prepare(
805
- "INSERT INTO limit_order_fills (limit_order_id, commitment, bid, amount, transaction_hash) VALUES (?, ?, ?, ?, ?)"
806
- ).run(fill.limitOrderId, fill.commitment, fill.bid ?? null, fill.amount, fill.transactionHash ?? null);
850
+ "INSERT INTO limit_order_fills (limit_order_id, commitment, bid, amount, amount_in, transaction_hash) VALUES (?, ?, ?, ?, ?, ?)"
851
+ ).run(
852
+ fill.limitOrderId,
853
+ fill.commitment,
854
+ fill.bid ?? null,
855
+ fill.amount,
856
+ fill.amountIn ?? null,
857
+ fill.transactionHash ?? null
858
+ );
859
+ }
860
+ async fillHistory() {
861
+ return this.db.prepare(
862
+ `SELECT f.id, f.limit_order_id as limitOrderId, o.book, o.base, o.quote, o.side, o.price,
863
+ f.amount, f.amount_in as amountIn, f.filled_at as filledAt
864
+ FROM limit_order_fills f JOIN limit_orders o ON o.id = f.limit_order_id
865
+ ORDER BY f.filled_at, f.id`
866
+ ).all();
807
867
  }
808
868
  async fills(limitOrderId, limit = 100) {
809
869
  return this.db.prepare(
810
- `SELECT id, limit_order_id as limitOrderId, commitment, bid, amount, transaction_hash as transactionHash,
870
+ `SELECT id, limit_order_id as limitOrderId, commitment, bid, amount, amount_in as amountIn, transaction_hash as transactionHash,
811
871
  filled_at as filledAt
812
872
  FROM limit_order_fills WHERE limit_order_id = ? ORDER BY id DESC LIMIT ?`
813
873
  ).all(limitOrderId, Math.min(Math.max(limit, 1), 500));
@@ -994,6 +1054,7 @@ var SqliteDataStore = class {
994
1054
  this.activity = new SqliteActivityStore(activityDb, loggers);
995
1055
  this.state = new SqliteStateStore(bidsDb, dataDir, loggers);
996
1056
  this.limitOrders = new SqliteLimitOrderStore(bidsDb, loggers);
1057
+ this.inventory = new SqliteInventoryStore(activityDb);
997
1058
  this.logger.info({ dataDir }, "SQLite data store opened");
998
1059
  }
999
1060
  /**
@@ -1028,6 +1089,7 @@ export {
1028
1089
  SqliteActivityStore,
1029
1090
  SqliteBidStore,
1030
1091
  SqliteDataStore,
1092
+ SqliteInventoryStore,
1031
1093
  SqliteLimitOrderStore,
1032
1094
  SqliteStateStore
1033
1095
  };