@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.
Files changed (118) hide show
  1. package/LICENSE.txt +28 -0
  2. package/README.md +13 -0
  3. package/dist/cjs/mod.js +28 -0
  4. package/dist/cjs/mod.js.map +1 -0
  5. package/dist/cjs/package.json +59 -0
  6. package/dist/cjs/src/LegacyNinjaAdvertiser.js +235 -0
  7. package/dist/cjs/src/LegacyNinjaAdvertiser.js.map +1 -0
  8. package/dist/cjs/src/NinjaAdvertiser.js +234 -0
  9. package/dist/cjs/src/NinjaAdvertiser.js.map +1 -0
  10. package/dist/cjs/src/SHIP/SHIPLookupService.js +116 -0
  11. package/dist/cjs/src/SHIP/SHIPLookupService.js.map +1 -0
  12. package/dist/cjs/src/SHIP/SHIPStorage.js +87 -0
  13. package/dist/cjs/src/SHIP/SHIPStorage.js.map +1 -0
  14. package/dist/cjs/src/SHIP/SHIPTopicManager.js +84 -0
  15. package/dist/cjs/src/SHIP/SHIPTopicManager.js.map +1 -0
  16. package/dist/cjs/src/SLAP/SLAPLookupService.js +114 -0
  17. package/dist/cjs/src/SLAP/SLAPLookupService.js.map +1 -0
  18. package/dist/cjs/src/SLAP/SLAPStorage.js +77 -0
  19. package/dist/cjs/src/SLAP/SLAPStorage.js.map +1 -0
  20. package/dist/cjs/src/SLAP/SLAPTopicManager.js +84 -0
  21. package/dist/cjs/src/SLAP/SLAPTopicManager.js.map +1 -0
  22. package/dist/cjs/src/types.js +3 -0
  23. package/dist/cjs/src/types.js.map +1 -0
  24. package/dist/cjs/src/utils/generateDocs.js +81 -0
  25. package/dist/cjs/src/utils/generateDocs.js.map +1 -0
  26. package/dist/cjs/src/utils/getDocumentation.js +22 -0
  27. package/dist/cjs/src/utils/getDocumentation.js.map +1 -0
  28. package/dist/cjs/src/utils/isValidDomain.js +15 -0
  29. package/dist/cjs/src/utils/isValidDomain.js.map +1 -0
  30. package/dist/cjs/src/utils/isValidServiceName.js +14 -0
  31. package/dist/cjs/src/utils/isValidServiceName.js.map +1 -0
  32. package/dist/cjs/src/utils/verifyToken.js +22 -0
  33. package/dist/cjs/src/utils/verifyToken.js.map +1 -0
  34. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
  35. package/dist/esm/mod.js +12 -0
  36. package/dist/esm/mod.js.map +1 -0
  37. package/dist/esm/src/LegacyNinjaAdvertiser.js +233 -0
  38. package/dist/esm/src/LegacyNinjaAdvertiser.js.map +1 -0
  39. package/dist/esm/src/NinjaAdvertiser.js +232 -0
  40. package/dist/esm/src/NinjaAdvertiser.js.map +1 -0
  41. package/dist/esm/src/SHIP/SHIPLookupService.js +110 -0
  42. package/dist/esm/src/SHIP/SHIPLookupService.js.map +1 -0
  43. package/dist/esm/src/SHIP/SHIPStorage.js +85 -0
  44. package/dist/esm/src/SHIP/SHIPStorage.js.map +1 -0
  45. package/dist/esm/src/SHIP/SHIPTopicManager.js +77 -0
  46. package/dist/esm/src/SHIP/SHIPTopicManager.js.map +1 -0
  47. package/dist/esm/src/SLAP/SLAPLookupService.js +108 -0
  48. package/dist/esm/src/SLAP/SLAPLookupService.js.map +1 -0
  49. package/dist/esm/src/SLAP/SLAPStorage.js +75 -0
  50. package/dist/esm/src/SLAP/SLAPStorage.js.map +1 -0
  51. package/dist/esm/src/SLAP/SLAPTopicManager.js +77 -0
  52. package/dist/esm/src/SLAP/SLAPTopicManager.js.map +1 -0
  53. package/dist/esm/src/types.js +2 -0
  54. package/dist/esm/src/types.js.map +1 -0
  55. package/dist/esm/src/utils/generateDocs.js +46 -0
  56. package/dist/esm/src/utils/generateDocs.js.map +1 -0
  57. package/dist/esm/src/utils/getDocumentation.js +20 -0
  58. package/dist/esm/src/utils/getDocumentation.js.map +1 -0
  59. package/dist/esm/src/utils/isValidDomain.js +11 -0
  60. package/dist/esm/src/utils/isValidDomain.js.map +1 -0
  61. package/dist/esm/src/utils/isValidServiceName.js +10 -0
  62. package/dist/esm/src/utils/isValidServiceName.js.map +1 -0
  63. package/dist/esm/src/utils/verifyToken.js +18 -0
  64. package/dist/esm/src/utils/verifyToken.js.map +1 -0
  65. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
  66. package/dist/types/mod.d.ts +12 -0
  67. package/dist/types/mod.d.ts.map +1 -0
  68. package/dist/types/src/LegacyNinjaAdvertiser.d.ts +60 -0
  69. package/dist/types/src/LegacyNinjaAdvertiser.d.ts.map +1 -0
  70. package/dist/types/src/NinjaAdvertiser.d.ts +60 -0
  71. package/dist/types/src/NinjaAdvertiser.d.ts.map +1 -0
  72. package/dist/types/src/SHIP/SHIPLookupService.d.ts +58 -0
  73. package/dist/types/src/SHIP/SHIPLookupService.d.ts.map +1 -0
  74. package/dist/types/src/SHIP/SHIPStorage.d.ts +48 -0
  75. package/dist/types/src/SHIP/SHIPStorage.d.ts.map +1 -0
  76. package/dist/types/src/SHIP/SHIPTopicManager.d.ts +34 -0
  77. package/dist/types/src/SHIP/SHIPTopicManager.d.ts.map +1 -0
  78. package/dist/types/src/SLAP/SLAPLookupService.d.ts +59 -0
  79. package/dist/types/src/SLAP/SLAPLookupService.d.ts.map +1 -0
  80. package/dist/types/src/SLAP/SLAPStorage.d.ts +48 -0
  81. package/dist/types/src/SLAP/SLAPStorage.d.ts.map +1 -0
  82. package/dist/types/src/SLAP/SLAPTopicManager.d.ts +34 -0
  83. package/dist/types/src/SLAP/SLAPTopicManager.d.ts.map +1 -0
  84. package/dist/types/src/types.d.ts +29 -0
  85. package/dist/types/src/types.d.ts.map +1 -0
  86. package/dist/types/src/utils/generateDocs.d.ts +2 -0
  87. package/dist/types/src/utils/generateDocs.d.ts.map +1 -0
  88. package/dist/types/src/utils/getDocumentation.d.ts +8 -0
  89. package/dist/types/src/utils/getDocumentation.d.ts.map +1 -0
  90. package/dist/types/src/utils/isValidDomain.d.ts +7 -0
  91. package/dist/types/src/utils/isValidDomain.d.ts.map +1 -0
  92. package/dist/types/src/utils/isValidServiceName.d.ts +7 -0
  93. package/dist/types/src/utils/isValidServiceName.d.ts.map +1 -0
  94. package/dist/types/src/utils/verifyToken.d.ts +12 -0
  95. package/dist/types/src/utils/verifyToken.d.ts.map +1 -0
  96. package/dist/types/tsconfig.types.tsbuildinfo +1 -0
  97. package/docs/SHIP/ship-lookup-service.md +352 -0
  98. package/docs/SHIP/ship-storage.md +207 -0
  99. package/docs/SHIP/ship-topic-manager.md +122 -0
  100. package/docs/SLAP/slap-lookup-service.md +353 -0
  101. package/docs/SLAP/slap-storage.md +207 -0
  102. package/docs/SLAP/slap-topic-manager.md +122 -0
  103. package/mod.ts +15 -0
  104. package/package.json +74 -0
  105. package/src/LegacyNinjaAdvertiser.ts +260 -0
  106. package/src/SHIP/SHIPLookupService.ts +122 -0
  107. package/src/SHIP/SHIPStorage.ts +96 -0
  108. package/src/SHIP/SHIPTopicManager.ts +89 -0
  109. package/src/SLAP/SLAPLookupService.ts +121 -0
  110. package/src/SLAP/SLAPStorage.ts +81 -0
  111. package/src/SLAP/SLAPTopicManager.ts +88 -0
  112. package/src/types.d.ts +2 -0
  113. package/src/types.ts +32 -0
  114. package/src/utils/generateDocs.ts +53 -0
  115. package/src/utils/getDocumentation.ts +19 -0
  116. package/src/utils/isValidDomain.ts +10 -0
  117. package/src/utils/isValidServiceName.ts +9 -0
  118. 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,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":""}