@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
package/LICENSE.txt ADDED
@@ -0,0 +1,28 @@
1
+ Open BSV License version 4
2
+
3
+ Copyright (c) 2023 BSV Blockchain Association ("Bitcoin Association")
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ 1 - The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ 2 - The Software, and any software that is derived from the Software or parts thereof,
16
+ can only be used on the Bitcoin SV blockchains. The Bitcoin SV blockchains are defined,
17
+ for purposes of this license, as the Bitcoin blockchain containing block height #556767
18
+ with the hash "000000000000000001d956714215d96ffc00e0afda4cd0a96c96f8d802b1662b" and
19
+ that contains the longest persistent chain of blocks accepted by this Software and which are valid under the rules set forth in the Bitcoin white paper (S. Nakamoto, Bitcoin: A Peer-to-Peer Electronic Cash System, posted online October 2008) and the latest version of this Software available in this repository or another repository designated by Bitcoin Association,
20
+ as well as the test blockchains that contain the longest persistent chains of blocks accepted by this Software and which are valid under the rules set forth in the Bitcoin whitepaper (S. Nakamoto, Bitcoin: A Peer-to-Peer Electronic Cash System, posted online October 2008) and the latest version of this Software available in this repository, or another repository designated by Bitcoin Association
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,13 @@
1
+ # Overlay Discovery Services
2
+
3
+ BSV BLOCKCHAIN | Overlay Discovery Services
4
+
5
+ This package contains the Service Host Interconnect and Service Lookup Availability systems.
6
+
7
+ It also contains SHIP/SLAP token advertiser implementations.
8
+
9
+ For questions, bug reports, or feature requests, please open an issue on GitHub.
10
+
11
+ ## License
12
+
13
+ The license for the code in this repository is the Open BSV License. Refer to [LICENSE.txt](./LICENSE.txt) for the license text.
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./src/SHIP/SHIPLookupService.js"), exports);
18
+ __exportStar(require("./src/SHIP/SHIPStorage.js"), exports);
19
+ __exportStar(require("./src/SHIP/SHIPTopicManager.js"), exports);
20
+ __exportStar(require("./src/SLAP/SLAPLookupService.js"), exports);
21
+ __exportStar(require("./src/SLAP/SLAPStorage.js"), exports);
22
+ __exportStar(require("./src/SLAP/SLAPTopicManager.js"), exports);
23
+ __exportStar(require("./src/LegacyNinjaAdvertiser.js"), exports);
24
+ __exportStar(require("./src/utils/isValidDomain.js"), exports);
25
+ __exportStar(require("./src/utils/isValidServiceName.js"), exports);
26
+ __exportStar(require("./src/utils/verifyToken.js"), exports);
27
+ __exportStar(require("./src/types.js"), exports);
28
+ //# sourceMappingURL=mod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.js","sourceRoot":"","sources":["../../mod.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kEAA+C;AAC/C,4DAAyC;AACzC,iEAA8C;AAE9C,kEAA+C;AAC/C,4DAAyC;AACzC,iEAA8C;AAE9C,iEAA8C;AAE9C,+DAA4C;AAC5C,oEAAiD;AACjD,6DAA0C;AAE1C,iDAA8B"}
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@bsv/overlay-discovery-services",
3
+ "version": "0.1.0",
4
+ "type": "commonjs",
5
+ "description": "BSV Blockchain Overlay Services Engine",
6
+ "files": [
7
+ "dist",
8
+ "src",
9
+ "docs",
10
+ "mod.ts",
11
+ "LICENSE.txt"
12
+ ],
13
+ "scripts": {
14
+ "test": "npm run build && jest",
15
+ "test:watch": "npm run build && jest --watch",
16
+ "test:coverage": "npm run build && jest --coverage",
17
+ "lint": "ts-standard --fix src/**/*.ts",
18
+ "build": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
19
+ "dev": "tsc -b -w",
20
+ "prepublish": "npm run build",
21
+ "doc": "ts2md --inputFilename=mod.ts --outputFilename=API.md --filenameSubstring=API --firstHeadingLevel=1",
22
+ "generate-service-docs": "node ./dist/cjs/src/utils/generateDocs.js"
23
+ },
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/bitcoin-sv/overlay-discovery-services.git"
27
+ },
28
+ "keywords": [
29
+ "BSV",
30
+ "Blockchain",
31
+ "Overlay",
32
+ "Bitcoin",
33
+ "SV"
34
+ ],
35
+ "author": "BSV Association",
36
+ "license": "SEE LICENSE IN LICENSE.txt",
37
+ "bugs": {
38
+ "url": "https://github.com/bitcoin-sv/overlay-discovery-services/issues"
39
+ },
40
+ "homepage": "https://github.com/bitcoin-sv/overlay-discovery-services#readme",
41
+ "devDependencies": {
42
+ "@types/jest": "^29.5.12",
43
+ "jest": "^29.7.0",
44
+ "ts-jest": "^29.1.1",
45
+ "ts-standard": "^12.0.2",
46
+ "ts2md": "^0.2.0",
47
+ "tsconfig-to-dual-package": "^1.2.0",
48
+ "typescript": "^5.2.2"
49
+ },
50
+ "dependencies": {
51
+ "@bsv/overlay": "^0.1.15",
52
+ "@bsv/sdk": "^1.2.3",
53
+ "mongodb": "^6.11.0",
54
+ "ninja-base": "^0.3.67",
55
+ "pushdrop": "^0.1.64",
56
+ "sendover": "^1.3.27",
57
+ "uhrp-url": "^0.1.10"
58
+ }
59
+ }
@@ -0,0 +1,235 @@
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.LegacyNinjaAdvertiser = void 0;
7
+ const pushdrop_1 = __importDefault(require("pushdrop"));
8
+ const ninja_base_1 = require("ninja-base");
9
+ const sdk_ts_1 = require("@babbage/sdk-ts");
10
+ const sdk_1 = require("@bsv/sdk");
11
+ const sendover_1 = require("sendover");
12
+ const toBEEF_js_1 = require("@babbage/sdk-ts/out/src/utils/toBEEF.js");
13
+ const AD_TOKEN_VALUE = 1;
14
+ // TODO: Add 'implements Advertiser' back, once Advertiser can be properly imported from Overlay Services.
15
+ /**
16
+ * Implements the Advertiser interface for managing SHIP and SLAP advertisements using a Ninja.
17
+ */
18
+ class LegacyNinjaAdvertiser {
19
+ /**
20
+ * Constructs a new NinjaAdvertiser instance.
21
+ * @param privateKey - The private key used for signing transactions.
22
+ * @param dojoURL - The URL of the dojo server for the Ninja.
23
+ * @param hostingDomain - The base server URL for the NinjaAdvertiser.
24
+ */
25
+ constructor(privateKey, dojoURL, hostingDomain) {
26
+ this.privateKey = privateKey;
27
+ this.dojoURL = dojoURL;
28
+ this.hostingDomain = hostingDomain;
29
+ this.ninja = new ninja_base_1.Ninja({
30
+ privateKey,
31
+ config: {
32
+ dojoURL
33
+ }
34
+ });
35
+ }
36
+ /**
37
+ * Sets the Engine instance to be used by this NinjaAdvertiser. This method allows for late
38
+ * binding of the Engine, thus avoiding circular dependencies during instantiation. The Engine
39
+ * provides necessary context with the relevant topic managers and lookup services,
40
+ * as well as the lookup function used for querying advertisements.
41
+ *
42
+ * @param engine The Engine instance to be associated with this NinjaAdvertiser. The Engine should
43
+ * be fully initialized before being passed to this method to ensure all functionalities are available.
44
+ */
45
+ setLookupEngine(engine) {
46
+ this.engine = engine;
47
+ }
48
+ /**
49
+ * Utility function to create multiple advertisements in a single transaction.
50
+ * @param privateKey The private key used to sign the transaction.
51
+ * @param adsData Array of advertisement details.
52
+ * @param ninja Ninja instance for transaction processing.
53
+ * @param note A note attached to the transaction.
54
+ * @returns A promise that resolves to an array of TaggedBEEF objects.
55
+ * @throws Will throw an error if the locking key is invalid.
56
+ */
57
+ async createAdvertisements(adsData) {
58
+ const identityKey = sdk_1.PublicKey.fromPrivateKey(new sdk_1.PrivateKey(this.privateKey, 'hex')).toString();
59
+ const outputs = await Promise.all(adsData.map(async (ad) => {
60
+ // Derive a locking private key using BRC-42 derivation scheme
61
+ const derivedPrivateKey = (0, sendover_1.getPaymentPrivateKey)({
62
+ recipientPrivateKey: this.privateKey,
63
+ senderPublicKey: identityKey,
64
+ invoiceNumber: `2-${ad.protocol}-1`,
65
+ returnType: 'hex'
66
+ });
67
+ const lockingScript = await pushdrop_1.default.create({
68
+ fields: [
69
+ Buffer.from(ad.protocol),
70
+ Buffer.from(identityKey, 'hex'),
71
+ Buffer.from(this.hostingDomain),
72
+ Buffer.from(ad.topicOrServiceName)
73
+ ],
74
+ key: derivedPrivateKey
75
+ });
76
+ return {
77
+ satoshis: AD_TOKEN_VALUE,
78
+ script: lockingScript
79
+ };
80
+ }));
81
+ const tx = await this.ninja.getTransactionWithOutputs({
82
+ outputs,
83
+ note: 'SHIP/SLAP Advertisement Issuance',
84
+ autoProcess: true
85
+ });
86
+ const beef = (0, sdk_ts_1.toBEEFfromEnvelope)({
87
+ rawTx: tx.rawTx,
88
+ inputs: tx.inputs,
89
+ txid: tx.txid
90
+ }).beef;
91
+ return {
92
+ beef,
93
+ topics: [...new Set(adsData.map(ad => ad.protocol === 'SHIP' ? 'tm_ship' : 'tm_slap'))]
94
+ };
95
+ }
96
+ /**
97
+ * Finds all SHIP advertisements for a given topic.
98
+ * @param topic - The topic name to search for.
99
+ * @returns A promise that resolves to an array of SHIP advertisements.
100
+ */
101
+ async findAllAdvertisements(protocol) {
102
+ if (this.engine === undefined) {
103
+ throw new Error('Advertiser must be configured with an overlay services engine for advertisement lookup.');
104
+ }
105
+ const advertisements = [];
106
+ const lookupAnswer = await this.engine.lookup({
107
+ service: protocol === 'SHIP' ? 'ls_ship' : 'ls_slap',
108
+ query: 'findAll'
109
+ });
110
+ // Lookup will currently always return type output-list
111
+ if (lookupAnswer.type === 'output-list') {
112
+ lookupAnswer.outputs.forEach(output => {
113
+ try {
114
+ // Parse out the advertisements using the provided parser
115
+ const tx = sdk_1.Transaction.fromBEEF(output.beef);
116
+ const advertisement = this.parseAdvertisement(tx.outputs[output.outputIndex].lockingScript);
117
+ if (advertisement !== undefined && advertisement !== null && advertisement.protocol === protocol) {
118
+ advertisements.push({
119
+ ...advertisement,
120
+ beef: output.beef,
121
+ outputIndex: output.outputIndex
122
+ });
123
+ }
124
+ }
125
+ catch (error) {
126
+ console.error('Failed to parse advertisement output:', error);
127
+ }
128
+ });
129
+ }
130
+ return advertisements;
131
+ }
132
+ /**
133
+ * Revokes an existing advertisement.
134
+ * @param advertisements - The advertisements to revoke, either SHIP or SLAP.
135
+ * @returns A promise that resolves to the revoked advertisement as TaggedBEEF.
136
+ */
137
+ async revokeAdvertisements(advertisements) {
138
+ if (advertisements.length === 0) {
139
+ throw new Error('Must provide advertisements to revoke!');
140
+ }
141
+ const inputsByTxid = {};
142
+ for (const advertisement of advertisements) {
143
+ if (advertisement.beef === undefined || advertisement.outputIndex === undefined) {
144
+ throw new Error('Advertisement to revoke must contain tagged beef!');
145
+ }
146
+ // Parse the transaction and UTXO to spend
147
+ const advertisementTx = sdk_1.Transaction.fromBEEF(advertisement.beef);
148
+ const adTxid = advertisementTx.id('hex');
149
+ const outputToRedeem = advertisementTx.outputs[advertisement.outputIndex];
150
+ const identityKey = sdk_1.PublicKey.fromPrivateKey(new sdk_1.PrivateKey(this.privateKey, 'hex')).toString();
151
+ // Derive a unlocking private key using BRC-42 derivation scheme
152
+ const derivedPrivateKey = (0, sendover_1.getPaymentPrivateKey)({
153
+ recipientPrivateKey: this.privateKey,
154
+ senderPublicKey: identityKey,
155
+ invoiceNumber: `2-${advertisement.protocol}-1`,
156
+ returnType: 'hex'
157
+ });
158
+ const unlockingScript = await pushdrop_1.default.redeem({
159
+ key: derivedPrivateKey,
160
+ prevTxId: adTxid,
161
+ outputIndex: advertisement.outputIndex,
162
+ lockingScript: outputToRedeem.lockingScript.toHex(),
163
+ outputAmount: outputToRedeem.satoshis
164
+ });
165
+ const constructedRedeem = {
166
+ index: advertisement.outputIndex,
167
+ unlockingScript
168
+ };
169
+ // Group outputs by their transaction ID
170
+ if (inputsByTxid[adTxid] === undefined) {
171
+ inputsByTxid[adTxid] = {
172
+ ...(0, toBEEF_js_1.toEnvelopeFromBEEF)(advertisementTx),
173
+ rawTx: advertisementTx.toHex(),
174
+ outputsToRedeem: [constructedRedeem]
175
+ };
176
+ }
177
+ else {
178
+ inputsByTxid[adTxid].outputsToRedeem.push(constructedRedeem);
179
+ }
180
+ }
181
+ // Create a new transaction that spends the SHIP or SLAP advertisement issuance token
182
+ const revokeTx = await this.ninja.getTransactionWithOutputs({
183
+ inputs: inputsByTxid,
184
+ outputs: [],
185
+ labels: [],
186
+ note: 'Revoked SHIP/SLAP advertisements',
187
+ autoProcess: true
188
+ });
189
+ const beef = (0, sdk_ts_1.toBEEFfromEnvelope)({
190
+ rawTx: revokeTx.rawTx,
191
+ inputs: revokeTx.inputs,
192
+ txid: revokeTx.txid
193
+ }).beef;
194
+ return {
195
+ beef,
196
+ topics: [...new Set(advertisements.map(ad => ad.protocol === 'SHIP' ? 'tm_ship' : 'tm_slap'))]
197
+ };
198
+ }
199
+ /**
200
+ * Parses an advertisement from the provided output script.
201
+ * @param outputScript - The output script to parse.
202
+ * @returns An Advertisement object if the script matches the expected format, otherwise throws an error.
203
+ */
204
+ parseAdvertisement(outputScript) {
205
+ try {
206
+ const result = pushdrop_1.default.decode({
207
+ script: outputScript.toHex(),
208
+ fieldFormat: 'buffer'
209
+ });
210
+ if (result.fields.length < 4) {
211
+ throw new Error('Invalid SHIP/SLAP advertisement!');
212
+ }
213
+ const protocol = result.fields[0].toString();
214
+ if (protocol !== 'SHIP' && protocol !== 'SLAP') {
215
+ throw new Error('Invalid protocol type!');
216
+ }
217
+ const identityKey = result.fields[1].toString('hex');
218
+ const domain = result.fields[2].toString();
219
+ const topicOrService = result.fields[3].toString();
220
+ // Construct a unified Advertisement object
221
+ return {
222
+ protocol: protocol,
223
+ identityKey,
224
+ domain,
225
+ topicOrService
226
+ };
227
+ }
228
+ catch (error) {
229
+ console.error('Error parsing advertisement:', error);
230
+ throw new Error('Error parsing advertisement!');
231
+ }
232
+ }
233
+ }
234
+ exports.LegacyNinjaAdvertiser = LegacyNinjaAdvertiser;
235
+ //# sourceMappingURL=LegacyNinjaAdvertiser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LegacyNinjaAdvertiser.js","sourceRoot":"","sources":["../../../src/LegacyNinjaAdvertiser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,234 @@
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.NinjaAdvertiser = void 0;
7
+ const pushdrop_1 = __importDefault(require("pushdrop"));
8
+ const ninja_base_1 = require("ninja-base");
9
+ const sdk_ts_1 = require("@babbage/sdk-ts");
10
+ const sdk_1 = require("@bsv/sdk");
11
+ const sendover_1 = require("sendover");
12
+ const toBEEF_js_1 = require("@babbage/sdk-ts/out/src/utils/toBEEF.js");
13
+ const AD_TOKEN_VALUE = 1;
14
+ /**
15
+ * Implements the Advertiser interface for managing SHIP and SLAP advertisements using a Ninja.
16
+ */
17
+ class NinjaAdvertiser {
18
+ /**
19
+ * Constructs a new NinjaAdvertiser instance.
20
+ * @param privateKey - The private key used for signing transactions.
21
+ * @param dojoURL - The URL of the dojo server for the Ninja.
22
+ * @param hostingDomain - The base server URL for the NinjaAdvertiser.
23
+ */
24
+ constructor(privateKey, dojoURL, hostingDomain) {
25
+ this.privateKey = privateKey;
26
+ this.dojoURL = dojoURL;
27
+ this.hostingDomain = hostingDomain;
28
+ this.ninja = new ninja_base_1.Ninja({
29
+ privateKey,
30
+ config: {
31
+ dojoURL
32
+ }
33
+ });
34
+ }
35
+ /**
36
+ * Sets the Engine instance to be used by this NinjaAdvertiser. This method allows for late
37
+ * binding of the Engine, thus avoiding circular dependencies during instantiation. The Engine
38
+ * provides necessary context with the relevant topic managers and lookup services,
39
+ * as well as the lookup function used for querying advertisements.
40
+ *
41
+ * @param engine The Engine instance to be associated with this NinjaAdvertiser. The Engine should
42
+ * be fully initialized before being passed to this method to ensure all functionalities are available.
43
+ */
44
+ setLookupEngine(engine) {
45
+ this.engine = engine;
46
+ }
47
+ /**
48
+ * Utility function to create multiple advertisements in a single transaction.
49
+ * @param privateKey The private key used to sign the transaction.
50
+ * @param adsData Array of advertisement details.
51
+ * @param ninja Ninja instance for transaction processing.
52
+ * @param note A note attached to the transaction.
53
+ * @returns A promise that resolves to an array of TaggedBEEF objects.
54
+ * @throws Will throw an error if the locking key is invalid.
55
+ */
56
+ async createAdvertisements(adsData) {
57
+ const identityKey = sdk_1.PublicKey.fromPrivateKey(new sdk_1.PrivateKey(this.privateKey, 'hex')).toString();
58
+ const outputs = await Promise.all(adsData.map(async (ad) => {
59
+ // Derive a locking private key using BRC-42 derivation scheme
60
+ const derivedPrivateKey = (0, sendover_1.getPaymentPrivateKey)({
61
+ recipientPrivateKey: this.privateKey,
62
+ senderPublicKey: identityKey,
63
+ invoiceNumber: `2-${ad.protocol}-1`,
64
+ returnType: 'hex'
65
+ });
66
+ const lockingScript = await pushdrop_1.default.create({
67
+ fields: [
68
+ Buffer.from(ad.protocol),
69
+ Buffer.from(identityKey, 'hex'),
70
+ Buffer.from(this.hostingDomain),
71
+ Buffer.from(ad.topicOrServiceName)
72
+ ],
73
+ key: derivedPrivateKey
74
+ });
75
+ return {
76
+ satoshis: AD_TOKEN_VALUE,
77
+ script: lockingScript
78
+ };
79
+ }));
80
+ const tx = await this.ninja.getTransactionWithOutputs({
81
+ outputs,
82
+ note: 'SHIP/SLAP Advertisement Issuance',
83
+ autoProcess: true
84
+ });
85
+ const beef = (0, sdk_ts_1.toBEEFfromEnvelope)({
86
+ rawTx: tx.rawTx,
87
+ inputs: tx.inputs,
88
+ txid: tx.txid
89
+ }).beef;
90
+ return {
91
+ beef,
92
+ topics: [...new Set(adsData.map(ad => ad.protocol === 'SHIP' ? 'tm_ship' : 'tm_slap'))]
93
+ };
94
+ }
95
+ /**
96
+ * Finds all SHIP advertisements for a given topic.
97
+ * @param topic - The topic name to search for.
98
+ * @returns A promise that resolves to an array of SHIP advertisements.
99
+ */
100
+ async findAllAdvertisements(protocol) {
101
+ if (this.engine === undefined) {
102
+ throw new Error('Advertiser must be configured with an overlay services engine for advertisement lookup.');
103
+ }
104
+ const advertisements = [];
105
+ const lookupAnswer = await this.engine.lookup({
106
+ service: protocol === 'SHIP' ? 'ls_ship' : 'ls_slap',
107
+ query: 'findAll'
108
+ });
109
+ // Lookup will currently always return type output-list
110
+ if (lookupAnswer.type === 'output-list') {
111
+ lookupAnswer.outputs.forEach(output => {
112
+ try {
113
+ // Parse out the advertisements using the provided parser
114
+ const tx = sdk_1.Transaction.fromBEEF(output.beef);
115
+ const advertisement = this.parseAdvertisement(tx.outputs[output.outputIndex].lockingScript);
116
+ if (advertisement !== undefined && advertisement !== null && advertisement.protocol === protocol) {
117
+ advertisements.push({
118
+ ...advertisement,
119
+ beef: output.beef,
120
+ outputIndex: output.outputIndex
121
+ });
122
+ }
123
+ }
124
+ catch (error) {
125
+ console.error('Failed to parse advertisement output:', error);
126
+ }
127
+ });
128
+ }
129
+ return advertisements;
130
+ }
131
+ /**
132
+ * Revokes an existing advertisement.
133
+ * @param advertisements - The advertisements to revoke, either SHIP or SLAP.
134
+ * @returns A promise that resolves to the revoked advertisement as TaggedBEEF.
135
+ */
136
+ async revokeAdvertisements(advertisements) {
137
+ if (advertisements.length === 0) {
138
+ throw new Error('Must provide advertisements to revoke!');
139
+ }
140
+ const inputsByTxid = {};
141
+ for (const advertisement of advertisements) {
142
+ if (advertisement.beef === undefined || advertisement.outputIndex === undefined) {
143
+ throw new Error('Advertisement to revoke must contain tagged beef!');
144
+ }
145
+ // Parse the transaction and UTXO to spend
146
+ const advertisementTx = sdk_1.Transaction.fromBEEF(advertisement.beef);
147
+ const adTxid = advertisementTx.id('hex');
148
+ const outputToRedeem = advertisementTx.outputs[advertisement.outputIndex];
149
+ const identityKey = sdk_1.PublicKey.fromPrivateKey(new sdk_1.PrivateKey(this.privateKey, 'hex')).toString();
150
+ // Derive a unlocking private key using BRC-42 derivation scheme
151
+ const derivedPrivateKey = (0, sendover_1.getPaymentPrivateKey)({
152
+ recipientPrivateKey: this.privateKey,
153
+ senderPublicKey: identityKey,
154
+ invoiceNumber: `2-${advertisement.protocol}-1`,
155
+ returnType: 'hex'
156
+ });
157
+ const unlockingScript = await pushdrop_1.default.redeem({
158
+ key: derivedPrivateKey,
159
+ prevTxId: adTxid,
160
+ outputIndex: advertisement.outputIndex,
161
+ lockingScript: outputToRedeem.lockingScript.toHex(),
162
+ outputAmount: outputToRedeem.satoshis
163
+ });
164
+ const constructedRedeem = {
165
+ index: advertisement.outputIndex,
166
+ unlockingScript
167
+ };
168
+ // Group outputs by their transaction ID
169
+ if (inputsByTxid[adTxid] === undefined) {
170
+ inputsByTxid[adTxid] = {
171
+ ...(0, toBEEF_js_1.toEnvelopeFromBEEF)(advertisementTx),
172
+ rawTx: advertisementTx.toHex(),
173
+ outputsToRedeem: [constructedRedeem]
174
+ };
175
+ }
176
+ else {
177
+ inputsByTxid[adTxid].outputsToRedeem.push(constructedRedeem);
178
+ }
179
+ }
180
+ // Create a new transaction that spends the SHIP or SLAP advertisement issuance token
181
+ const revokeTx = await this.ninja.getTransactionWithOutputs({
182
+ inputs: inputsByTxid,
183
+ outputs: [],
184
+ labels: [],
185
+ note: 'Revoked SHIP/SLAP advertisements',
186
+ autoProcess: true
187
+ });
188
+ const beef = (0, sdk_ts_1.toBEEFfromEnvelope)({
189
+ rawTx: revokeTx.rawTx,
190
+ inputs: revokeTx.inputs,
191
+ txid: revokeTx.txid
192
+ }).beef;
193
+ return {
194
+ beef,
195
+ topics: [...new Set(advertisements.map(ad => ad.protocol === 'SHIP' ? 'tm_ship' : 'tm_slap'))]
196
+ };
197
+ }
198
+ /**
199
+ * Parses an advertisement from the provided output script.
200
+ * @param outputScript - The output script to parse.
201
+ * @returns An Advertisement object if the script matches the expected format, otherwise throws an error.
202
+ */
203
+ parseAdvertisement(outputScript) {
204
+ try {
205
+ const result = pushdrop_1.default.decode({
206
+ script: outputScript.toHex(),
207
+ fieldFormat: 'buffer'
208
+ });
209
+ if (result.fields.length < 4) {
210
+ throw new Error('Invalid SHIP/SLAP advertisement!');
211
+ }
212
+ const protocol = result.fields[0].toString();
213
+ if (protocol !== 'SHIP' && protocol !== 'SLAP') {
214
+ throw new Error('Invalid protocol type!');
215
+ }
216
+ const identityKey = result.fields[1].toString('hex');
217
+ const domain = result.fields[2].toString();
218
+ const topicOrService = result.fields[3].toString();
219
+ // Construct a unified Advertisement object
220
+ return {
221
+ protocol: protocol,
222
+ identityKey,
223
+ domain,
224
+ topicOrService
225
+ };
226
+ }
227
+ catch (error) {
228
+ console.error('Error parsing advertisement:', error);
229
+ throw new Error('Error parsing advertisement!');
230
+ }
231
+ }
232
+ }
233
+ exports.NinjaAdvertiser = NinjaAdvertiser;
234
+ //# sourceMappingURL=NinjaAdvertiser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NinjaAdvertiser.js","sourceRoot":"","sources":["../../../src/NinjaAdvertiser.ts"],"names":[],"mappings":";;;;;;AACA,wDAA+B;AAC/B,2CAAoD;AACpD,4CAAyE;AACzE,kCAAqE;AAErE,uCAA+C;AAE/C,uEAA4E;AAE5E,MAAM,cAAc,GAAG,CAAC,CAAA;AAExB;;GAEG;AACH,MAAa,eAAe;IAI1B;;;;;OAKG;IACH,YACS,UAAkB,EAClB,OAAe,EACf,aAAqB;QAFrB,eAAU,GAAV,UAAU,CAAQ;QAClB,YAAO,GAAP,OAAO,CAAQ;QACf,kBAAa,GAAb,aAAa,CAAQ;QAE5B,IAAI,CAAC,KAAK,GAAG,IAAI,kBAAK,CAAC;YACrB,UAAU;YACV,MAAM,EAAE;gBACN,OAAO;aACR;SACF,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;;OAQG;IACH,eAAe,CAAC,MAAc;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,oBAAoB,CACxB,OAA4B;QAE5B,MAAM,WAAW,GAAG,eAAS,CAAC,cAAc,CAAC,IAAI,gBAAU,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;QAE/F,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;YACzD,8DAA8D;YAC9D,MAAM,iBAAiB,GAAG,IAAA,+BAAoB,EAAC;gBAC7C,mBAAmB,EAAE,IAAI,CAAC,UAAU;gBACpC,eAAe,EAAE,WAAW;gBAC5B,aAAa,EAAE,KAAK,EAAE,CAAC,QAAQ,IAAI;gBACnC,UAAU,EAAE,KAAK;aAClB,CAAC,CAAA;YAEF,MAAM,aAAa,GAAG,MAAM,kBAAQ,CAAC,MAAM,CAAC;gBAC1C,MAAM,EAAE;oBACN,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC;oBACxB,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC;oBAC/B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;oBAC/B,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC;iBACnC;gBACD,GAAG,EAAE,iBAAiB;aACvB,CAAC,CAAA;YAEF,OAAO;gBACL,QAAQ,EAAE,cAAc;gBACxB,MAAM,EAAE,aAAa;aACtB,CAAA;QACH,CAAC,CAAC,CAAC,CAAA;QAEH,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAC;YACpD,OAAO;YACP,IAAI,EAAE,kCAAkC;YACxC,WAAW,EAAE,IAAI;SAClB,CAAC,CAAA;QAEF,MAAM,IAAI,GAAG,IAAA,2BAAkB,EAAC;YAC9B,KAAK,EAAE,EAAE,CAAC,KAAe;YACzB,MAAM,EAAE,EAAE,CAAC,MAAM;YACjB,IAAI,EAAE,EAAE,CAAC,IAAI;SACS,CAAC,CAAC,IAAI,CAAA;QAE9B,OAAO;YACL,IAAI;YACJ,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;SACxF,CAAA;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,qBAAqB,CAAC,QAAyB;QACnD,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,yFAAyF,CAAC,CAAA;QAC5G,CAAC;QACD,MAAM,cAAc,GAAoB,EAAE,CAAA;QAC1C,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;YAC5C,OAAO,EAAE,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YACpD,KAAK,EAAE,SAAS;SACjB,CAAC,CAAA;QAEF,uDAAuD;QACvD,IAAI,YAAY,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YACxC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;gBACpC,IAAI,CAAC;oBACH,yDAAyD;oBACzD,MAAM,EAAE,GAAG,iBAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;oBAC5C,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,aAAa,CAAC,CAAA;oBAC3F,IAAI,aAAa,KAAK,SAAS,IAAI,aAAa,KAAK,IAAI,IAAI,aAAa,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;wBACjG,cAAc,CAAC,IAAI,CAAC;4BAClB,GAAG,aAAa;4BAChB,IAAI,EAAE,MAAM,CAAC,IAAI;4BACjB,WAAW,EAAE,MAAM,CAAC,WAAW;yBAChC,CAAC,CAAA;oBACJ,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAA;gBAC/D,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,cAAc,CAAA;IACvB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,oBAAoB,CAAC,cAA+B;QACxD,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;QAC3D,CAAC;QACD,MAAM,YAAY,GAAyC,EAAE,CAAA;QAC7D,KAAK,MAAM,aAAa,IAAI,cAAc,EAAE,CAAC;YAC3C,IAAI,aAAa,CAAC,IAAI,KAAK,SAAS,IAAI,aAAa,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;gBAChF,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;YACtE,CAAC;YACD,0CAA0C;YAC1C,MAAM,eAAe,GAAG,iBAAW,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;YAChE,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;YACxC,MAAM,cAAc,GAAG,eAAe,CAAC,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,CAAA;YACzE,MAAM,WAAW,GAAG,eAAS,CAAC,cAAc,CAAC,IAAI,gBAAU,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;YAE/F,gEAAgE;YAChE,MAAM,iBAAiB,GAAG,IAAA,+BAAoB,EAAC;gBAC7C,mBAAmB,EAAE,IAAI,CAAC,UAAU;gBACpC,eAAe,EAAE,WAAW;gBAC5B,aAAa,EAAE,KAAK,aAAa,CAAC,QAAQ,IAAI;gBAC9C,UAAU,EAAE,KAAK;aAClB,CAAC,CAAA;YAEF,MAAM,eAAe,GAAG,MAAM,kBAAQ,CAAC,MAAM,CAAC;gBAC5C,GAAG,EAAE,iBAAiB;gBACtB,QAAQ,EAAE,MAAM;gBAChB,WAAW,EAAE,aAAa,CAAC,WAAW;gBACtC,aAAa,EAAE,cAAc,CAAC,aAAa,CAAC,KAAK,EAAE;gBACnD,YAAY,EAAE,cAAc,CAAC,QAAQ;aACtC,CAAC,CAAA;YAEF,MAAM,iBAAiB,GAAG;gBACxB,KAAK,EAAE,aAAa,CAAC,WAAW;gBAChC,eAAe;aAChB,CAAA;YAED,wCAAwC;YACxC,IAAI,YAAY,CAAC,MAAM,CAAC,KAAK,SAAS,EAAE,CAAC;gBACvC,YAAY,CAAC,MAAM,CAAC,GAAG;oBACrB,GAAG,IAAA,8BAAkB,EAAC,eAAe,CAAC;oBACtC,KAAK,EAAE,eAAe,CAAC,KAAK,EAAE;oBAC9B,eAAe,EAAE,CAAC,iBAAiB,CAAC;iBACrC,CAAA;YACH,CAAC;iBAAM,CAAC;gBACN,YAAY,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;YAC9D,CAAC;QACH,CAAC;QAED,qFAAqF;QACrF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAC;YAC1D,MAAM,EAAE,YAAY;YACpB,OAAO,EAAE,EAAE;YACX,MAAM,EAAE,EAAE;YACV,IAAI,EAAE,kCAAkC;YACxC,WAAW,EAAE,IAAI;SAClB,CAAC,CAAA;QAEF,MAAM,IAAI,GAAG,IAAA,2BAAkB,EAAC;YAC9B,KAAK,EAAE,QAAQ,CAAC,KAAe;YAC/B,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,IAAI,EAAE,QAAQ,CAAC,IAAI;SACG,CAAC,CAAC,IAAI,CAAA;QAE9B,OAAO;YACL,IAAI;YACJ,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;SAC/F,CAAA;IACH,CAAC;IAED;;;;OAIG;IACH,kBAAkB,CAAC,YAAoB;QACrC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,kBAAQ,CAAC,MAAM,CAAC;gBAC7B,MAAM,EAAE,YAAY,CAAC,KAAK,EAAE;gBAC5B,WAAW,EAAE,QAAQ;aACtB,CAAC,CAAA;YAEF,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAA;YACrD,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;YAC5C,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;gBAC/C,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAA;YAC3C,CAAC;YAED,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;YACpD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;YAC1C,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;YAElD,2CAA2C;YAC3C,OAAO;gBACL,QAAQ,EAAE,QAA2B;gBACrC,WAAW;gBACX,MAAM;gBACN,cAAc;aACf,CAAA;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAA;YACpD,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;QACjD,CAAC;IACH,CAAC;CACF;AAlPD,0CAkPC"}