@bsv/overlay 0.1.0-alpha.1
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 +28 -0
- package/README.md +220 -0
- package/dist/cjs/mod.js +43 -0
- package/dist/cjs/mod.js.map +1 -0
- package/dist/cjs/package.json +53 -0
- package/dist/cjs/src/AdmittanceInstructions.js +3 -0
- package/dist/cjs/src/AdmittanceInstructions.js.map +1 -0
- package/dist/cjs/src/Engine.js +361 -0
- package/dist/cjs/src/Engine.js.map +1 -0
- package/dist/cjs/src/LookupAnswer.js +3 -0
- package/dist/cjs/src/LookupAnswer.js.map +1 -0
- package/dist/cjs/src/LookupFormula.js +3 -0
- package/dist/cjs/src/LookupFormula.js.map +1 -0
- package/dist/cjs/src/LookupQuestion.js +3 -0
- package/dist/cjs/src/LookupQuestion.js.map +1 -0
- package/dist/cjs/src/LookupService.js +3 -0
- package/dist/cjs/src/LookupService.js.map +1 -0
- package/dist/cjs/src/Output.js +3 -0
- package/dist/cjs/src/Output.js.map +1 -0
- package/dist/cjs/src/STEAK.js +3 -0
- package/dist/cjs/src/STEAK.js.map +1 -0
- package/dist/cjs/src/TaggedBEEF.js +3 -0
- package/dist/cjs/src/TaggedBEEF.js.map +1 -0
- package/dist/cjs/src/TopicManager.js +3 -0
- package/dist/cjs/src/TopicManager.js.map +1 -0
- package/dist/cjs/src/storage/Storage.js +3 -0
- package/dist/cjs/src/storage/Storage.js.map +1 -0
- package/dist/cjs/src/storage/knex/KnexStorage.js +76 -0
- package/dist/cjs/src/storage/knex/KnexStorage.js.map +1 -0
- package/dist/cjs/src/storage/knex/all-migrations.js +11 -0
- package/dist/cjs/src/storage/knex/all-migrations.js.map +1 -0
- package/dist/cjs/src/storage/knex/migrations/2024-05-18-001-initial.js +33 -0
- package/dist/cjs/src/storage/knex/migrations/2024-05-18-001-initial.js.map +1 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/esm/mod.js +17 -0
- package/dist/esm/mod.js.map +1 -0
- package/dist/esm/src/AdmittanceInstructions.js +2 -0
- package/dist/esm/src/AdmittanceInstructions.js.map +1 -0
- package/dist/esm/src/Engine.js +357 -0
- package/dist/esm/src/Engine.js.map +1 -0
- package/dist/esm/src/LookupAnswer.js +2 -0
- package/dist/esm/src/LookupAnswer.js.map +1 -0
- package/dist/esm/src/LookupFormula.js +2 -0
- package/dist/esm/src/LookupFormula.js.map +1 -0
- package/dist/esm/src/LookupQuestion.js +2 -0
- package/dist/esm/src/LookupQuestion.js.map +1 -0
- package/dist/esm/src/LookupService.js +2 -0
- package/dist/esm/src/LookupService.js.map +1 -0
- package/dist/esm/src/Output.js +2 -0
- package/dist/esm/src/Output.js.map +1 -0
- package/dist/esm/src/STEAK.js +2 -0
- package/dist/esm/src/STEAK.js.map +1 -0
- package/dist/esm/src/TaggedBEEF.js +2 -0
- package/dist/esm/src/TaggedBEEF.js.map +1 -0
- package/dist/esm/src/TopicManager.js +2 -0
- package/dist/esm/src/TopicManager.js.map +1 -0
- package/dist/esm/src/storage/Storage.js +2 -0
- package/dist/esm/src/storage/Storage.js.map +1 -0
- package/dist/esm/src/storage/knex/KnexStorage.js +74 -0
- package/dist/esm/src/storage/knex/KnexStorage.js.map +1 -0
- package/dist/esm/src/storage/knex/all-migrations.js +9 -0
- package/dist/esm/src/storage/knex/all-migrations.js.map +1 -0
- package/dist/esm/src/storage/knex/migrations/2024-05-18-001-initial.js +28 -0
- package/dist/esm/src/storage/knex/migrations/2024-05-18-001-initial.js.map +1 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
- package/dist/types/mod.d.ts +14 -0
- package/dist/types/mod.d.ts.map +1 -0
- package/dist/types/src/AdmittanceInstructions.d.ts +14 -0
- package/dist/types/src/AdmittanceInstructions.d.ts.map +1 -0
- package/dist/types/src/Engine.d.ts +92 -0
- package/dist/types/src/Engine.d.ts.map +1 -0
- package/dist/types/src/LookupAnswer.d.ts +15 -0
- package/dist/types/src/LookupAnswer.d.ts.map +1 -0
- package/dist/types/src/LookupFormula.d.ts +25 -0
- package/dist/types/src/LookupFormula.d.ts.map +1 -0
- package/dist/types/src/LookupQuestion.d.ts +15 -0
- package/dist/types/src/LookupQuestion.d.ts.map +1 -0
- package/dist/types/src/LookupService.d.ts +52 -0
- package/dist/types/src/LookupService.d.ts.map +1 -0
- package/dist/types/src/Output.d.ts +30 -0
- package/dist/types/src/Output.d.ts.map +1 -0
- package/dist/types/src/STEAK.d.ts +10 -0
- package/dist/types/src/STEAK.d.ts.map +1 -0
- package/dist/types/src/TaggedBEEF.d.ts +11 -0
- package/dist/types/src/TaggedBEEF.d.ts.map +1 -0
- package/dist/types/src/TopicManager.d.ts +27 -0
- package/dist/types/src/TopicManager.d.ts.map +1 -0
- package/dist/types/src/storage/Storage.d.ts +66 -0
- package/dist/types/src/storage/Storage.d.ts.map +1 -0
- package/dist/types/src/storage/knex/KnexStorage.d.ts +24 -0
- package/dist/types/src/storage/knex/KnexStorage.d.ts.map +1 -0
- package/dist/types/src/storage/knex/all-migrations.d.ts +10 -0
- package/dist/types/src/storage/knex/all-migrations.d.ts.map +1 -0
- package/dist/types/src/storage/knex/migrations/2024-05-18-001-initial.d.ts +4 -0
- package/dist/types/src/storage/knex/migrations/2024-05-18-001-initial.d.ts.map +1 -0
- package/dist/types/tsconfig.types.tsbuildinfo +1 -0
- package/docs/API.md +621 -0
- package/docs/README.md +8 -0
- package/docs/concepts/README.md +4 -0
- package/docs/examples/README.md +5 -0
- package/docs/examples/gs-wip.md +105 -0
- package/docs/internal/README.md +4 -0
- package/mod.ts +18 -0
- package/package.json +78 -0
- package/src/AdmittanceInstructions.ts +14 -0
- package/src/Engine.ts +419 -0
- package/src/LookupAnswer.ts +14 -0
- package/src/LookupFormula.ts +26 -0
- package/src/LookupQuestion.ts +15 -0
- package/src/LookupService.ts +52 -0
- package/src/Output.ts +29 -0
- package/src/STEAK.ts +10 -0
- package/src/TaggedBEEF.ts +10 -0
- package/src/TopicManager.ts +23 -0
- package/src/__tests/Engine.test.ts +792 -0
- package/src/storage/Storage.ts +72 -0
- package/src/storage/knex/KnexStorage.ts +90 -0
- package/src/storage/knex/all-migrations.ts +14 -0
- package/src/storage/knex/migrations/2024-05-18-001-initial.ts +30 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { Output } from '../Output.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Representa a transaction that has been applied to a topic.
|
|
5
|
+
*/
|
|
6
|
+
interface AppliedTransaction {
|
|
7
|
+
/** TXID of the applied transaction */
|
|
8
|
+
txid: string
|
|
9
|
+
/** Output index of the applied transaction */
|
|
10
|
+
topic: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Defines the Storage Engine interface used internally by the Overlay Services Engine.
|
|
15
|
+
*/
|
|
16
|
+
export default interface Storage {
|
|
17
|
+
/**
|
|
18
|
+
* Adds a new output to storage
|
|
19
|
+
* @param utxo — The output to add
|
|
20
|
+
*/
|
|
21
|
+
insertOutput: (utxo: Output) => Promise<void>
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Finds an output from storage
|
|
25
|
+
* @param txid — TXID of hte output to find
|
|
26
|
+
* @param outputIndex — Output index for the output to find
|
|
27
|
+
* @param topic — The topic in which the output is stored
|
|
28
|
+
* @param spent — Whether the output must be spent to be returned
|
|
29
|
+
*/
|
|
30
|
+
findOutput: (txid: string, outputIndex: number, topic?: string, spent?: boolean) => Promise<Output | null>
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Deletes an output from storage
|
|
34
|
+
* @param txid — The TXID of the output to delete
|
|
35
|
+
* @param outputIndex — The index of the output to delete
|
|
36
|
+
* @param topic — The topic where the output should be deleted
|
|
37
|
+
*/
|
|
38
|
+
deleteOutput: (txid: string, outputIndex: number, topic: string) => Promise<void>
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Updates a UTXO as spent
|
|
42
|
+
* @param txid — TXID of the output to update
|
|
43
|
+
* @param outputIndex — Index of the output to update
|
|
44
|
+
* @param topic — Topic in which the output should be updated
|
|
45
|
+
*/
|
|
46
|
+
markUTXOAsSpent: (txid: string, outputIndex: number, topic: string) => Promise<void>
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Updates which outputs are consumed by this output
|
|
50
|
+
* @param txid — TXID of the output to update
|
|
51
|
+
* @param outputIndex — Index of the output to update
|
|
52
|
+
* @param topic — Topic in which the output should be updated
|
|
53
|
+
* @param consumedBy — The new set of outputs consumed by this output
|
|
54
|
+
*/
|
|
55
|
+
updateConsumedBy: (txid: string, outputIndex: number, topic: string, consumedBy: Array<{
|
|
56
|
+
txid: string
|
|
57
|
+
outputIndex: number
|
|
58
|
+
}>) => Promise<void>
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Inserts record of the applied transaction
|
|
62
|
+
* @param tx — The transaction to insert
|
|
63
|
+
*/
|
|
64
|
+
insertAppliedTransaction: (tx: AppliedTransaction) => Promise<void>
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Checks if a duplicate transaction exists
|
|
68
|
+
* @param tx — Transaction to check
|
|
69
|
+
* @returns Whether the transaction is already applied
|
|
70
|
+
*/
|
|
71
|
+
doesAppliedTransactionExist: (tx: AppliedTransaction) => Promise<boolean>
|
|
72
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import Storage from '../Storage.js'
|
|
2
|
+
import { Knex } from 'knex'
|
|
3
|
+
import type { Output } from '../../Output.js'
|
|
4
|
+
|
|
5
|
+
export default class KnexStorage implements Storage {
|
|
6
|
+
knex: Knex
|
|
7
|
+
|
|
8
|
+
constructor(knex: Knex) {
|
|
9
|
+
this.knex = knex
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async findOutput(txid: string, outputIndex: number, topic?: string, spent?: boolean): Promise<Output | null> {
|
|
13
|
+
const search: {
|
|
14
|
+
txid: string,
|
|
15
|
+
outputIndex: number,
|
|
16
|
+
topic?: string,
|
|
17
|
+
spent?: boolean
|
|
18
|
+
} = {
|
|
19
|
+
txid,
|
|
20
|
+
outputIndex
|
|
21
|
+
}
|
|
22
|
+
if (topic !== undefined) search.topic = topic
|
|
23
|
+
if (spent !== undefined) search.spent = spent
|
|
24
|
+
const [output] = await this.knex('outputs').where(search).select(
|
|
25
|
+
'txid', 'outputIndex', 'outputScript', 'topic', 'satoshis', 'beef', 'outputsConsumed', 'spent', 'consumedBy'
|
|
26
|
+
)
|
|
27
|
+
if (!output) {
|
|
28
|
+
return null
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
...output,
|
|
32
|
+
outputScript: [...output.outputScript],
|
|
33
|
+
beef: [...output.beef],
|
|
34
|
+
spent: Boolean(output.spent),
|
|
35
|
+
outputsConsumed: JSON.parse(output.outputsConsumed),
|
|
36
|
+
consumedBy: JSON.parse(output.consumedBy)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async deleteOutput(txid: string, outputIndex: number, topic: string): Promise<void> {
|
|
41
|
+
await this.knex('outputs').where({
|
|
42
|
+
txid, outputIndex, topic
|
|
43
|
+
}).del()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async insertOutput(output: Output) {
|
|
47
|
+
await this.knex('outputs').insert({
|
|
48
|
+
txid: output.txid,
|
|
49
|
+
outputIndex: Number(output.outputIndex),
|
|
50
|
+
outputScript: Buffer.from(output.outputScript),
|
|
51
|
+
topic: output.topic,
|
|
52
|
+
satoshis: Number(output.satoshis),
|
|
53
|
+
beef: [...output.beef],
|
|
54
|
+
outputsConsumed: JSON.stringify(output.outputsConsumed),
|
|
55
|
+
consumedBy: JSON.stringify(output.consumedBy),
|
|
56
|
+
spent: output.spent
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async markUTXOAsSpent(txid: string, outputIndex: number, topic?: string): Promise<void> {
|
|
61
|
+
await this.knex('outputs').where({
|
|
62
|
+
txid,
|
|
63
|
+
outputIndex,
|
|
64
|
+
topic
|
|
65
|
+
}).update('spent', true)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async updateConsumedBy(txid: string, outputIndex: number, topic: string, consumedBy: { txid: string, outputIndex: number }[]) {
|
|
69
|
+
await this.knex('outputs').where({
|
|
70
|
+
txid,
|
|
71
|
+
outputIndex,
|
|
72
|
+
topic
|
|
73
|
+
}).update('consumedBy', consumedBy)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async insertAppliedTransaction(tx: { txid: string, topic: string }) {
|
|
77
|
+
await this.knex('applied_transactions').insert({
|
|
78
|
+
txid: tx.txid,
|
|
79
|
+
topic: tx.topic
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async doesAppliedTransactionExist(tx: { txid: string, topic: string }): Promise<boolean> {
|
|
84
|
+
const appliedTransactions = await this.knex('applied_transactions').where({
|
|
85
|
+
txid: tx.txid,
|
|
86
|
+
topic: tx.topic
|
|
87
|
+
}).select('txid', 'topic')
|
|
88
|
+
return appliedTransactions.length > 0
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Knex } from 'knex'
|
|
2
|
+
import { up as oneUp, down as oneDown } from './migrations/2024-05-18-001-initial.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* An array of all migrations, in order.
|
|
6
|
+
*/
|
|
7
|
+
const allMigrations: {
|
|
8
|
+
up: (knex: Knex) => Promise<void>
|
|
9
|
+
down: (knex: Knex) => Promise<void>
|
|
10
|
+
}[] = [
|
|
11
|
+
{ up: oneUp, down: oneDown }
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
export default allMigrations
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Knex } from 'knex'
|
|
2
|
+
|
|
3
|
+
export async function up(knex: Knex): Promise<void> {
|
|
4
|
+
await knex.schema.createTable('outputs', table => {
|
|
5
|
+
table.increments()
|
|
6
|
+
table.string('txid', 64)
|
|
7
|
+
table.integer('outputIndex', 10)
|
|
8
|
+
table.binary('outputScript')
|
|
9
|
+
table.string('topic')
|
|
10
|
+
table.integer('satoshis', 15)
|
|
11
|
+
table.binary('beef')
|
|
12
|
+
// Represents the outputs that were provided as inputs
|
|
13
|
+
// to the transaction that created this output.
|
|
14
|
+
// This indicates the correct history of this output.
|
|
15
|
+
table.text('outputsConsumed', 'longtext').defaultTo('[]')
|
|
16
|
+
// Tracks any outputs the current output is used as an input in it's creation
|
|
17
|
+
table.text('consumedBy', 'longtext').defaultTo('[]')
|
|
18
|
+
table.boolean('spent').defaultTo(false)
|
|
19
|
+
})
|
|
20
|
+
await knex.schema.createTable('applied_transactions', table => {
|
|
21
|
+
table.increments()
|
|
22
|
+
table.string('txid', 64)
|
|
23
|
+
table.string('topic')
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function down(knex: Knex): Promise<void> {
|
|
28
|
+
await knex.schema.dropTable('applied_transactions')
|
|
29
|
+
await knex.schema.dropTable('outputs')
|
|
30
|
+
}
|