@bsv/overlay-discovery-services 0.1.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/LICENSE.txt +28 -0
- package/README.md +13 -0
- package/dist/cjs/mod.js +28 -0
- package/dist/cjs/mod.js.map +1 -0
- package/dist/cjs/package.json +59 -0
- package/dist/cjs/src/LegacyNinjaAdvertiser.js +235 -0
- package/dist/cjs/src/LegacyNinjaAdvertiser.js.map +1 -0
- package/dist/cjs/src/NinjaAdvertiser.js +234 -0
- package/dist/cjs/src/NinjaAdvertiser.js.map +1 -0
- package/dist/cjs/src/SHIP/SHIPLookupService.js +116 -0
- package/dist/cjs/src/SHIP/SHIPLookupService.js.map +1 -0
- package/dist/cjs/src/SHIP/SHIPStorage.js +87 -0
- package/dist/cjs/src/SHIP/SHIPStorage.js.map +1 -0
- package/dist/cjs/src/SHIP/SHIPTopicManager.js +84 -0
- package/dist/cjs/src/SHIP/SHIPTopicManager.js.map +1 -0
- package/dist/cjs/src/SLAP/SLAPLookupService.js +114 -0
- package/dist/cjs/src/SLAP/SLAPLookupService.js.map +1 -0
- package/dist/cjs/src/SLAP/SLAPStorage.js +77 -0
- package/dist/cjs/src/SLAP/SLAPStorage.js.map +1 -0
- package/dist/cjs/src/SLAP/SLAPTopicManager.js +84 -0
- package/dist/cjs/src/SLAP/SLAPTopicManager.js.map +1 -0
- package/dist/cjs/src/types.js +3 -0
- package/dist/cjs/src/types.js.map +1 -0
- package/dist/cjs/src/utils/generateDocs.js +81 -0
- package/dist/cjs/src/utils/generateDocs.js.map +1 -0
- package/dist/cjs/src/utils/getDocumentation.js +22 -0
- package/dist/cjs/src/utils/getDocumentation.js.map +1 -0
- package/dist/cjs/src/utils/isValidDomain.js +15 -0
- package/dist/cjs/src/utils/isValidDomain.js.map +1 -0
- package/dist/cjs/src/utils/isValidServiceName.js +14 -0
- package/dist/cjs/src/utils/isValidServiceName.js.map +1 -0
- package/dist/cjs/src/utils/verifyToken.js +22 -0
- package/dist/cjs/src/utils/verifyToken.js.map +1 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/esm/mod.js +12 -0
- package/dist/esm/mod.js.map +1 -0
- package/dist/esm/src/LegacyNinjaAdvertiser.js +233 -0
- package/dist/esm/src/LegacyNinjaAdvertiser.js.map +1 -0
- package/dist/esm/src/NinjaAdvertiser.js +232 -0
- package/dist/esm/src/NinjaAdvertiser.js.map +1 -0
- package/dist/esm/src/SHIP/SHIPLookupService.js +110 -0
- package/dist/esm/src/SHIP/SHIPLookupService.js.map +1 -0
- package/dist/esm/src/SHIP/SHIPStorage.js +85 -0
- package/dist/esm/src/SHIP/SHIPStorage.js.map +1 -0
- package/dist/esm/src/SHIP/SHIPTopicManager.js +77 -0
- package/dist/esm/src/SHIP/SHIPTopicManager.js.map +1 -0
- package/dist/esm/src/SLAP/SLAPLookupService.js +108 -0
- package/dist/esm/src/SLAP/SLAPLookupService.js.map +1 -0
- package/dist/esm/src/SLAP/SLAPStorage.js +75 -0
- package/dist/esm/src/SLAP/SLAPStorage.js.map +1 -0
- package/dist/esm/src/SLAP/SLAPTopicManager.js +77 -0
- package/dist/esm/src/SLAP/SLAPTopicManager.js.map +1 -0
- package/dist/esm/src/types.js +2 -0
- package/dist/esm/src/types.js.map +1 -0
- package/dist/esm/src/utils/generateDocs.js +46 -0
- package/dist/esm/src/utils/generateDocs.js.map +1 -0
- package/dist/esm/src/utils/getDocumentation.js +20 -0
- package/dist/esm/src/utils/getDocumentation.js.map +1 -0
- package/dist/esm/src/utils/isValidDomain.js +11 -0
- package/dist/esm/src/utils/isValidDomain.js.map +1 -0
- package/dist/esm/src/utils/isValidServiceName.js +10 -0
- package/dist/esm/src/utils/isValidServiceName.js.map +1 -0
- package/dist/esm/src/utils/verifyToken.js +18 -0
- package/dist/esm/src/utils/verifyToken.js.map +1 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
- package/dist/types/mod.d.ts +12 -0
- package/dist/types/mod.d.ts.map +1 -0
- package/dist/types/src/LegacyNinjaAdvertiser.d.ts +60 -0
- package/dist/types/src/LegacyNinjaAdvertiser.d.ts.map +1 -0
- package/dist/types/src/NinjaAdvertiser.d.ts +60 -0
- package/dist/types/src/NinjaAdvertiser.d.ts.map +1 -0
- package/dist/types/src/SHIP/SHIPLookupService.d.ts +58 -0
- package/dist/types/src/SHIP/SHIPLookupService.d.ts.map +1 -0
- package/dist/types/src/SHIP/SHIPStorage.d.ts +48 -0
- package/dist/types/src/SHIP/SHIPStorage.d.ts.map +1 -0
- package/dist/types/src/SHIP/SHIPTopicManager.d.ts +34 -0
- package/dist/types/src/SHIP/SHIPTopicManager.d.ts.map +1 -0
- package/dist/types/src/SLAP/SLAPLookupService.d.ts +59 -0
- package/dist/types/src/SLAP/SLAPLookupService.d.ts.map +1 -0
- package/dist/types/src/SLAP/SLAPStorage.d.ts +48 -0
- package/dist/types/src/SLAP/SLAPStorage.d.ts.map +1 -0
- package/dist/types/src/SLAP/SLAPTopicManager.d.ts +34 -0
- package/dist/types/src/SLAP/SLAPTopicManager.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +29 -0
- package/dist/types/src/types.d.ts.map +1 -0
- package/dist/types/src/utils/generateDocs.d.ts +2 -0
- package/dist/types/src/utils/generateDocs.d.ts.map +1 -0
- package/dist/types/src/utils/getDocumentation.d.ts +8 -0
- package/dist/types/src/utils/getDocumentation.d.ts.map +1 -0
- package/dist/types/src/utils/isValidDomain.d.ts +7 -0
- package/dist/types/src/utils/isValidDomain.d.ts.map +1 -0
- package/dist/types/src/utils/isValidServiceName.d.ts +7 -0
- package/dist/types/src/utils/isValidServiceName.d.ts.map +1 -0
- package/dist/types/src/utils/verifyToken.d.ts +12 -0
- package/dist/types/src/utils/verifyToken.d.ts.map +1 -0
- package/dist/types/tsconfig.types.tsbuildinfo +1 -0
- package/docs/SHIP/ship-lookup-service.md +352 -0
- package/docs/SHIP/ship-storage.md +207 -0
- package/docs/SHIP/ship-topic-manager.md +122 -0
- package/docs/SLAP/slap-lookup-service.md +353 -0
- package/docs/SLAP/slap-storage.md +207 -0
- package/docs/SLAP/slap-topic-manager.md +122 -0
- package/mod.ts +15 -0
- package/package.json +74 -0
- package/src/LegacyNinjaAdvertiser.ts +260 -0
- package/src/SHIP/SHIPLookupService.ts +122 -0
- package/src/SHIP/SHIPStorage.ts +96 -0
- package/src/SHIP/SHIPTopicManager.ts +89 -0
- package/src/SLAP/SLAPLookupService.ts +121 -0
- package/src/SLAP/SLAPStorage.ts +81 -0
- package/src/SLAP/SLAPTopicManager.ts +88 -0
- package/src/types.d.ts +2 -0
- package/src/types.ts +32 -0
- package/src/utils/generateDocs.ts +53 -0
- package/src/utils/getDocumentation.ts +19 -0
- package/src/utils/isValidDomain.ts +10 -0
- package/src/utils/isValidServiceName.ts +9 -0
- package/src/utils/verifyToken.ts +26 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SHIPLookupService = void 0;
|
|
7
|
+
const pushdrop_1 = __importDefault(require("pushdrop"));
|
|
8
|
+
const getDocumentation_js_1 = require("../utils/getDocumentation.js");
|
|
9
|
+
/**
|
|
10
|
+
* Implements the SHIP lookup service
|
|
11
|
+
*
|
|
12
|
+
* The SHIP lookup service allows querying for overlay services hosting specific topics
|
|
13
|
+
* within the overlay network.
|
|
14
|
+
*/
|
|
15
|
+
class SHIPLookupService {
|
|
16
|
+
constructor(storage) {
|
|
17
|
+
this.storage = storage;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Handles the addition of a new output to the topic.
|
|
21
|
+
* @param txid - The transaction ID containing the output.
|
|
22
|
+
* @param outputIndex - The index of the output in the transaction.
|
|
23
|
+
* @param outputScript - The script of the output to be processed.
|
|
24
|
+
* @param topic - The topic associated with the output.
|
|
25
|
+
*/
|
|
26
|
+
async outputAdded(txid, outputIndex, outputScript, topic) {
|
|
27
|
+
if (topic !== 'tm_ship')
|
|
28
|
+
return;
|
|
29
|
+
const result = pushdrop_1.default.decode({
|
|
30
|
+
script: outputScript.toHex(),
|
|
31
|
+
fieldFormat: 'buffer'
|
|
32
|
+
});
|
|
33
|
+
const shipIdentifier = result.fields[0].toString();
|
|
34
|
+
const identityKey = result.fields[1].toString('hex');
|
|
35
|
+
const domain = result.fields[2].toString();
|
|
36
|
+
const topicSupported = result.fields[3].toString();
|
|
37
|
+
if (shipIdentifier !== 'SHIP')
|
|
38
|
+
return;
|
|
39
|
+
await this.storage.storeSHIPRecord(txid, outputIndex, identityKey, domain, topicSupported);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Handles the spending of an output in the topic.
|
|
43
|
+
* @param txid - The transaction ID of the spent output.
|
|
44
|
+
* @param outputIndex - The index of the spent output.
|
|
45
|
+
* @param topic - The topic associated with the spent output.
|
|
46
|
+
*/
|
|
47
|
+
async outputSpent(txid, outputIndex, topic) {
|
|
48
|
+
if (topic !== 'tm_ship')
|
|
49
|
+
return;
|
|
50
|
+
await this.storage.deleteSHIPRecord(txid, outputIndex);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Handles the deletion of an output in the topic.
|
|
54
|
+
* @param txid - The transaction ID of the deleted output.
|
|
55
|
+
* @param outputIndex - The index of the deleted output.
|
|
56
|
+
* @param topic - The topic associated with the deleted output.
|
|
57
|
+
*/
|
|
58
|
+
async outputDeleted(txid, outputIndex, topic) {
|
|
59
|
+
if (topic !== 'tm_ship')
|
|
60
|
+
return;
|
|
61
|
+
await this.storage.deleteSHIPRecord(txid, outputIndex);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Answers a lookup query.
|
|
65
|
+
* @param question - The lookup question to be answered.
|
|
66
|
+
* @returns A promise that resolves to a lookup answer or formula.
|
|
67
|
+
*/
|
|
68
|
+
async lookup(question) {
|
|
69
|
+
if (question.query === undefined || question.query === null) {
|
|
70
|
+
throw new Error('A valid query must be provided!');
|
|
71
|
+
}
|
|
72
|
+
if (question.service !== 'ls_ship') {
|
|
73
|
+
throw new Error('Lookup service not supported!');
|
|
74
|
+
}
|
|
75
|
+
if (question.query === 'findAll') {
|
|
76
|
+
return await this.storage.findAll();
|
|
77
|
+
}
|
|
78
|
+
const { domain, topics } = question.query;
|
|
79
|
+
// Validate lookup query
|
|
80
|
+
if (domain !== undefined && domain !== null && topics !== undefined && topics !== null) {
|
|
81
|
+
// If both domain and topic are provided, construct a query with both
|
|
82
|
+
const records = await this.storage.findRecord({ domain, topics });
|
|
83
|
+
return records;
|
|
84
|
+
}
|
|
85
|
+
else if (domain !== undefined && domain !== null) {
|
|
86
|
+
const records = await this.storage.findRecord({ domain });
|
|
87
|
+
return records;
|
|
88
|
+
}
|
|
89
|
+
else if (topics !== undefined && topics !== null) {
|
|
90
|
+
const records = await this.storage.findRecord({ topics });
|
|
91
|
+
return records;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
throw new Error('A valid domain or topic must be provided in the query!');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Returns documentation specific to this overlay lookup service.
|
|
99
|
+
* @returns A promise that resolves to the documentation string.
|
|
100
|
+
*/
|
|
101
|
+
async getDocumentation() {
|
|
102
|
+
return await (0, getDocumentation_js_1.getDocumentation)('./docs/SHIP/ship-lookup-service.md');
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Returns metadata associated with this lookup service.
|
|
106
|
+
* @returns A promise that resolves to an object containing metadata.
|
|
107
|
+
*/
|
|
108
|
+
async getMetaData() {
|
|
109
|
+
return {
|
|
110
|
+
name: 'SHIP Lookup Service',
|
|
111
|
+
shortDescription: 'Provides lookup capabilities for SHIP tokens.'
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
exports.SHIPLookupService = SHIPLookupService;
|
|
116
|
+
//# sourceMappingURL=SHIPLookupService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SHIPLookupService.js","sourceRoot":"","sources":["../../../../src/SHIP/SHIPLookupService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SHIPStorage = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Implements a storage engine for SHIP protocol
|
|
6
|
+
*/
|
|
7
|
+
class SHIPStorage {
|
|
8
|
+
/**
|
|
9
|
+
* Constructs a new SHIPStorage instance
|
|
10
|
+
* @param {Db} db - connected mongo database instance
|
|
11
|
+
*/
|
|
12
|
+
constructor(db) {
|
|
13
|
+
this.db = db;
|
|
14
|
+
this.shipRecords = db.collection('shipRecords');
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Ensures the necessary indexes are created for the collections.
|
|
18
|
+
*/
|
|
19
|
+
async ensureIndexes() {
|
|
20
|
+
await this.shipRecords.createIndex({ domain: 1, topic: 1 });
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Stores a SHIP record
|
|
24
|
+
* @param {string} txid transaction id
|
|
25
|
+
* @param {number} outputIndex index of the UTXO
|
|
26
|
+
* @param {string} identityKey identity key
|
|
27
|
+
* @param {string} domain domain name
|
|
28
|
+
* @param {string} topic topic name
|
|
29
|
+
*/
|
|
30
|
+
async storeSHIPRecord(txid, outputIndex, identityKey, domain, topic) {
|
|
31
|
+
await this.shipRecords.insertOne({
|
|
32
|
+
txid,
|
|
33
|
+
outputIndex,
|
|
34
|
+
identityKey,
|
|
35
|
+
domain,
|
|
36
|
+
topic,
|
|
37
|
+
createdAt: new Date()
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Deletes a SHIP record
|
|
42
|
+
* @param {string} txid transaction id
|
|
43
|
+
* @param {number} outputIndex index of the UTXO
|
|
44
|
+
*/
|
|
45
|
+
async deleteSHIPRecord(txid, outputIndex) {
|
|
46
|
+
await this.shipRecords.deleteOne({ txid, outputIndex });
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Finds SHIP records based on a given query object.
|
|
50
|
+
* @param {Object} query The query object which may contain properties for domain or topics.
|
|
51
|
+
* @returns {Promise<UTXOReference[]>} Returns matching UTXO references.
|
|
52
|
+
*/
|
|
53
|
+
async findRecord(query) {
|
|
54
|
+
const mongoQuery = {};
|
|
55
|
+
// Add domain to the query if provided
|
|
56
|
+
if (query.domain) {
|
|
57
|
+
mongoQuery.domain = query.domain;
|
|
58
|
+
}
|
|
59
|
+
// Add topics to the query if provided
|
|
60
|
+
if (query.topics && Array.isArray(query.topics)) {
|
|
61
|
+
mongoQuery.topic = { $in: query.topics };
|
|
62
|
+
}
|
|
63
|
+
return await this.shipRecords
|
|
64
|
+
.find(mongoQuery)
|
|
65
|
+
.project({ txid: 1, outputIndex: 1 })
|
|
66
|
+
.toArray()
|
|
67
|
+
.then((results) => results.map((record) => ({
|
|
68
|
+
txid: record.txid,
|
|
69
|
+
outputIndex: record.outputIndex,
|
|
70
|
+
})));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Returns all results tracked by the overlay
|
|
74
|
+
* @returns {Promise<UTXOReference[]>} returns matching UTXO references
|
|
75
|
+
*/
|
|
76
|
+
async findAll() {
|
|
77
|
+
return await this.shipRecords.find({})
|
|
78
|
+
.project({ txid: 1, outputIndex: 1 })
|
|
79
|
+
.toArray()
|
|
80
|
+
.then(results => results.map(shipRecords => ({
|
|
81
|
+
txid: shipRecords.txid,
|
|
82
|
+
outputIndex: shipRecords.outputIndex
|
|
83
|
+
})));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.SHIPStorage = SHIPStorage;
|
|
87
|
+
//# sourceMappingURL=SHIPStorage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SHIPStorage.js","sourceRoot":"","sources":["../../../../src/SHIP/SHIPStorage.ts"],"names":[],"mappings":";;;AAGA;;GAEG;AACH,MAAa,WAAW;IAGtB;;;OAGG;IACH,YAA6B,EAAM;QAAN,OAAE,GAAF,EAAE,CAAI;QACjC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,UAAU,CAAa,aAAa,CAAC,CAAA;IAC7D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;IAC7D,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,eAAe,CAAC,IAAY,EAAE,WAAmB,EAAE,WAAmB,EAAE,MAAc,EAAE,KAAa;QACzG,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;YAC/B,IAAI;YACJ,WAAW;YACX,WAAW;YACX,MAAM;YACN,KAAK;YACL,SAAS,EAAE,IAAI,IAAI,EAAE;SACtB,CAAC,CAAA;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,gBAAgB,CAAC,IAAY,EAAE,WAAmB;QACtD,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAA;IACzD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,UAAU,CAAC,KAA6C;QAC5D,MAAM,UAAU,GAAQ,EAAE,CAAA;QAE1B,sCAAsC;QACtC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAA;QAClC,CAAC;QAED,sCAAsC;QACtC,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YAChD,UAAU,CAAC,KAAK,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,CAAA;QAC1C,CAAC;QAED,OAAO,MAAM,IAAI,CAAC,WAAW;aAC1B,IAAI,CAAC,UAAU,CAAC;aAChB,OAAO,CAAgB,EAAE,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;aACnD,OAAO,EAAE;aACT,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAChB,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACvB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,WAAW,EAAE,MAAM,CAAC,WAAW;SAChC,CAAC,CAAC,CACJ,CAAA;IACL,CAAC;IAED;;;KAGC;IACD,KAAK,CAAC,OAAO;QACX,OAAO,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;aACnC,OAAO,CAAgB,EAAE,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;aACnD,OAAO,EAAE;aACT,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YAC3C,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,WAAW,EAAE,WAAW,CAAC,WAAW;SACrC,CAAC,CAAC,CAAC,CAAA;IACR,CAAC;CACF;AAzFD,kCAyFC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SHIPTopicManager = void 0;
|
|
7
|
+
const sdk_1 = require("@bsv/sdk");
|
|
8
|
+
const pushdrop_1 = __importDefault(require("pushdrop"));
|
|
9
|
+
const verifyToken_js_1 = require("../utils/verifyToken.js");
|
|
10
|
+
const isValidDomain_js_1 = require("../utils/isValidDomain.js");
|
|
11
|
+
const getDocumentation_js_1 = require("../utils/getDocumentation.js");
|
|
12
|
+
/**
|
|
13
|
+
* SHIP Topic Manager
|
|
14
|
+
* Implements the TopicManager interface for SHIP (Service Host Interconnect Protocol) tokens.
|
|
15
|
+
*
|
|
16
|
+
* The SHIP Topic Manager identifies admissible outputs based on SHIP protocol requirements.
|
|
17
|
+
* SHIP tokens facilitate the advertisement of nodes hosting specific topics within the overlay network.
|
|
18
|
+
*/
|
|
19
|
+
class SHIPTopicManager {
|
|
20
|
+
/**
|
|
21
|
+
* Identifies admissible outputs for SHIP tokens.
|
|
22
|
+
* @param beef - The transaction data in BEEF format.
|
|
23
|
+
* @param previousCoins - The previous coins to consider.
|
|
24
|
+
* @returns A promise that resolves with the admittance instructions.
|
|
25
|
+
*/
|
|
26
|
+
async identifyAdmissibleOutputs(beef, previousCoins) {
|
|
27
|
+
const outputsToAdmit = [];
|
|
28
|
+
try {
|
|
29
|
+
const parsedTransaction = sdk_1.Transaction.fromBEEF(beef);
|
|
30
|
+
for (const [i, output] of parsedTransaction.outputs.entries()) {
|
|
31
|
+
try {
|
|
32
|
+
const result = pushdrop_1.default.decode({
|
|
33
|
+
script: output.lockingScript.toHex(),
|
|
34
|
+
fieldFormat: 'buffer'
|
|
35
|
+
});
|
|
36
|
+
if (result.fields.length !== 4)
|
|
37
|
+
continue; // SHIP tokens should have 4 fields
|
|
38
|
+
const shipIdentifier = result.fields[0].toString();
|
|
39
|
+
const identityKey = result.fields[1].toString('hex');
|
|
40
|
+
const domain = result.fields[2].toString();
|
|
41
|
+
// const topic = result.fields[3].toString()
|
|
42
|
+
if (shipIdentifier !== 'SHIP')
|
|
43
|
+
continue;
|
|
44
|
+
// Validate domain and service
|
|
45
|
+
if (!(0, isValidDomain_js_1.isValidDomain)(domain))
|
|
46
|
+
continue;
|
|
47
|
+
// if (!isValidTopicName(topic)) continue
|
|
48
|
+
// Verify the token locking key and signature
|
|
49
|
+
(0, verifyToken_js_1.verifyToken)(identityKey, result.lockingPublicKey, result.fields, result.signature);
|
|
50
|
+
outputsToAdmit.push(i);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error('Error processing output:', error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
console.error('Error identifying admissible outputs:', error);
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
outputsToAdmit,
|
|
62
|
+
coinsToRetain: []
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Returns documentation specific to the SHIP topic manager.
|
|
67
|
+
* @returns A promise that resolves to the documentation string.
|
|
68
|
+
*/
|
|
69
|
+
async getDocumentation() {
|
|
70
|
+
return await (0, getDocumentation_js_1.getDocumentation)('./docs/SHIP/ship-lookup-service.md');
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Returns metadata associated with this topic manager.
|
|
74
|
+
* @returns A promise that resolves to an object containing metadata.
|
|
75
|
+
*/
|
|
76
|
+
async getMetaData() {
|
|
77
|
+
return {
|
|
78
|
+
name: 'SHIP Topic Manager',
|
|
79
|
+
shortDescription: 'Manages SHIP tokens for service host interconnect.'
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.SHIPTopicManager = SHIPTopicManager;
|
|
84
|
+
//# sourceMappingURL=SHIPTopicManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SHIPTopicManager.js","sourceRoot":"","sources":["../../../../src/SHIP/SHIPTopicManager.ts"],"names":[],"mappings":";;;;;;AACA,kCAAsC;AACtC,wDAA+B;AAC/B,4DAAqD;AACrD,gEAAyD;AACzD,sEAA+D;AAE/D;;;;;;GAMG;AACH,MAAa,gBAAgB;IAC3B;;;;;OAKG;IACH,KAAK,CAAC,yBAAyB,CAAC,IAAc,EAAE,aAAuB;QACrE,MAAM,cAAc,GAAa,EAAE,CAAA;QACnC,IAAI,CAAC;YACH,MAAM,iBAAiB,GAAG,iBAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;YAEpD,KAAK,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;gBAC9D,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,kBAAQ,CAAC,MAAM,CAAC;wBAC7B,MAAM,EAAE,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE;wBACpC,WAAW,EAAE,QAAQ;qBACtB,CAAC,CAAA;oBAEF,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;wBAAE,SAAQ,CAAC,mCAAmC;oBAE5E,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;oBAClD,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;oBACpD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;oBAC1C,4CAA4C;oBAE5C,IAAI,cAAc,KAAK,MAAM;wBAAE,SAAQ;oBAEvC,8BAA8B;oBAC9B,IAAI,CAAC,IAAA,gCAAa,EAAC,MAAM,CAAC;wBAAE,SAAQ;oBACpC,yCAAyC;oBAEzC,6CAA6C;oBAC7C,IAAA,4BAAW,EAAC,WAAW,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAA;oBAElF,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBACxB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAA;gBAClD,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAA;QAC/D,CAAC;QAED,OAAO;YACL,cAAc;YACd,aAAa,EAAE,EAAE;SAClB,CAAA;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,gBAAgB;QACpB,OAAO,MAAM,IAAA,sCAAgB,EAAC,oCAAoC,CAAC,CAAA;IACrE,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,WAAW;QAOf,OAAO;YACL,IAAI,EAAE,oBAAoB;YAC1B,gBAAgB,EAAE,oDAAoD;SACvE,CAAA;IACH,CAAC;CACF;AA1ED,4CA0EC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SLAPLookupService = void 0;
|
|
7
|
+
const pushdrop_1 = __importDefault(require("pushdrop"));
|
|
8
|
+
const getDocumentation_js_1 = require("../utils/getDocumentation.js");
|
|
9
|
+
/**
|
|
10
|
+
* Implements the SLAP lookup service
|
|
11
|
+
*
|
|
12
|
+
* The SLAP lookup service allows querying for service availability within the
|
|
13
|
+
* overlay network. This service listens for SLAP-related UTXOs and stores relevant
|
|
14
|
+
* records for lookup purposes.
|
|
15
|
+
*/
|
|
16
|
+
class SLAPLookupService {
|
|
17
|
+
constructor(storage) {
|
|
18
|
+
this.storage = storage;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Handles the addition of a new output to the topic.
|
|
22
|
+
* @param txid - The transaction ID containing the output.
|
|
23
|
+
* @param outputIndex - The index of the output in the transaction.
|
|
24
|
+
* @param outputScript - The script of the output to be processed.
|
|
25
|
+
* @param topic - The topic associated with the output.
|
|
26
|
+
*/
|
|
27
|
+
async outputAdded(txid, outputIndex, outputScript, topic) {
|
|
28
|
+
if (topic !== 'tm_slap')
|
|
29
|
+
return;
|
|
30
|
+
const result = pushdrop_1.default.decode({
|
|
31
|
+
script: outputScript.toHex(),
|
|
32
|
+
fieldFormat: 'buffer'
|
|
33
|
+
});
|
|
34
|
+
const protocol = result.fields[0].toString();
|
|
35
|
+
const identityKey = result.fields[1].toString('hex');
|
|
36
|
+
const domain = result.fields[2].toString();
|
|
37
|
+
const service = result.fields[3].toString();
|
|
38
|
+
if (protocol !== 'SLAP')
|
|
39
|
+
return;
|
|
40
|
+
await this.storage.storeSLAPRecord(txid, outputIndex, identityKey, domain, service);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Handles the spending of an output in the topic.
|
|
44
|
+
* @param txid - The transaction ID of the spent output.
|
|
45
|
+
* @param outputIndex - The index of the spent output.
|
|
46
|
+
* @param topic - The topic associated with the spent output.
|
|
47
|
+
*/
|
|
48
|
+
async outputSpent(txid, outputIndex, topic) {
|
|
49
|
+
if (topic !== 'tm_slap')
|
|
50
|
+
return;
|
|
51
|
+
await this.storage.deleteSLAPRecord(txid, outputIndex);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Handles the deletion of an output in the topic.
|
|
55
|
+
* @param txid - The transaction ID of the deleted output.
|
|
56
|
+
* @param outputIndex - The index of the deleted output.
|
|
57
|
+
* @param topic - The topic associated with the deleted output.
|
|
58
|
+
*/
|
|
59
|
+
async outputDeleted(txid, outputIndex, topic) {
|
|
60
|
+
if (topic !== 'tm_slap')
|
|
61
|
+
return;
|
|
62
|
+
await this.storage.deleteSLAPRecord(txid, outputIndex);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Answers a lookup query.
|
|
66
|
+
* @param question - The lookup question to be answered.
|
|
67
|
+
* @returns A promise that resolves to a lookup answer or formula.
|
|
68
|
+
*/
|
|
69
|
+
async lookup(question) {
|
|
70
|
+
if (question.query === undefined || question.query === null) {
|
|
71
|
+
throw new Error('A valid query must be provided!');
|
|
72
|
+
}
|
|
73
|
+
if (question.service !== 'ls_slap') {
|
|
74
|
+
throw new Error('Lookup service not supported!');
|
|
75
|
+
}
|
|
76
|
+
if (question.query === 'findAll') {
|
|
77
|
+
return await this.storage.findAll();
|
|
78
|
+
}
|
|
79
|
+
const { domain, service } = question.query;
|
|
80
|
+
// Validate lookup query
|
|
81
|
+
if (domain !== undefined && domain !== null && service !== undefined && service !== null) {
|
|
82
|
+
// If both domain and service are provided, construct a query with both
|
|
83
|
+
return await this.storage.findRecord({ domain, service });
|
|
84
|
+
}
|
|
85
|
+
else if (domain !== undefined && domain !== null) {
|
|
86
|
+
return await this.storage.findRecord({ domain });
|
|
87
|
+
}
|
|
88
|
+
else if (service !== undefined && service !== null) {
|
|
89
|
+
return await this.storage.findRecord({ service });
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
throw new Error('A valid domain or service must be provided in the query!');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Returns documentation specific to this overlay lookup service.
|
|
97
|
+
* @returns A promise that resolves to the documentation string.
|
|
98
|
+
*/
|
|
99
|
+
async getDocumentation() {
|
|
100
|
+
return await (0, getDocumentation_js_1.getDocumentation)('./docs/SLAP/slap-lookup-service.md');
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Returns metadata associated with this lookup service.
|
|
104
|
+
* @returns A promise that resolves to an object containing metadata.
|
|
105
|
+
*/
|
|
106
|
+
async getMetaData() {
|
|
107
|
+
return {
|
|
108
|
+
name: 'SLAP Lookup Service',
|
|
109
|
+
shortDescription: 'Provides lookup capabilities for SLAP tokens.'
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exports.SLAPLookupService = SLAPLookupService;
|
|
114
|
+
//# sourceMappingURL=SLAPLookupService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SLAPLookupService.js","sourceRoot":"","sources":["../../../../src/SLAP/SLAPLookupService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SLAPStorage = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Implements a storage engine for SLAP protocol
|
|
6
|
+
*/
|
|
7
|
+
class SLAPStorage {
|
|
8
|
+
/**
|
|
9
|
+
* Constructs a new SLAPStorage instance
|
|
10
|
+
* @param {Db} db - connected mongo database instance
|
|
11
|
+
*/
|
|
12
|
+
constructor(db) {
|
|
13
|
+
this.db = db;
|
|
14
|
+
this.slapRecords = db.collection('slapRecords');
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Ensures the necessary indexes are created for the collections.
|
|
18
|
+
*/
|
|
19
|
+
async ensureIndexes() {
|
|
20
|
+
await this.slapRecords.createIndex({ domain: 1, service: 1 });
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Stores a SLAP record
|
|
24
|
+
* @param {string} txid transaction id
|
|
25
|
+
* @param {number} outputIndex index of the UTXO
|
|
26
|
+
* @param {string} identityKey identity key
|
|
27
|
+
* @param {string} domain domain name
|
|
28
|
+
* @param {string} service service name
|
|
29
|
+
*/
|
|
30
|
+
async storeSLAPRecord(txid, outputIndex, identityKey, domain, service) {
|
|
31
|
+
await this.slapRecords.insertOne({
|
|
32
|
+
txid,
|
|
33
|
+
outputIndex,
|
|
34
|
+
identityKey,
|
|
35
|
+
domain,
|
|
36
|
+
service,
|
|
37
|
+
createdAt: new Date()
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Deletes a SLAP record
|
|
42
|
+
* @param {string} txid transaction id
|
|
43
|
+
* @param {number} outputIndex index of the UTXO
|
|
44
|
+
*/
|
|
45
|
+
async deleteSLAPRecord(txid, outputIndex) {
|
|
46
|
+
await this.slapRecords.deleteOne({ txid, outputIndex });
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Finds SLAP records based on a given query object.
|
|
50
|
+
* @param {Object} query The query object which may contain properties for domain or service.
|
|
51
|
+
* @returns {Promise<UTXOReference[]>} returns matching UTXO references
|
|
52
|
+
*/
|
|
53
|
+
async findRecord(query) {
|
|
54
|
+
return await this.slapRecords.find(query)
|
|
55
|
+
.project({ txid: 1, outputIndex: 1 })
|
|
56
|
+
.toArray()
|
|
57
|
+
.then(results => results.map(record => ({
|
|
58
|
+
txid: record.txid,
|
|
59
|
+
outputIndex: record.outputIndex
|
|
60
|
+
})));
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Returns all results tracked by the overlay
|
|
64
|
+
* @returns {Promise<UTXOReference[]>} returns matching UTXO references
|
|
65
|
+
*/
|
|
66
|
+
async findAll() {
|
|
67
|
+
return await this.slapRecords.find({})
|
|
68
|
+
.project({ txid: 1, outputIndex: 1 })
|
|
69
|
+
.toArray()
|
|
70
|
+
.then(results => results.map(slapRecords => ({
|
|
71
|
+
txid: slapRecords.txid,
|
|
72
|
+
outputIndex: slapRecords.outputIndex
|
|
73
|
+
})));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
exports.SLAPStorage = SLAPStorage;
|
|
77
|
+
//# sourceMappingURL=SLAPStorage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SLAPStorage.js","sourceRoot":"","sources":["../../../../src/SLAP/SLAPStorage.ts"],"names":[],"mappings":";;;AAGA;;GAEG;AACH,MAAa,WAAW;IAGtB;;;OAGG;IACH,YAA6B,EAAM;QAAN,OAAE,GAAF,EAAE,CAAI;QACjC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,UAAU,CAAa,aAAa,CAAC,CAAA;IAC7D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAA;IAC/D,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,eAAe,CAAC,IAAY,EAAE,WAAmB,EAAE,WAAmB,EAAE,MAAc,EAAE,OAAe;QAC3G,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;YAC/B,IAAI;YACJ,WAAW;YACX,WAAW;YACX,MAAM;YACN,OAAO;YACP,SAAS,EAAE,IAAI,IAAI,EAAE;SACtB,CAAC,CAAA;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,gBAAgB,CAAC,IAAY,EAAE,WAAmB;QACtD,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAA;IACzD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,UAAU,CAAC,KAA4C;QAC3D,OAAO,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;aACtC,OAAO,CAAgB,EAAE,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;aACnD,OAAO,EAAE;aACT,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACtC,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,WAAW,EAAE,MAAM,CAAC,WAAW;SAChC,CAAC,CAAC,CAAC,CAAA;IACR,CAAC;IAED;;;MAGE;IACF,KAAK,CAAC,OAAO;QACX,OAAO,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;aACnC,OAAO,CAAgB,EAAE,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;aACnD,OAAO,EAAE;aACT,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YAC3C,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,WAAW,EAAE,WAAW,CAAC,WAAW;SACrC,CAAC,CAAC,CAAC,CAAA;IACR,CAAC;CACF;AA1ED,kCA0EC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SLAPTopicManager = void 0;
|
|
7
|
+
const sdk_1 = require("@bsv/sdk");
|
|
8
|
+
const pushdrop_1 = __importDefault(require("pushdrop"));
|
|
9
|
+
const verifyToken_js_1 = require("../utils/verifyToken.js");
|
|
10
|
+
const isValidServiceName_js_1 = require("../utils/isValidServiceName.js");
|
|
11
|
+
const getDocumentation_js_1 = require("../utils/getDocumentation.js");
|
|
12
|
+
/**
|
|
13
|
+
* SLAP Topic Manager
|
|
14
|
+
* Implements the TopicManager interface for SLAP (Service Lookup Availability Protocol) tokens.
|
|
15
|
+
*
|
|
16
|
+
* The SLAP Topic Manager identifies admissible outputs based on SLAP protocol requirements.
|
|
17
|
+
* SLAP tokens facilitate the advertisement of lookup services availability within the overlay network.
|
|
18
|
+
*/
|
|
19
|
+
class SLAPTopicManager {
|
|
20
|
+
/**
|
|
21
|
+
* Identifies admissible outputs for SLAP tokens.
|
|
22
|
+
* @param beef - The transaction data in BEEF format.
|
|
23
|
+
* @param previousCoins - The previous coins to consider.
|
|
24
|
+
* @returns A promise that resolves with the admittance instructions.
|
|
25
|
+
*/
|
|
26
|
+
async identifyAdmissibleOutputs(beef, previousCoins) {
|
|
27
|
+
const outputsToAdmit = [];
|
|
28
|
+
try {
|
|
29
|
+
const parsedTransaction = sdk_1.Transaction.fromBEEF(beef);
|
|
30
|
+
for (const [i, output] of parsedTransaction.outputs.entries()) {
|
|
31
|
+
try {
|
|
32
|
+
const result = pushdrop_1.default.decode({
|
|
33
|
+
script: output.lockingScript.toHex(),
|
|
34
|
+
fieldFormat: 'buffer'
|
|
35
|
+
});
|
|
36
|
+
if (result.fields.length !== 4)
|
|
37
|
+
continue; // SLAP tokens should have 4 fields
|
|
38
|
+
const slapIdentifier = result.fields[0].toString();
|
|
39
|
+
const identityKey = result.fields[1].toString('hex');
|
|
40
|
+
// const domain = result.fields[2].toString()
|
|
41
|
+
const service = result.fields[3].toString();
|
|
42
|
+
if (slapIdentifier !== 'SLAP')
|
|
43
|
+
continue;
|
|
44
|
+
// Validate domain and service
|
|
45
|
+
// if (isValidDomain(domain) !== true) continue
|
|
46
|
+
if (!(0, isValidServiceName_js_1.isValidServiceName)(service))
|
|
47
|
+
continue;
|
|
48
|
+
// Verify the token locking key and signature
|
|
49
|
+
(0, verifyToken_js_1.verifyToken)(identityKey, result.lockingPublicKey, result.fields, result.signature);
|
|
50
|
+
outputsToAdmit.push(i);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error('Error processing output:', error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
console.error('Error identifying admissible outputs:', error);
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
outputsToAdmit,
|
|
62
|
+
coinsToRetain: []
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Returns documentation specific to the SLAP topic manager.
|
|
67
|
+
* @returns A promise that resolves to the documentation string.
|
|
68
|
+
*/
|
|
69
|
+
async getDocumentation() {
|
|
70
|
+
return await (0, getDocumentation_js_1.getDocumentation)('./docs/SLAP/slap-lookup-service.md');
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Returns metadata associated with this topic manager.
|
|
74
|
+
* @returns A promise that resolves to an object containing metadata.
|
|
75
|
+
*/
|
|
76
|
+
async getMetaData() {
|
|
77
|
+
return {
|
|
78
|
+
name: 'SLAP Topic Manager',
|
|
79
|
+
shortDescription: 'Manages SLAP tokens for service lookup availability.',
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.SLAPTopicManager = SLAPTopicManager;
|
|
84
|
+
//# sourceMappingURL=SLAPTopicManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SLAPTopicManager.js","sourceRoot":"","sources":["../../../../src/SLAP/SLAPTopicManager.ts"],"names":[],"mappings":";;;;;;AACA,kCAAsC;AACtC,wDAA+B;AAC/B,4DAAqD;AACrD,0EAAmE;AACnE,sEAA+D;AAE/D;;;;;;GAMG;AACH,MAAa,gBAAgB;IAC3B;;;;;OAKG;IACH,KAAK,CAAC,yBAAyB,CAAC,IAAc,EAAE,aAAuB;QACrE,MAAM,cAAc,GAAa,EAAE,CAAA;QACnC,IAAI,CAAC;YACH,MAAM,iBAAiB,GAAG,iBAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;YAEpD,KAAK,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;gBAC9D,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,kBAAQ,CAAC,MAAM,CAAC;wBAC7B,MAAM,EAAE,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE;wBACpC,WAAW,EAAE,QAAQ;qBACtB,CAAC,CAAA;oBAEF,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;wBAAE,SAAQ,CAAC,mCAAmC;oBAE5E,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;oBAClD,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;oBACpD,6CAA6C;oBAC7C,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;oBAC3C,IAAI,cAAc,KAAK,MAAM;wBAAE,SAAQ;oBAEvC,8BAA8B;oBAC9B,+CAA+C;oBAC/C,IAAI,CAAC,IAAA,0CAAkB,EAAC,OAAO,CAAC;wBAAE,SAAQ;oBAE1C,6CAA6C;oBAC7C,IAAA,4BAAW,EAAC,WAAW,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAA;oBAElF,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBACxB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAA;gBAClD,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAA;QAC/D,CAAC;QAED,OAAO;YACL,cAAc;YACd,aAAa,EAAE,EAAE;SAClB,CAAA;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,gBAAgB;QACpB,OAAO,MAAM,IAAA,sCAAgB,EAAC,oCAAoC,CAAC,CAAA;IACrE,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,WAAW;QAOf,OAAO;YACL,IAAI,EAAE,oBAAoB;YAC1B,gBAAgB,EAAE,sDAAsD;SACzE,CAAA;IACH,CAAC;CACF;AAzED,4CAyEC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":""}
|