@bsv/overlay 0.1.0-alpha.1 → 0.1.0-alpha.2
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/cjs/mod.js +5 -14
- package/dist/cjs/mod.js.map +1 -1
- package/dist/cjs/package.json +2 -2
- package/dist/cjs/src/Engine.js +110 -43
- package/dist/cjs/src/Engine.js.map +1 -1
- package/dist/cjs/src/storage/knex/KnexStorage.js +25 -3
- package/dist/cjs/src/storage/knex/KnexStorage.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/mod.js +2 -13
- package/dist/esm/mod.js.map +1 -1
- package/dist/esm/src/Engine.js +110 -43
- package/dist/esm/src/Engine.js.map +1 -1
- package/dist/esm/src/storage/knex/KnexStorage.js +24 -3
- package/dist/esm/src/storage/knex/KnexStorage.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/mod.d.ts +12 -12
- package/dist/types/mod.d.ts.map +1 -1
- package/dist/types/src/AdmittanceInstructions.d.ts +2 -2
- package/dist/types/src/AdmittanceInstructions.d.ts.map +1 -1
- package/dist/types/src/Engine.d.ts +46 -26
- package/dist/types/src/Engine.d.ts.map +1 -1
- package/dist/types/src/LookupAnswer.d.ts.map +1 -1
- package/dist/types/src/LookupFormula.d.ts +5 -5
- package/dist/types/src/LookupFormula.d.ts.map +1 -1
- package/dist/types/src/LookupQuestion.d.ts.map +1 -1
- package/dist/types/src/LookupService.d.ts +32 -20
- package/dist/types/src/LookupService.d.ts.map +1 -1
- package/dist/types/src/Output.d.ts +4 -4
- package/dist/types/src/Output.d.ts.map +1 -1
- package/dist/types/src/STEAK.d.ts +1 -1
- package/dist/types/src/TopicManager.d.ts +5 -5
- package/dist/types/src/TopicManager.d.ts.map +1 -1
- package/dist/types/src/storage/Storage.d.ts +47 -34
- package/dist/types/src/storage/Storage.d.ts.map +1 -1
- package/dist/types/src/storage/knex/KnexStorage.d.ts +6 -4
- package/dist/types/src/storage/knex/KnexStorage.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/mod.ts +12 -12
- package/package.json +2 -2
- package/src/AdmittanceInstructions.ts +8 -8
- package/src/Engine.ts +458 -383
- package/src/LookupAnswer.ts +7 -7
- package/src/LookupFormula.ts +21 -21
- package/src/LookupQuestion.ts +9 -9
- package/src/LookupService.ts +54 -36
- package/src/Output.ts +22 -22
- package/src/STEAK.ts +1 -1
- package/src/TopicManager.ts +21 -15
- package/src/__tests/Engine.test.ts +6 -4
- package/src/storage/Storage.ts +49 -34
- package/src/storage/knex/KnexStorage.ts +101 -76
package/src/LookupAnswer.ts
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
* It may comprise either an output list or a freeform response from the Lookup Service.
|
|
4
4
|
*/
|
|
5
5
|
export type LookupAnswer = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
type: 'output-list'
|
|
7
|
+
outputs: Array<{
|
|
8
|
+
beef: number[]
|
|
9
|
+
outputIndex: number
|
|
10
|
+
}>
|
|
11
11
|
} | {
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
type: 'freeform'
|
|
13
|
+
result: unknown
|
|
14
14
|
}
|
package/src/LookupFormula.ts
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The formula that will be used by the Overlay Services Engine to compute the Lookup Answer. Can be returned by Lookup Services in response to a Lookup Question.
|
|
3
3
|
*/
|
|
4
|
-
export type LookupFormula = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
export type LookupFormula = Array<{
|
|
5
|
+
/**
|
|
6
|
+
* TXID of the transaction where an output responsive to the Lookup Question resides.
|
|
7
|
+
*/
|
|
8
|
+
txid: string
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Index of the transaction output responsive to the Lookup Question.
|
|
12
|
+
*/
|
|
13
|
+
outputIndex: number
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
15
|
+
/**
|
|
16
|
+
* Decides what history to incorporate into the Lookup Answer.
|
|
17
|
+
*
|
|
18
|
+
* Optionally directs the Overlay Services Engine as to the historical context (preceding outputs) to include as part of the Lookup Answer.
|
|
19
|
+
* - If a number, denotes how many previous spends (in terms of chain depth) the Engine should include with the Answer.
|
|
20
|
+
* - If a decider function, accepts a BEEF-formatted transaction, an output index and the current depth (relative to the top-level responsive UTXO) as parameters.
|
|
21
|
+
* The function returns a promise for a boolean indicating whether the output should be incorporated into the Lookup Answer.
|
|
22
|
+
* If so, the function will be called again for transactions that preceded the one provided, ultimately allowing the complete shape of the responsive spend history to be described.
|
|
23
|
+
* If not provided, no historical information will be included with the Lookup Answer, except that which may incidentally be required to fully anchor the Lookup Answer to the blockchain.
|
|
24
|
+
*/
|
|
25
|
+
history?: ((beef: number[], outputIndex: number, currentDepth: number) => Promise<boolean>) | number
|
|
26
|
+
}>
|
package/src/LookupQuestion.ts
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
* The question asked to the Overlay Services Engine when a consumer of state wishes to look up information.
|
|
3
3
|
*/
|
|
4
4
|
export type LookupQuestion = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
/**
|
|
6
|
+
* The identifier for a Lookup Service which the person asking the question wishes to use.
|
|
7
|
+
*/
|
|
8
|
+
service: string
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
/**
|
|
11
|
+
* The query which will be forwarded to the Lookup Service.
|
|
12
|
+
* Its type depends on that prescribed by the Lookup Service employed.
|
|
13
|
+
*/
|
|
14
|
+
query: unknown
|
|
15
15
|
}
|
package/src/LookupService.ts
CHANGED
|
@@ -6,47 +6,65 @@ import { Script } from '@bsv/sdk'
|
|
|
6
6
|
/**
|
|
7
7
|
* Defines a Lookup Service interface to be implemented for specific use-cases
|
|
8
8
|
*/
|
|
9
|
-
export
|
|
9
|
+
export interface LookupService {
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Process the event when a new UTXO is let into a topic
|
|
13
|
+
* @param txid - The transaction ID (TXID) of the transaction where the new UTXO resides.
|
|
14
|
+
* @param outputIndex - The index of the transaction output (UTXO) within the transaction.
|
|
15
|
+
* @param outputScript - The script associated with the transaction output.
|
|
16
|
+
* @param topic - The topic to which the new UTXO is being added.
|
|
17
|
+
* @returns A promise that resolves when the processing of the new UTXO is complete.
|
|
18
|
+
*/
|
|
19
|
+
outputAdded?: (txid: string, outputIndex: number, outputScript: Script, topic: string) => Promise<void>
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Processes the spend event for a UTXO.
|
|
23
|
+
*
|
|
24
|
+
* @param txid - The transaction ID of the spent UTXO.
|
|
25
|
+
* @param outputIndex - The index of the transaction output that was spent.
|
|
26
|
+
* @param topic - The topic from which the UTXO was spent.
|
|
27
|
+
*
|
|
28
|
+
* @returns A promise that resolves when processing is complete.
|
|
29
|
+
*/
|
|
30
|
+
outputSpent?: (txid: string, outputIndex: number, topic: string) => Promise<void>
|
|
27
31
|
|
|
28
|
-
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* @param
|
|
32
|
-
* @param
|
|
32
|
+
/**
|
|
33
|
+
* Processes the deletion event for a UTXO.
|
|
34
|
+
*
|
|
35
|
+
* @param txid - The transaction ID of the deleted UTXO.
|
|
36
|
+
* @param outputIndex - The index of the transaction output that was deleted.
|
|
37
|
+
* @param topic - The topic from which the UTXO was deleted.
|
|
38
|
+
*
|
|
39
|
+
* @returns A promise that resolves when processing is complete.
|
|
33
40
|
*/
|
|
34
|
-
|
|
41
|
+
outputDeleted?: (txid: string, outputIndex: number, topic: string) => Promise<void>
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Queries the lookup service for information
|
|
45
|
+
* @param question — The question to be answered by the lookup service
|
|
46
|
+
* @returns — The Lookup Answer or Lookup Formula used to answer the question
|
|
47
|
+
*/
|
|
48
|
+
lookup: (question: LookupQuestion) => Promise<LookupAnswer | LookupFormula>
|
|
42
49
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Returns a Markdown-formatted documentation string for the lookup service.
|
|
52
|
+
*
|
|
53
|
+
* @returns A promise that resolves to a documentation string.
|
|
54
|
+
*/
|
|
55
|
+
getDocumentation: () => Promise<string>
|
|
47
56
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Returns a metadata object that can be used to identify the lookup service.
|
|
59
|
+
*
|
|
60
|
+
* @returns A promise that resolves to a metadata object containing the name, short description,
|
|
61
|
+
* and optional properties such as icon URL, version, and information URL.
|
|
62
|
+
*/
|
|
63
|
+
getMetaData: () => Promise<{
|
|
64
|
+
name: string
|
|
65
|
+
shortDescription: string
|
|
66
|
+
iconURL?: string
|
|
67
|
+
version?: string
|
|
68
|
+
informationURL?: string
|
|
69
|
+
}>
|
|
52
70
|
}
|
package/src/Output.ts
CHANGED
|
@@ -2,28 +2,28 @@
|
|
|
2
2
|
* Represents an output to be tracked by the Overlay Services Engine
|
|
3
3
|
*/
|
|
4
4
|
export type Output = {
|
|
5
|
-
|
|
5
|
+
/** TXID of the output */
|
|
6
|
+
txid: string
|
|
7
|
+
/** index of the output */
|
|
8
|
+
outputIndex: number
|
|
9
|
+
/** script of the output */
|
|
10
|
+
outputScript: number[]
|
|
11
|
+
/** number of satoshis in the output */
|
|
12
|
+
satoshis: number
|
|
13
|
+
/** topic to which the output belongs */
|
|
14
|
+
topic: string
|
|
15
|
+
/** Whether the output is spent */
|
|
16
|
+
spent: boolean
|
|
17
|
+
/** The transaction data for the output */
|
|
18
|
+
beef: number[]
|
|
19
|
+
/** Outputs consumed by the transaction associated with the output */
|
|
20
|
+
outputsConsumed: Array<{
|
|
6
21
|
txid: string
|
|
7
|
-
/** index of the output */
|
|
8
22
|
outputIndex: number
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
/** Whether the output is spent */
|
|
16
|
-
spent: boolean
|
|
17
|
-
/** The transaction data for the output */
|
|
18
|
-
beef: number[]
|
|
19
|
-
/** Outputs consumed by the transaction associated with the output */
|
|
20
|
-
outputsConsumed: {
|
|
21
|
-
txid: string
|
|
22
|
-
outputIndex: number
|
|
23
|
-
}[]
|
|
24
|
-
/** Outputs consuming this output */
|
|
25
|
-
consumedBy: {
|
|
26
|
-
txid: string
|
|
27
|
-
outputIndex: number
|
|
28
|
-
}[]
|
|
23
|
+
}>
|
|
24
|
+
/** Outputs consuming this output */
|
|
25
|
+
consumedBy: Array<{
|
|
26
|
+
txid: string
|
|
27
|
+
outputIndex: number
|
|
28
|
+
}>
|
|
29
29
|
}
|
package/src/STEAK.ts
CHANGED
package/src/TopicManager.ts
CHANGED
|
@@ -3,21 +3,27 @@ import { AdmittanceInstructions } from './AdmittanceInstructions.js'
|
|
|
3
3
|
/**
|
|
4
4
|
* Defines a Topic Manager interface that can be implemented for specific use-cases
|
|
5
5
|
*/
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
export interface TopicManager {
|
|
7
|
+
/**
|
|
8
|
+
* Returns instructions that denote which outputs from the provided transaction to admit into the topic, and which previous coins should be retained.
|
|
9
|
+
* Accepts the transaction in BEEF format and an array of those input indices which spend previously-admitted outputs from the same topic.
|
|
10
|
+
* The transaction's BEEF structure will always contain the transactions associated with previous coins for reference (if any), regardless of whether the current transaction was directly proven.
|
|
11
|
+
*/
|
|
12
|
+
identifyAdmissibleOutputs: (beef: number[], previousCoins: number[]) => Promise<AdmittanceInstructions>
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Returns a Markdown-formatted documentation string for the topic manager.
|
|
16
|
+
*/
|
|
17
|
+
getDocumentation: () => Promise<string>
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Returns a metadata object that can be used to identify the topic manager.
|
|
21
|
+
*/
|
|
22
|
+
getMetaData: () => Promise<{
|
|
23
|
+
name: string
|
|
24
|
+
shortDescription: string
|
|
25
|
+
iconURL?: string
|
|
26
|
+
version?: string
|
|
27
|
+
informationURL?: string
|
|
28
|
+
}>
|
|
23
29
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import Engine from '../Engine'
|
|
2
|
-
import LookupService from '../LookupService'
|
|
3
|
-
import TopicManager from '../TopicManager'
|
|
1
|
+
import { Engine } from '../Engine'
|
|
2
|
+
import { LookupService } from '../LookupService'
|
|
3
|
+
import { TopicManager } from '../TopicManager'
|
|
4
4
|
import { AdmittanceInstructions } from '../AdmittanceInstructions'
|
|
5
|
-
import Storage from '../storage/Storage'
|
|
5
|
+
import { Storage } from '../storage/Storage'
|
|
6
6
|
import { Transaction } from '@bsv/sdk'
|
|
7
7
|
import { Output } from '../Output'
|
|
8
8
|
|
|
@@ -56,8 +56,10 @@ describe('BSV Overlay Services Engine', () => {
|
|
|
56
56
|
insertAppliedTransaction: jest.fn(),
|
|
57
57
|
insertOutput: jest.fn(),
|
|
58
58
|
findOutput: jest.fn(async () => null),
|
|
59
|
+
findOutputsForTransaction: jest.fn(async () => []),
|
|
59
60
|
markUTXOAsSpent: jest.fn(),
|
|
60
61
|
updateConsumedBy: jest.fn(),
|
|
62
|
+
updateOutputBeef: jest.fn(),
|
|
61
63
|
deleteOutput: jest.fn()
|
|
62
64
|
}
|
|
63
65
|
})
|
package/src/storage/Storage.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Output } from '../Output.js'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Represents a transaction that has been applied to a topic.
|
|
5
5
|
*/
|
|
6
6
|
interface AppliedTransaction {
|
|
7
7
|
/** TXID of the applied transaction */
|
|
@@ -13,60 +13,75 @@ interface AppliedTransaction {
|
|
|
13
13
|
/**
|
|
14
14
|
* Defines the Storage Engine interface used internally by the Overlay Services Engine.
|
|
15
15
|
*/
|
|
16
|
-
export
|
|
16
|
+
export interface Storage {
|
|
17
17
|
/**
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
* Adds a new output to storage
|
|
19
|
+
* @param utxo — The output to add
|
|
20
|
+
*/
|
|
21
21
|
insertOutput: (utxo: Output) => Promise<void>
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
30
|
findOutput: (txid: string, outputIndex: number, topic?: string, spent?: boolean) => Promise<Output | null>
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
* Finds outputs with a matching transaction ID from storage
|
|
34
|
+
* @param txid — TXID of the outputs to find
|
|
35
|
+
*/
|
|
36
|
+
findOutputsForTransaction: (txid: string) => Promise<Output[]>
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Deletes an output from storage
|
|
40
|
+
* @param txid — The TXID of the output to delete
|
|
41
|
+
* @param outputIndex — The index of the output to delete
|
|
42
|
+
* @param topic — The topic where the output should be deleted
|
|
43
|
+
*/
|
|
38
44
|
deleteOutput: (txid: string, outputIndex: number, topic: string) => Promise<void>
|
|
39
45
|
|
|
40
46
|
/**
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
* Updates a UTXO as spent
|
|
48
|
+
* @param txid — TXID of the output to update
|
|
49
|
+
* @param outputIndex — Index of the output to update
|
|
50
|
+
* @param topic — Topic in which the output should be updated
|
|
51
|
+
*/
|
|
46
52
|
markUTXOAsSpent: (txid: string, outputIndex: number, topic: string) => Promise<void>
|
|
47
53
|
|
|
48
54
|
/**
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
* Updates which outputs are consumed by this output
|
|
56
|
+
* @param txid — TXID of the output to update
|
|
57
|
+
* @param outputIndex — Index of the output to update
|
|
58
|
+
* @param topic — Topic in which the output should be updated
|
|
59
|
+
* @param consumedBy — The new set of outputs consumed by this output
|
|
60
|
+
*/
|
|
55
61
|
updateConsumedBy: (txid: string, outputIndex: number, topic: string, consumedBy: Array<{
|
|
56
62
|
txid: string
|
|
57
63
|
outputIndex: number
|
|
58
64
|
}>) => Promise<void>
|
|
59
65
|
|
|
60
66
|
/**
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
67
|
+
* Updates the beef data on an output
|
|
68
|
+
* @param txid — TXID of the output to update
|
|
69
|
+
* @param outputIndex — Index of the output to update
|
|
70
|
+
* @param topic — Topic in which the output should be updated
|
|
71
|
+
* @param beef - BEEF data to update
|
|
72
|
+
*/
|
|
73
|
+
updateOutputBeef: (txid: string, outputIndex: number, topic: string, beef: number[]) => Promise<void>
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Inserts record of the applied transaction
|
|
77
|
+
* @param tx — The transaction to insert
|
|
78
|
+
*/
|
|
64
79
|
insertAppliedTransaction: (tx: AppliedTransaction) => Promise<void>
|
|
65
80
|
|
|
66
81
|
/**
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
82
|
+
* Checks if a duplicate transaction exists
|
|
83
|
+
* @param tx — Transaction to check
|
|
84
|
+
* @returns Whether the transaction is already applied
|
|
85
|
+
*/
|
|
71
86
|
doesAppliedTransactionExist: (tx: AppliedTransaction) => Promise<boolean>
|
|
72
87
|
}
|
|
@@ -1,90 +1,115 @@
|
|
|
1
|
-
import Storage from '../Storage.js'
|
|
1
|
+
import { Storage } from '../Storage.js'
|
|
2
2
|
import { Knex } from 'knex'
|
|
3
3
|
import type { Output } from '../../Output.js'
|
|
4
4
|
|
|
5
|
-
export
|
|
6
|
-
|
|
5
|
+
export class KnexStorage implements Storage {
|
|
6
|
+
knex: Knex
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
constructor(knex: Knex) {
|
|
9
|
+
this.knex = knex
|
|
10
|
+
}
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
}
|
|
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
|
|
38
21
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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 === undefined || output === null) {
|
|
28
|
+
return null
|
|
44
29
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
})
|
|
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)
|
|
58
37
|
}
|
|
38
|
+
}
|
|
59
39
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
40
|
+
async findOutputsForTransaction(txid: string): Promise<Output[]> {
|
|
41
|
+
const [output] = await this.knex('outputs').where({ txid }).select(
|
|
42
|
+
'txid', 'outputIndex', 'outputScript', 'topic', 'satoshis', 'beef', 'outputsConsumed', 'spent', 'consumedBy'
|
|
43
|
+
)
|
|
44
|
+
if (output === undefined || output === null) {
|
|
45
|
+
return []
|
|
66
46
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
47
|
+
return {
|
|
48
|
+
...output,
|
|
49
|
+
outputScript: [...output.outputScript],
|
|
50
|
+
beef: [...output.beef],
|
|
51
|
+
spent: Boolean(output.spent),
|
|
52
|
+
outputsConsumed: JSON.parse(output.outputsConsumed),
|
|
53
|
+
consumedBy: JSON.parse(output.consumedBy)
|
|
74
54
|
}
|
|
55
|
+
}
|
|
75
56
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
57
|
+
async deleteOutput(txid: string, outputIndex: number, topic: string): Promise<void> {
|
|
58
|
+
await this.knex('outputs').where({
|
|
59
|
+
txid, outputIndex, topic
|
|
60
|
+
}).del()
|
|
61
|
+
}
|
|
82
62
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
63
|
+
async insertOutput(output: Output): Promise<void> {
|
|
64
|
+
await this.knex('outputs').insert({
|
|
65
|
+
txid: output.txid,
|
|
66
|
+
outputIndex: Number(output.outputIndex),
|
|
67
|
+
outputScript: Buffer.from(output.outputScript),
|
|
68
|
+
topic: output.topic,
|
|
69
|
+
satoshis: Number(output.satoshis),
|
|
70
|
+
beef: Buffer.from(new Uint8Array(output.beef)),
|
|
71
|
+
outputsConsumed: JSON.stringify(output.outputsConsumed),
|
|
72
|
+
consumedBy: JSON.stringify(output.consumedBy),
|
|
73
|
+
spent: output.spent
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async markUTXOAsSpent(txid: string, outputIndex: number, topic?: string): Promise<void> {
|
|
78
|
+
await this.knex('outputs').where({
|
|
79
|
+
txid,
|
|
80
|
+
outputIndex,
|
|
81
|
+
topic
|
|
82
|
+
}).update('spent', true)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async updateConsumedBy(txid: string, outputIndex: number, topic: string, consumedBy: Array<{ txid: string, outputIndex: number }>): Promise<void> {
|
|
86
|
+
await this.knex('outputs').where({
|
|
87
|
+
txid,
|
|
88
|
+
outputIndex,
|
|
89
|
+
topic
|
|
90
|
+
}).update('consumedBy', consumedBy)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async updateOutputBeef(txid: string, outputIndex: number, topic: string, beef: number[]): Promise<void> {
|
|
94
|
+
await this.knex('outputs').where({
|
|
95
|
+
txid,
|
|
96
|
+
outputIndex,
|
|
97
|
+
topic
|
|
98
|
+
}).update('beef', beef)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async insertAppliedTransaction(tx: { txid: string, topic: string }): Promise<void> {
|
|
102
|
+
await this.knex('applied_transactions').insert({
|
|
103
|
+
txid: tx.txid,
|
|
104
|
+
topic: tx.topic
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async doesAppliedTransactionExist(tx: { txid: string, topic: string }): Promise<boolean> {
|
|
109
|
+
const appliedTransactions = await this.knex('applied_transactions').where({
|
|
110
|
+
txid: tx.txid,
|
|
111
|
+
topic: tx.topic
|
|
112
|
+
}).select('txid', 'topic')
|
|
113
|
+
return appliedTransactions.length > 0
|
|
114
|
+
}
|
|
90
115
|
}
|