@bsv/overlay 2.2.1 → 2.2.7
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.txt +57 -27
- package/README.md +102 -269
- package/dist/cjs/mod.d.ts +15 -0
- package/dist/cjs/mod.d.ts.map +1 -0
- package/dist/cjs/mod.js +4 -1
- package/dist/cjs/mod.js.map +1 -1
- package/dist/cjs/package.json +41 -13
- package/dist/cjs/src/Advertisement.d.ts +9 -0
- package/dist/cjs/src/Advertisement.d.ts.map +1 -0
- package/dist/cjs/src/Advertiser.d.ts +36 -0
- package/dist/cjs/src/Advertiser.d.ts.map +1 -0
- package/dist/cjs/src/BASM.d.ts +110 -0
- package/dist/cjs/src/BASM.d.ts.map +1 -0
- package/dist/cjs/src/BASM.js.map +1 -1
- package/dist/cjs/src/BASMRemote.d.ts +14 -0
- package/dist/cjs/src/BASMRemote.d.ts.map +1 -0
- package/dist/cjs/src/BASMRemote.js.map +1 -1
- package/dist/cjs/src/Engine.d.ts +377 -0
- package/dist/cjs/src/Engine.d.ts.map +1 -0
- package/dist/cjs/src/Engine.js +416 -417
- package/dist/cjs/src/Engine.js.map +1 -1
- package/dist/cjs/src/GASP/OverlayGASPRemote.d.ts +24 -0
- package/dist/cjs/src/GASP/OverlayGASPRemote.d.ts.map +1 -0
- package/dist/cjs/src/GASP/OverlayGASPRemote.js +7 -10
- package/dist/cjs/src/GASP/OverlayGASPRemote.js.map +1 -1
- package/dist/cjs/src/GASP/OverlayGASPStorage.d.ts +103 -0
- package/dist/cjs/src/GASP/OverlayGASPStorage.d.ts.map +1 -0
- package/dist/cjs/src/GASP/OverlayGASPStorage.js +32 -30
- package/dist/cjs/src/GASP/OverlayGASPStorage.js.map +1 -1
- package/dist/cjs/src/LookupFormula.d.ts +29 -0
- package/dist/cjs/src/LookupFormula.d.ts.map +1 -0
- package/dist/cjs/src/LookupService.d.ts +85 -0
- package/dist/cjs/src/LookupService.d.ts.map +1 -0
- package/dist/cjs/src/Output.d.ts +32 -0
- package/dist/cjs/src/Output.d.ts.map +1 -0
- package/dist/cjs/src/SafeLog.d.ts +14 -0
- package/dist/cjs/src/SafeLog.d.ts.map +1 -0
- package/dist/cjs/src/SafeLog.js +44 -0
- package/dist/cjs/src/SafeLog.js.map +1 -0
- package/{src/SyncConfiguration.ts → dist/cjs/src/SyncConfiguration.d.ts} +2 -1
- package/dist/cjs/src/SyncConfiguration.d.ts.map +1 -0
- package/dist/cjs/src/TopicManager.d.ts +35 -0
- package/dist/cjs/src/TopicManager.d.ts.map +1 -0
- package/dist/cjs/src/storage/Storage.d.ts +237 -0
- package/dist/cjs/src/storage/Storage.d.ts.map +1 -0
- package/dist/cjs/src/storage/knex/KnexStorage.d.ts +69 -0
- package/dist/cjs/src/storage/knex/KnexStorage.d.ts.map +1 -0
- package/dist/cjs/src/storage/knex/KnexStorage.js +7 -10
- package/dist/cjs/src/storage/knex/KnexStorage.js.map +1 -1
- package/dist/cjs/src/storage/knex/all-migrations.d.ts +11 -0
- package/dist/cjs/src/storage/knex/all-migrations.d.ts.map +1 -0
- package/dist/cjs/src/storage/knex/all-migrations.js.map +1 -1
- package/dist/cjs/src/storage/knex/migrations/2024-05-18-001-initial.d.ts +4 -0
- package/dist/cjs/src/storage/knex/migrations/2024-05-18-001-initial.d.ts.map +1 -0
- package/dist/cjs/src/storage/knex/migrations/2024-05-18-001-initial.js.map +1 -1
- package/dist/cjs/src/storage/knex/migrations/2024-07-10-001-block-height.d.ts +4 -0
- package/dist/cjs/src/storage/knex/migrations/2024-07-10-001-block-height.d.ts.map +1 -0
- package/dist/cjs/src/storage/knex/migrations/2024-07-10-001-block-height.js.map +1 -1
- package/dist/cjs/src/storage/knex/migrations/2024-07-17-001-transactions.d.ts +4 -0
- package/dist/cjs/src/storage/knex/migrations/2024-07-17-001-transactions.d.ts.map +1 -0
- package/dist/cjs/src/storage/knex/migrations/2024-07-17-001-transactions.js.map +1 -1
- package/dist/cjs/src/storage/knex/migrations/2024-07-18-001-indexes.d.ts +4 -0
- package/dist/cjs/src/storage/knex/migrations/2024-07-18-001-indexes.d.ts.map +1 -0
- package/dist/cjs/src/storage/knex/migrations/2024-07-18-001-indexes.js.map +1 -1
- package/dist/cjs/src/storage/knex/migrations/2025-05-28-001-enlarge.d.ts +4 -0
- package/dist/cjs/src/storage/knex/migrations/2025-05-28-001-enlarge.d.ts.map +1 -0
- package/dist/cjs/src/storage/knex/migrations/2025-05-28-001-enlarge.js.map +1 -1
- package/dist/cjs/src/storage/knex/migrations/2025-06-25-001-gasp-pagination-support.d.ts +4 -0
- package/dist/cjs/src/storage/knex/migrations/2025-06-25-001-gasp-pagination-support.d.ts.map +1 -0
- package/dist/cjs/src/storage/knex/migrations/2025-06-25-001-gasp-pagination-support.js.map +1 -1
- package/dist/cjs/src/storage/knex/migrations/2025-07-22-001-fix-score-column-type.d.ts +4 -0
- package/dist/cjs/src/storage/knex/migrations/2025-07-22-001-fix-score-column-type.d.ts.map +1 -0
- package/dist/cjs/src/storage/knex/migrations/2025-07-22-001-fix-score-column-type.js.map +1 -1
- package/dist/cjs/src/storage/knex/migrations/2025-11-11-001-utxo-lookup-index.d.ts +9 -0
- package/dist/cjs/src/storage/knex/migrations/2025-11-11-001-utxo-lookup-index.d.ts.map +1 -0
- package/dist/cjs/src/storage/knex/migrations/2025-11-11-001-utxo-lookup-index.js.map +1 -1
- package/dist/cjs/src/storage/knex/migrations/2026-05-29-001-brc136-basm.d.ts +4 -0
- package/dist/cjs/src/storage/knex/migrations/2026-05-29-001-brc136-basm.d.ts.map +1 -0
- package/dist/cjs/src/storage/knex/migrations/2026-05-29-001-brc136-basm.js.map +1 -1
- package/dist/esm/mod.js +2 -1
- package/dist/esm/mod.js.map +1 -1
- package/dist/esm/src/BASMRemote.js.map +1 -1
- package/dist/esm/src/Engine.js +394 -395
- package/dist/esm/src/Engine.js.map +1 -1
- package/dist/esm/src/GASP/OverlayGASPRemote.js +2 -2
- package/dist/esm/src/GASP/OverlayGASPRemote.js.map +1 -1
- package/dist/esm/src/GASP/OverlayGASPStorage.js +21 -18
- package/dist/esm/src/GASP/OverlayGASPStorage.js.map +1 -1
- package/dist/esm/src/SafeLog.js +40 -0
- package/dist/esm/src/SafeLog.js.map +1 -0
- package/dist/esm/src/storage/knex/KnexStorage.js.map +1 -1
- package/dist/types/mod.d.ts +5 -4
- package/dist/types/mod.d.ts.map +1 -1
- package/dist/types/src/BASMRemote.d.ts.map +1 -1
- package/dist/types/src/Engine.d.ts +15 -0
- package/dist/types/src/Engine.d.ts.map +1 -1
- package/dist/types/src/GASP/OverlayGASPRemote.d.ts +2 -2
- package/dist/types/src/GASP/OverlayGASPRemote.d.ts.map +1 -1
- package/dist/types/src/GASP/OverlayGASPStorage.d.ts +3 -1
- package/dist/types/src/GASP/OverlayGASPStorage.d.ts.map +1 -1
- package/dist/types/src/SafeLog.d.ts +14 -0
- package/dist/types/src/SafeLog.d.ts.map +1 -0
- package/dist/types/src/storage/knex/KnexStorage.d.ts.map +1 -1
- package/dist/types/src/storage/knex/all-migrations.d.ts.map +1 -1
- package/package.json +85 -28
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +0 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +0 -1
- package/dist/types/tsconfig.types.tsbuildinfo +0 -1
- package/docs/API.md +0 -944
- package/docs/BRC-136-BASM.md +0 -327
- package/docs/README.md +0 -16
- package/docs/Synchronization.md +0 -212
- package/docs/concepts/00-overview.md +0 -85
- package/docs/concepts/01-best-practices.md +0 -202
- package/docs/concepts/02-query-performance.md +0 -345
- package/docs/concepts/03-database-monitoring.md +0 -211
- package/docs/concepts/04-pagination-example.md +0 -186
- package/docs/concepts/05-recommendations-summary.md +0 -158
- package/docs/concepts/README.md +0 -20
- package/docs/examples/README.md +0 -15
- package/docs/examples/gs-wip.md +0 -111
- package/docs/internal/README.md +0 -11
- package/mod.ts +0 -40
- package/src/Advertisement.ts +0 -8
- package/src/Advertiser.ts +0 -41
- package/src/BASM.ts +0 -208
- package/src/BASMRemote.ts +0 -54
- package/src/Engine.ts +0 -2194
- package/src/GASP/OverlayGASPRemote.ts +0 -108
- package/src/GASP/OverlayGASPStorage.ts +0 -384
- package/src/LookupFormula.ts +0 -31
- package/src/LookupService.ts +0 -136
- package/src/Output.ts +0 -31
- package/src/TopicManager.ts +0 -40
- package/src/__tests/BASM.test.ts +0 -44
- package/src/__tests/BASMChain.test.ts +0 -295
- package/src/__tests/Engine.test.ts +0 -1381
- package/src/__tests/OverlayGASPRemote.test.ts +0 -135
- package/src/__tests/OverlayGASPStorage.test.ts +0 -205
- package/src/storage/Storage.ts +0 -260
- package/src/storage/knex/KnexStorage.ts +0 -651
- package/src/storage/knex/all-migrations.ts +0 -32
- package/src/storage/knex/migrations/2024-05-18-001-initial.ts +0 -30
- package/src/storage/knex/migrations/2024-07-10-001-block-height.ts +0 -15
- package/src/storage/knex/migrations/2024-07-17-001-transactions.ts +0 -64
- package/src/storage/knex/migrations/2024-07-18-001-indexes.ts +0 -30
- package/src/storage/knex/migrations/2025-05-28-001-enlarge.ts +0 -42
- package/src/storage/knex/migrations/2025-06-25-001-gasp-pagination-support.ts +0 -46
- package/src/storage/knex/migrations/2025-07-22-001-fix-score-column-type.ts +0 -24
- package/src/storage/knex/migrations/2025-11-11-001-utxo-lookup-index.ts +0 -18
- package/src/storage/knex/migrations/2026-05-29-001-brc136-basm.ts +0 -123
|
@@ -1,651 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Storage,
|
|
3
|
-
type AppliedTransaction,
|
|
4
|
-
type AppliedTransactionProofUpdate,
|
|
5
|
-
type StoredTransactionRecord,
|
|
6
|
-
type UnprovenAppliedTransactionCandidate
|
|
7
|
-
} from '../Storage.js'
|
|
8
|
-
import { Knex } from 'knex'
|
|
9
|
-
import type { Output } from '../../Output.js'
|
|
10
|
-
import { Transaction } from '@bsv/sdk'
|
|
11
|
-
import {
|
|
12
|
-
BASM_ZERO_HASH,
|
|
13
|
-
type AdmittedTxRef,
|
|
14
|
-
type RawTransactionRecord,
|
|
15
|
-
type TopicAnchorTip,
|
|
16
|
-
type TopicBlockAnchor,
|
|
17
|
-
extractMerkleProofMetadata
|
|
18
|
-
} from '../../BASM.js'
|
|
19
|
-
|
|
20
|
-
const OUTPUT_SELECT_FIELDS = [
|
|
21
|
-
'outputs.txid',
|
|
22
|
-
'outputs.outputIndex',
|
|
23
|
-
'outputs.outputScript',
|
|
24
|
-
'outputs.topic',
|
|
25
|
-
'outputs.satoshis',
|
|
26
|
-
'outputs.outputsConsumed',
|
|
27
|
-
'outputs.spent',
|
|
28
|
-
'outputs.consumedBy',
|
|
29
|
-
'outputs.blockHeight',
|
|
30
|
-
'outputs.score'
|
|
31
|
-
] as const
|
|
32
|
-
|
|
33
|
-
export class KnexStorage implements Storage {
|
|
34
|
-
knex: Knex
|
|
35
|
-
|
|
36
|
-
constructor (knex: Knex) {
|
|
37
|
-
this.knex = knex
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
private parseOutputRelations(
|
|
41
|
-
value: string | Array<{ txid: string, outputIndex: number }>
|
|
42
|
-
): Array<{ txid: string, outputIndex: number }> {
|
|
43
|
-
if (Array.isArray(value)) {
|
|
44
|
-
return value
|
|
45
|
-
}
|
|
46
|
-
return JSON.parse(value)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
private parseOutputRecord(
|
|
50
|
-
row: any,
|
|
51
|
-
includeBEEF: boolean,
|
|
52
|
-
beefOverride?: number[]
|
|
53
|
-
): Output {
|
|
54
|
-
return {
|
|
55
|
-
...row,
|
|
56
|
-
outputScript: Array.from(row.outputScript),
|
|
57
|
-
beef: (() => {
|
|
58
|
-
if (!includeBEEF) return undefined
|
|
59
|
-
if (beefOverride != null) return beefOverride
|
|
60
|
-
return row.beef != null ? Array.from(row.beef) : undefined
|
|
61
|
-
})(),
|
|
62
|
-
spent: Boolean(row.spent),
|
|
63
|
-
outputsConsumed: this.parseOutputRelations(row.outputsConsumed),
|
|
64
|
-
consumedBy: this.parseOutputRelations(row.consumedBy)
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
private binaryToNumberArray(value: any): number[] | undefined {
|
|
69
|
-
if (value === undefined || value === null) {
|
|
70
|
-
return undefined
|
|
71
|
-
}
|
|
72
|
-
return Array.from(Buffer.from(value))
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
private binaryToHex(value: any): string | undefined {
|
|
76
|
-
const array = this.binaryToNumberArray(value)
|
|
77
|
-
if (array === undefined) {
|
|
78
|
-
return undefined
|
|
79
|
-
}
|
|
80
|
-
return Buffer.from(array).toString('hex')
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
private transactionRecordFromBEEF(txid: string, beef: number[]): StoredTransactionRecord {
|
|
84
|
-
const tx = Transaction.fromBEEF(beef)
|
|
85
|
-
const metadata = extractMerkleProofMetadata(txid, tx.merklePath)
|
|
86
|
-
return {
|
|
87
|
-
txid,
|
|
88
|
-
beef: tx.merklePath === undefined ? beef : tx.toAtomicBEEF(),
|
|
89
|
-
rawTx: Array.from(tx.toBinary()),
|
|
90
|
-
merklePath: tx.merklePath?.toBinary(),
|
|
91
|
-
blockHeight: metadata?.blockHeight,
|
|
92
|
-
blockIndex: metadata?.blockIndex,
|
|
93
|
-
merkleRoot: metadata?.merkleRoot
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
private async fetchTransactionBeefMap(txids: string[]): Promise<Map<string, number[]>> {
|
|
98
|
-
if (txids.length === 0) {
|
|
99
|
-
return new Map<string, number[]>()
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const rows = await this.knex('transactions')
|
|
103
|
-
.whereIn('txid', txids)
|
|
104
|
-
.select(['txid', 'beef'])
|
|
105
|
-
|
|
106
|
-
const beefByTxid = new Map<string, number[]>()
|
|
107
|
-
for (const row of rows) {
|
|
108
|
-
if (row.beef !== undefined && row.beef !== null) {
|
|
109
|
-
beefByTxid.set(row.txid, Array.from(row.beef))
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return beefByTxid
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
async findOutput (txid: string, outputIndex: number, topic?: string, spent?: boolean, includeBEEF: boolean = false): Promise<Output | null> {
|
|
116
|
-
const search: {
|
|
117
|
-
'outputs.txid': string
|
|
118
|
-
'outputs.outputIndex': number
|
|
119
|
-
'outputs.topic'?: string
|
|
120
|
-
'outputs.spent'?: boolean
|
|
121
|
-
} = {
|
|
122
|
-
'outputs.txid': txid,
|
|
123
|
-
'outputs.outputIndex': outputIndex
|
|
124
|
-
}
|
|
125
|
-
if (topic !== undefined) search['outputs.topic'] = topic
|
|
126
|
-
if (spent !== undefined) search['outputs.spent'] = spent
|
|
127
|
-
|
|
128
|
-
const query = this.knex('outputs').where(search)
|
|
129
|
-
const selectFields: string[] = [...OUTPUT_SELECT_FIELDS]
|
|
130
|
-
|
|
131
|
-
if (includeBEEF) {
|
|
132
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
133
|
-
query.leftJoin('transactions', 'outputs.txid', 'transactions.txid')
|
|
134
|
-
selectFields.push('transactions.beef')
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const output = await query.select(selectFields).first()
|
|
138
|
-
|
|
139
|
-
if (output === undefined || output === null) {
|
|
140
|
-
return null
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return this.parseOutputRecord(output, includeBEEF)
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
async findOutputsByOutpoints (
|
|
147
|
-
outpoints: Array<{ txid: string, outputIndex: number }>,
|
|
148
|
-
includeBEEF: boolean = false
|
|
149
|
-
): Promise<Output[]> {
|
|
150
|
-
if (outpoints.length === 0) {
|
|
151
|
-
return []
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const deduped = new Map<string, { txid: string, outputIndex: number }>()
|
|
155
|
-
for (const outpoint of outpoints) {
|
|
156
|
-
deduped.set(`${outpoint.txid}:${outpoint.outputIndex}`, outpoint)
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const rows = await this.knex('outputs')
|
|
160
|
-
.whereIn(
|
|
161
|
-
['outputs.txid', 'outputs.outputIndex'],
|
|
162
|
-
Array.from(deduped.values()).map(outpoint => [outpoint.txid, outpoint.outputIndex])
|
|
163
|
-
)
|
|
164
|
-
.select([...OUTPUT_SELECT_FIELDS])
|
|
165
|
-
|
|
166
|
-
if (rows === undefined || rows.length === 0) {
|
|
167
|
-
return []
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
if (!includeBEEF) {
|
|
171
|
-
return rows.map(row => this.parseOutputRecord(row, false))
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const txids = Array.from(new Set(rows.map(row => row.txid)))
|
|
175
|
-
const beefByTxid = await this.fetchTransactionBeefMap(txids)
|
|
176
|
-
return rows.map(row => this.parseOutputRecord(row, true, beefByTxid.get(row.txid)))
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
async findOutputsForTransaction (txid: string, includeBEEF: boolean = false): Promise<Output[]> {
|
|
180
|
-
const outputs = await this.knex('outputs')
|
|
181
|
-
.where({ 'outputs.txid': txid })
|
|
182
|
-
.select([...OUTPUT_SELECT_FIELDS])
|
|
183
|
-
|
|
184
|
-
if (outputs === undefined || outputs.length === 0) {
|
|
185
|
-
return []
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (!includeBEEF) {
|
|
189
|
-
return outputs.map(output => this.parseOutputRecord(output, false))
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
const beefByTxid = await this.fetchTransactionBeefMap([txid])
|
|
193
|
-
return outputs.map(output => this.parseOutputRecord(output, true, beefByTxid.get(output.txid)))
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
async findUTXOsForTopic (topic: string, since?: number, limit?: number, includeBEEF: boolean = false): Promise<Output[]> {
|
|
197
|
-
// Base query to get outputs
|
|
198
|
-
const query = this.knex('outputs').where({ 'outputs.topic': topic, 'outputs.spent': false })
|
|
199
|
-
|
|
200
|
-
// If provided, additionally filters UTXOs by score
|
|
201
|
-
if (since !== undefined && since > 0) {
|
|
202
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
203
|
-
query.andWhere('outputs.score', '>=', since)
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Sort by score
|
|
207
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
208
|
-
query.orderBy('outputs.score', 'asc')
|
|
209
|
-
|
|
210
|
-
// Apply limit if specified
|
|
211
|
-
if (limit !== undefined && limit > 0) {
|
|
212
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
213
|
-
query.limit(limit)
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
const outputs = await query.select([...OUTPUT_SELECT_FIELDS])
|
|
217
|
-
|
|
218
|
-
if (outputs === undefined || outputs.length === 0) {
|
|
219
|
-
return []
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
if (!includeBEEF) {
|
|
223
|
-
return outputs.map(output => this.parseOutputRecord(output, false))
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const txids = Array.from(new Set(outputs.map(output => output.txid)))
|
|
227
|
-
const beefByTxid = await this.fetchTransactionBeefMap(txids)
|
|
228
|
-
return outputs.map(output => this.parseOutputRecord(output, true, beefByTxid.get(output.txid)))
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
async deleteOutput (txid: string, outputIndex: number, topic: string): Promise<void> {
|
|
232
|
-
await this.knex.transaction(async trx => {
|
|
233
|
-
// Delete the specific output
|
|
234
|
-
await trx('outputs').where({ txid, outputIndex, topic }).del()
|
|
235
|
-
|
|
236
|
-
// Check how many outputs reference the same transaction
|
|
237
|
-
const remainingOutputs = await trx('outputs').where({ txid }).count('* as count').first()
|
|
238
|
-
|
|
239
|
-
if (remainingOutputs !== undefined && Number(remainingOutputs.count) === 0) {
|
|
240
|
-
// If no more outputs reference the transaction, delete the beef
|
|
241
|
-
await trx('transactions').where({ txid }).del()
|
|
242
|
-
}
|
|
243
|
-
})
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
async insertOutput (output: Output): Promise<void> {
|
|
247
|
-
await this.knex.transaction(async trx => {
|
|
248
|
-
const existing = await trx('outputs').where({
|
|
249
|
-
txid: output.txid,
|
|
250
|
-
outputIndex: Number(output.outputIndex),
|
|
251
|
-
topic: output.topic
|
|
252
|
-
}).first()
|
|
253
|
-
|
|
254
|
-
if (existing === undefined || existing === null) {
|
|
255
|
-
await trx('outputs').insert({
|
|
256
|
-
txid: output.txid,
|
|
257
|
-
outputIndex: Number(output.outputIndex),
|
|
258
|
-
outputScript: Buffer.from(output.outputScript),
|
|
259
|
-
topic: output.topic,
|
|
260
|
-
satoshis: Number(output.satoshis),
|
|
261
|
-
outputsConsumed: JSON.stringify(output.outputsConsumed),
|
|
262
|
-
consumedBy: JSON.stringify(output.consumedBy),
|
|
263
|
-
spent: output.spent,
|
|
264
|
-
score: output.score,
|
|
265
|
-
blockHeight: output.blockHeight
|
|
266
|
-
})
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
if (output.beef !== undefined) {
|
|
270
|
-
const record = this.transactionRecordFromBEEF(output.txid, output.beef)
|
|
271
|
-
const transactionRecord: Record<string, any> = {
|
|
272
|
-
txid: output.txid,
|
|
273
|
-
updatedAt: new Date()
|
|
274
|
-
}
|
|
275
|
-
if (record.beef !== undefined) transactionRecord.beef = Buffer.from(record.beef)
|
|
276
|
-
if (record.rawTx !== undefined) transactionRecord.rawTx = Buffer.from(record.rawTx)
|
|
277
|
-
if (record.merklePath !== undefined) transactionRecord.merklePath = Buffer.from(record.merklePath)
|
|
278
|
-
if (record.blockHeight !== undefined) transactionRecord.blockHeight = record.blockHeight
|
|
279
|
-
if (record.blockIndex !== undefined) transactionRecord.blockIndex = record.blockIndex
|
|
280
|
-
if (record.merkleRoot !== undefined) transactionRecord.merkleRoot = record.merkleRoot
|
|
281
|
-
|
|
282
|
-
const mergeRecord = { ...transactionRecord }
|
|
283
|
-
delete mergeRecord.txid
|
|
284
|
-
await trx('transactions').insert(transactionRecord).onConflict('txid').merge(mergeRecord)
|
|
285
|
-
}
|
|
286
|
-
})
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
async markUTXOAsSpent (txid: string, outputIndex: number, topic?: string): Promise<void> {
|
|
290
|
-
await this.knex('outputs').where({
|
|
291
|
-
txid,
|
|
292
|
-
outputIndex,
|
|
293
|
-
topic
|
|
294
|
-
}).update('spent', true)
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
async updateConsumedBy (txid: string, outputIndex: number, topic: string, consumedBy: Array<{ txid: string, outputIndex: number }>): Promise<void> {
|
|
298
|
-
await this.knex('outputs').where({
|
|
299
|
-
txid,
|
|
300
|
-
outputIndex,
|
|
301
|
-
topic
|
|
302
|
-
}).update('consumedBy', JSON.stringify(consumedBy))
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
async updateTransactionBEEF (txid: string, beef: number[]): Promise<void> {
|
|
306
|
-
await this.upsertTransactionRecord(this.transactionRecordFromBEEF(txid, beef))
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
async updateOutputBlockHeight (txid: string, outputIndex: number, topic: string, blockHeight: number): Promise<void> {
|
|
310
|
-
await this.knex('outputs').where({
|
|
311
|
-
txid,
|
|
312
|
-
outputIndex,
|
|
313
|
-
topic
|
|
314
|
-
}).update('blockHeight', blockHeight)
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
async upsertTransactionRecord(record: StoredTransactionRecord): Promise<void> {
|
|
318
|
-
const insert: Record<string, any> = {
|
|
319
|
-
txid: record.txid,
|
|
320
|
-
updatedAt: new Date()
|
|
321
|
-
}
|
|
322
|
-
if (record.beef !== undefined) insert.beef = Buffer.from(record.beef)
|
|
323
|
-
if (record.rawTx !== undefined) insert.rawTx = Buffer.from(record.rawTx)
|
|
324
|
-
if (record.merklePath !== undefined) insert.merklePath = Buffer.from(record.merklePath)
|
|
325
|
-
if (record.blockHeight !== undefined) insert.blockHeight = record.blockHeight
|
|
326
|
-
if (record.blockHash !== undefined) insert.blockHash = record.blockHash
|
|
327
|
-
if (record.blockIndex !== undefined) insert.blockIndex = record.blockIndex
|
|
328
|
-
if (record.merkleRoot !== undefined) insert.merkleRoot = record.merkleRoot
|
|
329
|
-
|
|
330
|
-
const merge = { ...insert }
|
|
331
|
-
delete merge.txid
|
|
332
|
-
|
|
333
|
-
await this.knex('transactions')
|
|
334
|
-
.insert(insert)
|
|
335
|
-
.onConflict('txid')
|
|
336
|
-
.merge(merge)
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
async updateAppliedTransactionProof(record: AppliedTransactionProofUpdate): Promise<void> {
|
|
340
|
-
await this.knex('applied_transactions')
|
|
341
|
-
.where({ txid: record.txid, topic: record.topic })
|
|
342
|
-
.update({
|
|
343
|
-
blockHeight: record.blockHeight,
|
|
344
|
-
blockHash: record.blockHash,
|
|
345
|
-
blockIndex: record.blockIndex,
|
|
346
|
-
merkleRoot: record.merkleRoot,
|
|
347
|
-
proven: true
|
|
348
|
-
})
|
|
349
|
-
|
|
350
|
-
if (record.blockHeight !== undefined) {
|
|
351
|
-
await this.knex('outputs')
|
|
352
|
-
.where({ txid: record.txid, topic: record.topic })
|
|
353
|
-
.update({ blockHeight: record.blockHeight })
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
async insertAppliedTransaction (tx: AppliedTransaction): Promise<void> {
|
|
358
|
-
await this.knex('applied_transactions').insert({
|
|
359
|
-
txid: tx.txid,
|
|
360
|
-
topic: tx.topic,
|
|
361
|
-
blockHeight: tx.blockHeight,
|
|
362
|
-
blockHash: tx.blockHash,
|
|
363
|
-
blockIndex: tx.blockIndex,
|
|
364
|
-
merkleRoot: tx.merkleRoot,
|
|
365
|
-
firstSeenHeight: tx.firstSeenHeight,
|
|
366
|
-
proven: tx.proven ?? false
|
|
367
|
-
})
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
async doesAppliedTransactionExist (tx: { txid: string, topic: string }): Promise<boolean> {
|
|
371
|
-
const result = await this.knex('applied_transactions')
|
|
372
|
-
.where({ txid: tx.txid, topic: tx.topic })
|
|
373
|
-
.select(this.knex.raw('1'))
|
|
374
|
-
.first()
|
|
375
|
-
|
|
376
|
-
return !!result
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
async updateLastInteraction (host: string, topic: string, since: number): Promise<void> {
|
|
380
|
-
await this.knex('host_sync_state')
|
|
381
|
-
.insert({ host, topic, since })
|
|
382
|
-
.onConflict(['host', 'topic'])
|
|
383
|
-
.merge({ since })
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
async getLastInteraction (host: string, topic: string): Promise<number> {
|
|
387
|
-
const result = await this.knex('host_sync_state')
|
|
388
|
-
.where({ host, topic })
|
|
389
|
-
.select('since')
|
|
390
|
-
.first()
|
|
391
|
-
|
|
392
|
-
return result ? result.since : 0
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
async findAdmittedTransactionsForBlock(topic: string, blockHeight: number, blockHash?: string): Promise<AdmittedTxRef[]> {
|
|
396
|
-
let query = this.knex('applied_transactions')
|
|
397
|
-
.where({ topic, blockHeight, proven: true })
|
|
398
|
-
.whereNotNull('blockIndex')
|
|
399
|
-
|
|
400
|
-
if (blockHash !== undefined) {
|
|
401
|
-
query = query.andWhere({ blockHash })
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
const rows = await query
|
|
405
|
-
.select(['txid', 'blockIndex'])
|
|
406
|
-
.orderBy('blockIndex', 'asc')
|
|
407
|
-
|
|
408
|
-
return rows.map(row => ({
|
|
409
|
-
txid: row.txid,
|
|
410
|
-
blockIndex: Number(row.blockIndex)
|
|
411
|
-
}))
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
async upsertTopicBlockAnchor(anchor: TopicBlockAnchor): Promise<void> {
|
|
415
|
-
await this.knex('topic_block_anchors')
|
|
416
|
-
.insert({
|
|
417
|
-
topic: anchor.topic,
|
|
418
|
-
blockHeight: anchor.blockHeight,
|
|
419
|
-
blockHash: anchor.blockHash,
|
|
420
|
-
basmRoot: anchor.basmRoot,
|
|
421
|
-
admittedCount: anchor.admittedCount,
|
|
422
|
-
tac: anchor.tac,
|
|
423
|
-
updatedAt: new Date()
|
|
424
|
-
})
|
|
425
|
-
.onConflict(['topic', 'blockHeight'])
|
|
426
|
-
.merge({
|
|
427
|
-
blockHash: anchor.blockHash,
|
|
428
|
-
basmRoot: anchor.basmRoot,
|
|
429
|
-
admittedCount: anchor.admittedCount,
|
|
430
|
-
tac: anchor.tac,
|
|
431
|
-
updatedAt: new Date()
|
|
432
|
-
})
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
async findTopicBlockAnchor(topic: string, blockHeight: number, blockHash?: string): Promise<TopicBlockAnchor | undefined> {
|
|
436
|
-
let query = this.knex('topic_block_anchors').where({ topic, blockHeight })
|
|
437
|
-
if (blockHash !== undefined) {
|
|
438
|
-
query = query.andWhere({ blockHash })
|
|
439
|
-
}
|
|
440
|
-
const row = await query.first()
|
|
441
|
-
if (row === undefined) {
|
|
442
|
-
return undefined
|
|
443
|
-
}
|
|
444
|
-
return {
|
|
445
|
-
topic: row.topic,
|
|
446
|
-
blockHeight: Number(row.blockHeight),
|
|
447
|
-
blockHash: row.blockHash,
|
|
448
|
-
basmRoot: row.basmRoot,
|
|
449
|
-
admittedCount: Number(row.admittedCount),
|
|
450
|
-
tac: row.tac
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
async findTopicBlockAnchors(topic: string, fromHeight: number, toHeight: number): Promise<TopicBlockAnchor[]> {
|
|
455
|
-
const rows = await this.knex('topic_block_anchors')
|
|
456
|
-
.where({ topic })
|
|
457
|
-
.andWhere('blockHeight', '>=', fromHeight)
|
|
458
|
-
.andWhere('blockHeight', '<=', toHeight)
|
|
459
|
-
.select(['topic', 'blockHeight', 'blockHash', 'basmRoot', 'admittedCount', 'tac'])
|
|
460
|
-
.orderBy('blockHeight', 'asc')
|
|
461
|
-
|
|
462
|
-
return rows.map(row => ({
|
|
463
|
-
topic: row.topic,
|
|
464
|
-
blockHeight: Number(row.blockHeight),
|
|
465
|
-
blockHash: row.blockHash,
|
|
466
|
-
basmRoot: row.basmRoot,
|
|
467
|
-
admittedCount: Number(row.admittedCount),
|
|
468
|
-
tac: row.tac
|
|
469
|
-
}))
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
async findTopicAnchorTip(topic: string): Promise<TopicAnchorTip | undefined> {
|
|
473
|
-
const row = await this.knex('topic_block_anchors')
|
|
474
|
-
.where({ topic })
|
|
475
|
-
.orderBy('blockHeight', 'desc')
|
|
476
|
-
.first()
|
|
477
|
-
|
|
478
|
-
if (row === undefined) {
|
|
479
|
-
return {
|
|
480
|
-
topic,
|
|
481
|
-
blockHeight: -1,
|
|
482
|
-
tac: BASM_ZERO_HASH
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
return {
|
|
487
|
-
topic: row.topic,
|
|
488
|
-
blockHeight: Number(row.blockHeight),
|
|
489
|
-
blockHash: row.blockHash,
|
|
490
|
-
basmRoot: row.basmRoot,
|
|
491
|
-
admittedCount: Number(row.admittedCount),
|
|
492
|
-
tac: row.tac
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
async findRawTransactions(txids: string[]): Promise<RawTransactionRecord[]> {
|
|
497
|
-
if (txids.length === 0) return []
|
|
498
|
-
const rows = await this.knex('transactions')
|
|
499
|
-
.whereIn('txid', txids)
|
|
500
|
-
.select(['txid', 'rawTx', 'beef'])
|
|
501
|
-
|
|
502
|
-
const records: RawTransactionRecord[] = []
|
|
503
|
-
for (const row of rows) {
|
|
504
|
-
let rawTx = this.binaryToHex(row.rawTx)
|
|
505
|
-
if (rawTx === undefined) {
|
|
506
|
-
const beef = this.binaryToNumberArray(row.beef)
|
|
507
|
-
if (beef !== undefined) {
|
|
508
|
-
rawTx = Transaction.fromBEEF(beef, row.txid).toHex()
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
if (rawTx !== undefined) {
|
|
512
|
-
records.push({ txid: row.txid, rawTx })
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
return records
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
async findTransactionMerklePaths(txids: string[]): Promise<Array<{
|
|
519
|
-
txid: string
|
|
520
|
-
merklePath: string
|
|
521
|
-
blockHeight?: number
|
|
522
|
-
blockHash?: string
|
|
523
|
-
blockIndex?: number
|
|
524
|
-
merkleRoot?: string
|
|
525
|
-
}>> {
|
|
526
|
-
if (txids.length === 0) return []
|
|
527
|
-
const rows = await this.knex('transactions')
|
|
528
|
-
.whereIn('txid', txids)
|
|
529
|
-
.select(['txid', 'merklePath', 'blockHeight', 'blockHash', 'blockIndex', 'merkleRoot', 'beef'])
|
|
530
|
-
|
|
531
|
-
const records: Array<{
|
|
532
|
-
txid: string
|
|
533
|
-
merklePath: string
|
|
534
|
-
blockHeight?: number
|
|
535
|
-
blockHash?: string
|
|
536
|
-
blockIndex?: number
|
|
537
|
-
merkleRoot?: string
|
|
538
|
-
}> = []
|
|
539
|
-
|
|
540
|
-
for (const row of rows) {
|
|
541
|
-
let merklePath = this.binaryToHex(row.merklePath)
|
|
542
|
-
if (merklePath === undefined) {
|
|
543
|
-
const beef = this.binaryToNumberArray(row.beef)
|
|
544
|
-
if (beef !== undefined) {
|
|
545
|
-
merklePath = Transaction.fromBEEF(beef, row.txid).merklePath?.toHex()
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
if (merklePath !== undefined) {
|
|
549
|
-
records.push({
|
|
550
|
-
txid: row.txid,
|
|
551
|
-
merklePath,
|
|
552
|
-
blockHeight: row.blockHeight === undefined || row.blockHeight === null ? undefined : Number(row.blockHeight),
|
|
553
|
-
blockHash: row.blockHash,
|
|
554
|
-
blockIndex: row.blockIndex === undefined || row.blockIndex === null ? undefined : Number(row.blockIndex),
|
|
555
|
-
merkleRoot: row.merkleRoot
|
|
556
|
-
})
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
return records
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
async findUnprovenAppliedTransactions(cutoffHeight: number, topic?: string): Promise<UnprovenAppliedTransactionCandidate[]> {
|
|
564
|
-
let query = this.knex('applied_transactions')
|
|
565
|
-
.where(builder => {
|
|
566
|
-
builder.where({ proven: false }).orWhereNull('proven')
|
|
567
|
-
})
|
|
568
|
-
.whereNotNull('firstSeenHeight')
|
|
569
|
-
.andWhere('firstSeenHeight', '<=', cutoffHeight)
|
|
570
|
-
.select(['txid', 'topic', 'firstSeenHeight'])
|
|
571
|
-
|
|
572
|
-
if (topic !== undefined) {
|
|
573
|
-
query = query.andWhere({ topic })
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
const rows = await query
|
|
577
|
-
const candidates: UnprovenAppliedTransactionCandidate[] = []
|
|
578
|
-
|
|
579
|
-
for (const row of rows) {
|
|
580
|
-
const outputs = await this.knex('outputs')
|
|
581
|
-
.where({ txid: row.txid, topic: row.topic })
|
|
582
|
-
.select(['txid', 'outputIndex'])
|
|
583
|
-
|
|
584
|
-
candidates.push({
|
|
585
|
-
txid: row.txid,
|
|
586
|
-
topic: row.topic,
|
|
587
|
-
firstSeenHeight: row.firstSeenHeight === undefined || row.firstSeenHeight === null ? undefined : Number(row.firstSeenHeight),
|
|
588
|
-
outputs: outputs.map(output => ({
|
|
589
|
-
txid: output.txid,
|
|
590
|
-
outputIndex: Number(output.outputIndex)
|
|
591
|
-
}))
|
|
592
|
-
})
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
return candidates
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
async deleteAppliedTransaction(txid: string, topic: string): Promise<void> {
|
|
599
|
-
await this.knex('applied_transactions').where({ txid, topic }).del()
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
async findProvenAppliedTransactionsByBlockHash(blockHash: string): Promise<Array<{ txid: string, topic: string, blockHeight: number }>> {
|
|
603
|
-
const rows = await this.knex('applied_transactions')
|
|
604
|
-
.where({ blockHash, proven: true })
|
|
605
|
-
.whereNotNull('blockHeight')
|
|
606
|
-
.select(['txid', 'topic', 'blockHeight'])
|
|
607
|
-
|
|
608
|
-
return rows.map(row => ({
|
|
609
|
-
txid: row.txid,
|
|
610
|
-
topic: row.topic,
|
|
611
|
-
blockHeight: Number(row.blockHeight)
|
|
612
|
-
}))
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
async findProvenAppliedTransactionsInRange(fromHeight: number, toHeight: number, topic?: string): Promise<Array<{ txid: string, topic: string, blockHeight: number, blockHash?: string, merkleRoot?: string }>> {
|
|
616
|
-
let query = this.knex('applied_transactions')
|
|
617
|
-
.where({ proven: true })
|
|
618
|
-
.andWhere('blockHeight', '>=', fromHeight)
|
|
619
|
-
.andWhere('blockHeight', '<=', toHeight)
|
|
620
|
-
|
|
621
|
-
if (topic !== undefined) {
|
|
622
|
-
query = query.andWhere({ topic })
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
const rows = await query.select(['txid', 'topic', 'blockHeight', 'blockHash', 'merkleRoot'])
|
|
626
|
-
|
|
627
|
-
return rows.map(row => ({
|
|
628
|
-
txid: row.txid,
|
|
629
|
-
topic: row.topic,
|
|
630
|
-
blockHeight: Number(row.blockHeight),
|
|
631
|
-
blockHash: row.blockHash ?? undefined,
|
|
632
|
-
merkleRoot: row.merkleRoot ?? undefined
|
|
633
|
-
}))
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
async demoteAppliedTransactionToUnproven(txid: string, topic: string): Promise<void> {
|
|
637
|
-
await this.knex('applied_transactions')
|
|
638
|
-
.where({ txid, topic })
|
|
639
|
-
.update({
|
|
640
|
-
blockHeight: null,
|
|
641
|
-
blockHash: null,
|
|
642
|
-
blockIndex: null,
|
|
643
|
-
merkleRoot: null,
|
|
644
|
-
proven: false
|
|
645
|
-
})
|
|
646
|
-
|
|
647
|
-
await this.knex('outputs')
|
|
648
|
-
.where({ txid, topic })
|
|
649
|
-
.update({ blockHeight: null })
|
|
650
|
-
}
|
|
651
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { Knex } from 'knex'
|
|
2
|
-
import { up as initialSchemaUp, down as initialSchemaDown } from './migrations/2024-05-18-001-initial.js'
|
|
3
|
-
import { up as addBlockHeightColumnUp, down as addBlockHeightColumnDown } from './migrations/2024-07-10-001-block-height.js'
|
|
4
|
-
import { up as addTransactionsTableUp, down as addTransactionsTableDown } from './migrations/2024-07-17-001-transactions.js'
|
|
5
|
-
import { up as addedIndexesUp, down as addedIndexesDown } from './migrations/2024-07-18-001-indexes.js'
|
|
6
|
-
import { up as enlargeUp, down as enlargeDown } from './migrations/2025-05-28-001-enlarge.js'
|
|
7
|
-
import { up as gaspPaginationSupportUp, down as gaspPaginationSupportDown } from './migrations/2025-06-25-001-gasp-pagination-support.js'
|
|
8
|
-
import { up as fixScoreColumnTypeUp, down as fixScoreColumnTypeDown } from './migrations/2025-07-22-001-fix-score-column-type.js'
|
|
9
|
-
import { up as utxoLookupIndexUp, down as utxoLookupIndexDown } from './migrations/2025-11-11-001-utxo-lookup-index.js'
|
|
10
|
-
import { up as brc136BasmUp, down as brc136BasmDown } from './migrations/2026-05-29-001-brc136-basm.js'
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* An array of all migrations, in order.
|
|
14
|
-
*/
|
|
15
|
-
interface Migration {
|
|
16
|
-
up: (knex: Knex) => Promise<void>
|
|
17
|
-
down: (knex: Knex) => Promise<void>
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const allMigrations: Migration[] = [
|
|
21
|
-
{ up: initialSchemaUp, down: initialSchemaDown },
|
|
22
|
-
{ up: addBlockHeightColumnUp, down: addBlockHeightColumnDown },
|
|
23
|
-
{ up: addTransactionsTableUp, down: addTransactionsTableDown },
|
|
24
|
-
{ up: addedIndexesUp, down: addedIndexesDown },
|
|
25
|
-
{ up: enlargeUp, down: enlargeDown },
|
|
26
|
-
{ up: gaspPaginationSupportUp, down: gaspPaginationSupportDown },
|
|
27
|
-
{ up: fixScoreColumnTypeUp, down: fixScoreColumnTypeDown },
|
|
28
|
-
{ up: utxoLookupIndexUp, down: utxoLookupIndexDown },
|
|
29
|
-
{ up: brc136BasmUp, down: brc136BasmDown }
|
|
30
|
-
]
|
|
31
|
-
|
|
32
|
-
export default allMigrations
|