@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.
Files changed (119) hide show
  1. package/LICENSE.txt +28 -0
  2. package/README.md +220 -0
  3. package/dist/cjs/mod.js +43 -0
  4. package/dist/cjs/mod.js.map +1 -0
  5. package/dist/cjs/package.json +53 -0
  6. package/dist/cjs/src/AdmittanceInstructions.js +3 -0
  7. package/dist/cjs/src/AdmittanceInstructions.js.map +1 -0
  8. package/dist/cjs/src/Engine.js +361 -0
  9. package/dist/cjs/src/Engine.js.map +1 -0
  10. package/dist/cjs/src/LookupAnswer.js +3 -0
  11. package/dist/cjs/src/LookupAnswer.js.map +1 -0
  12. package/dist/cjs/src/LookupFormula.js +3 -0
  13. package/dist/cjs/src/LookupFormula.js.map +1 -0
  14. package/dist/cjs/src/LookupQuestion.js +3 -0
  15. package/dist/cjs/src/LookupQuestion.js.map +1 -0
  16. package/dist/cjs/src/LookupService.js +3 -0
  17. package/dist/cjs/src/LookupService.js.map +1 -0
  18. package/dist/cjs/src/Output.js +3 -0
  19. package/dist/cjs/src/Output.js.map +1 -0
  20. package/dist/cjs/src/STEAK.js +3 -0
  21. package/dist/cjs/src/STEAK.js.map +1 -0
  22. package/dist/cjs/src/TaggedBEEF.js +3 -0
  23. package/dist/cjs/src/TaggedBEEF.js.map +1 -0
  24. package/dist/cjs/src/TopicManager.js +3 -0
  25. package/dist/cjs/src/TopicManager.js.map +1 -0
  26. package/dist/cjs/src/storage/Storage.js +3 -0
  27. package/dist/cjs/src/storage/Storage.js.map +1 -0
  28. package/dist/cjs/src/storage/knex/KnexStorage.js +76 -0
  29. package/dist/cjs/src/storage/knex/KnexStorage.js.map +1 -0
  30. package/dist/cjs/src/storage/knex/all-migrations.js +11 -0
  31. package/dist/cjs/src/storage/knex/all-migrations.js.map +1 -0
  32. package/dist/cjs/src/storage/knex/migrations/2024-05-18-001-initial.js +33 -0
  33. package/dist/cjs/src/storage/knex/migrations/2024-05-18-001-initial.js.map +1 -0
  34. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
  35. package/dist/esm/mod.js +17 -0
  36. package/dist/esm/mod.js.map +1 -0
  37. package/dist/esm/src/AdmittanceInstructions.js +2 -0
  38. package/dist/esm/src/AdmittanceInstructions.js.map +1 -0
  39. package/dist/esm/src/Engine.js +357 -0
  40. package/dist/esm/src/Engine.js.map +1 -0
  41. package/dist/esm/src/LookupAnswer.js +2 -0
  42. package/dist/esm/src/LookupAnswer.js.map +1 -0
  43. package/dist/esm/src/LookupFormula.js +2 -0
  44. package/dist/esm/src/LookupFormula.js.map +1 -0
  45. package/dist/esm/src/LookupQuestion.js +2 -0
  46. package/dist/esm/src/LookupQuestion.js.map +1 -0
  47. package/dist/esm/src/LookupService.js +2 -0
  48. package/dist/esm/src/LookupService.js.map +1 -0
  49. package/dist/esm/src/Output.js +2 -0
  50. package/dist/esm/src/Output.js.map +1 -0
  51. package/dist/esm/src/STEAK.js +2 -0
  52. package/dist/esm/src/STEAK.js.map +1 -0
  53. package/dist/esm/src/TaggedBEEF.js +2 -0
  54. package/dist/esm/src/TaggedBEEF.js.map +1 -0
  55. package/dist/esm/src/TopicManager.js +2 -0
  56. package/dist/esm/src/TopicManager.js.map +1 -0
  57. package/dist/esm/src/storage/Storage.js +2 -0
  58. package/dist/esm/src/storage/Storage.js.map +1 -0
  59. package/dist/esm/src/storage/knex/KnexStorage.js +74 -0
  60. package/dist/esm/src/storage/knex/KnexStorage.js.map +1 -0
  61. package/dist/esm/src/storage/knex/all-migrations.js +9 -0
  62. package/dist/esm/src/storage/knex/all-migrations.js.map +1 -0
  63. package/dist/esm/src/storage/knex/migrations/2024-05-18-001-initial.js +28 -0
  64. package/dist/esm/src/storage/knex/migrations/2024-05-18-001-initial.js.map +1 -0
  65. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
  66. package/dist/types/mod.d.ts +14 -0
  67. package/dist/types/mod.d.ts.map +1 -0
  68. package/dist/types/src/AdmittanceInstructions.d.ts +14 -0
  69. package/dist/types/src/AdmittanceInstructions.d.ts.map +1 -0
  70. package/dist/types/src/Engine.d.ts +92 -0
  71. package/dist/types/src/Engine.d.ts.map +1 -0
  72. package/dist/types/src/LookupAnswer.d.ts +15 -0
  73. package/dist/types/src/LookupAnswer.d.ts.map +1 -0
  74. package/dist/types/src/LookupFormula.d.ts +25 -0
  75. package/dist/types/src/LookupFormula.d.ts.map +1 -0
  76. package/dist/types/src/LookupQuestion.d.ts +15 -0
  77. package/dist/types/src/LookupQuestion.d.ts.map +1 -0
  78. package/dist/types/src/LookupService.d.ts +52 -0
  79. package/dist/types/src/LookupService.d.ts.map +1 -0
  80. package/dist/types/src/Output.d.ts +30 -0
  81. package/dist/types/src/Output.d.ts.map +1 -0
  82. package/dist/types/src/STEAK.d.ts +10 -0
  83. package/dist/types/src/STEAK.d.ts.map +1 -0
  84. package/dist/types/src/TaggedBEEF.d.ts +11 -0
  85. package/dist/types/src/TaggedBEEF.d.ts.map +1 -0
  86. package/dist/types/src/TopicManager.d.ts +27 -0
  87. package/dist/types/src/TopicManager.d.ts.map +1 -0
  88. package/dist/types/src/storage/Storage.d.ts +66 -0
  89. package/dist/types/src/storage/Storage.d.ts.map +1 -0
  90. package/dist/types/src/storage/knex/KnexStorage.d.ts +24 -0
  91. package/dist/types/src/storage/knex/KnexStorage.d.ts.map +1 -0
  92. package/dist/types/src/storage/knex/all-migrations.d.ts +10 -0
  93. package/dist/types/src/storage/knex/all-migrations.d.ts.map +1 -0
  94. package/dist/types/src/storage/knex/migrations/2024-05-18-001-initial.d.ts +4 -0
  95. package/dist/types/src/storage/knex/migrations/2024-05-18-001-initial.d.ts.map +1 -0
  96. package/dist/types/tsconfig.types.tsbuildinfo +1 -0
  97. package/docs/API.md +621 -0
  98. package/docs/README.md +8 -0
  99. package/docs/concepts/README.md +4 -0
  100. package/docs/examples/README.md +5 -0
  101. package/docs/examples/gs-wip.md +105 -0
  102. package/docs/internal/README.md +4 -0
  103. package/mod.ts +18 -0
  104. package/package.json +78 -0
  105. package/src/AdmittanceInstructions.ts +14 -0
  106. package/src/Engine.ts +419 -0
  107. package/src/LookupAnswer.ts +14 -0
  108. package/src/LookupFormula.ts +26 -0
  109. package/src/LookupQuestion.ts +15 -0
  110. package/src/LookupService.ts +52 -0
  111. package/src/Output.ts +29 -0
  112. package/src/STEAK.ts +10 -0
  113. package/src/TaggedBEEF.ts +10 -0
  114. package/src/TopicManager.ts +23 -0
  115. package/src/__tests/Engine.test.ts +792 -0
  116. package/src/storage/Storage.ts +72 -0
  117. package/src/storage/knex/KnexStorage.ts +90 -0
  118. package/src/storage/knex/all-migrations.ts +14 -0
  119. 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
+ }