@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/bin/simplex.js +1728 -409
- package/dist/bin/simplex.js.map +1 -1
- package/dist/index.cjs +1086 -145
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +224 -23
- package/dist/index.d.ts +224 -23
- package/dist/index.js +1080 -134
- package/dist/index.js.map +1 -1
- package/dist/sqlite.cjs +67 -4
- package/dist/sqlite.cjs.map +1 -1
- package/dist/sqlite.d.cts +21 -2
- package/dist/sqlite.d.ts +21 -2
- package/dist/sqlite.js +66 -4
- package/dist/sqlite.js.map +1 -1
- package/dist/{types-B5zkFhxR.d.cts → types-BPyUX8qu.d.cts} +64 -1
- package/dist/{types-B5zkFhxR.d.ts → types-BPyUX8qu.d.ts} +64 -1
- package/dist/ui/assets/Novatica-Medium-CjNgGPEL.ttf +0 -0
- package/dist/ui/assets/index-CK8E6aPx.css +1 -0
- package/dist/ui/assets/index-D8DLeEH0.js +106 -0
- package/dist/ui/index.html +2 -2
- package/package.json +5 -5
- package/dist/ui/assets/index-QU1Ik7IX.js +0 -106
- package/dist/ui/assets/index-XKHMOpY2.css +0 -1
package/dist/sqlite.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as ActivityStore, L as LoggerContext, c as ActivityInsert, d as ActivityEvent,
|
|
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(
|
|
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
|
};
|