@tradelayerprotocol/tradelayer 1.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/.claude/settings.local.json +13 -0
  2. package/.claude/skills/tl-algo/SKILL.md +255 -0
  3. package/.gitattributes +2 -0
  4. package/.github/workflows/publish.yaml +26 -0
  5. package/4mm.js +163 -0
  6. package/LICENSE +21 -0
  7. package/NPMSwapRefactor.zip +0 -0
  8. package/README.md +217 -0
  9. package/address.sh +26 -0
  10. package/algoAPI.js +581 -0
  11. package/analyzepsbt.js +92 -0
  12. package/apiEx.js +99 -0
  13. package/bb_hyperscalper.js +290 -0
  14. package/bbo_demo.js +111 -0
  15. package/buyer.js +622 -0
  16. package/client.js +50 -0
  17. package/createTxTest.js +26 -0
  18. package/createWallet.js +75 -0
  19. package/daytrader.js +531 -0
  20. package/decodeTest.js +69 -0
  21. package/fundingManager.js +144 -0
  22. package/index.js +4 -0
  23. package/listener.js +27 -0
  24. package/litecoreTxBuilder.js +1128 -0
  25. package/mmEx.js +356 -0
  26. package/networks.js +51 -0
  27. package/orderbook.js +200 -0
  28. package/package.json +34 -0
  29. package/perTradeQueue.js +36 -0
  30. package/projectsTLNPMTLNPM/package-lock.json +162 -0
  31. package/projectsTLNPMTLNPM/package.json +5 -0
  32. package/quick.js +32 -0
  33. package/quickFut.js +37 -0
  34. package/quickSell.js +37 -0
  35. package/relayerClient.js +117 -0
  36. package/run4mm.js +80 -0
  37. package/run_bbo_tracker.js +241 -0
  38. package/seller.js +443 -0
  39. package/session.js +45 -0
  40. package/setup-lin-ltc.sh +139 -0
  41. package/setup-lin.sh +203 -0
  42. package/setup-win-ltc.bat +108 -0
  43. package/setup-win.bat +167 -0
  44. package/spam_screamer_futures.js +222 -0
  45. package/tradelayer.js/.gitattributes +2 -0
  46. package/tradelayer.js/README.md +2 -0
  47. package/tradelayer.js/oldTests/activationTest.js +6 -0
  48. package/tradelayer.js/oldTests/base58.test.js +23 -0
  49. package/tradelayer.js/oldTests/base64Decode.test.js +16 -0
  50. package/tradelayer.js/oldTests/blocksRefactor.js +140 -0
  51. package/tradelayer.js/oldTests/checkVestBalance.js +25 -0
  52. package/tradelayer.js/oldTests/consensusHashProto.js +151 -0
  53. package/tradelayer.js/oldTests/contractOrderbook.js +243 -0
  54. package/tradelayer.js/oldTests/createPayload.js +0 -0
  55. package/tradelayer.js/oldTests/createTestnetAddr.js +43 -0
  56. package/tradelayer.js/oldTests/decode.js +205 -0
  57. package/tradelayer.js/oldTests/decodeTest.js +50 -0
  58. package/tradelayer.js/oldTests/displayTallyMap.js +19 -0
  59. package/tradelayer.js/oldTests/encodeDecode.js +340 -0
  60. package/tradelayer.js/oldTests/expressTest.js +29 -0
  61. package/tradelayer.js/oldTests/extractBlocksVanilla.js +214 -0
  62. package/tradelayer.js/oldTests/extractBlocksVanillaa.js +179 -0
  63. package/tradelayer.js/oldTests/extractPubkeyTest.js +60 -0
  64. package/tradelayer.js/oldTests/fillInputCacheProto.js +111 -0
  65. package/tradelayer.js/oldTests/getRawTxTest.js +22 -0
  66. package/tradelayer.js/oldTests/indexTest.js +26 -0
  67. package/tradelayer.js/oldTests/initTokensTest.js +32 -0
  68. package/tradelayer.js/oldTests/interfaceChild.js +129 -0
  69. package/tradelayer.js/oldTests/listenerChild.js +112 -0
  70. package/tradelayer.js/oldTests/opdecode.js +26 -0
  71. package/tradelayer.js/oldTests/options.js +79 -0
  72. package/tradelayer.js/oldTests/optxtest.js +116 -0
  73. package/tradelayer.js/oldTests/optxtest1.js +64 -0
  74. package/tradelayer.js/oldTests/oracle.test.js +32 -0
  75. package/tradelayer.js/oldTests/orderbook.test.js +36 -0
  76. package/tradelayer.js/oldTests/parsing.js +93 -0
  77. package/tradelayer.js/oldTests/payload.js +13 -0
  78. package/tradelayer.js/oldTests/persistenceUnitTest.js +23 -0
  79. package/tradelayer.js/oldTests/property.test.js +53 -0
  80. package/tradelayer.js/oldTests/propertyLevel.js +75 -0
  81. package/tradelayer.js/oldTests/propertyTest.js +32 -0
  82. package/tradelayer.js/oldTests/queryAddressTest.js +17 -0
  83. package/tradelayer.js/oldTests/salter.js +14 -0
  84. package/tradelayer.js/oldTests/tally.js +81 -0
  85. package/tradelayer.js/oldTests/tally.test.js +48 -0
  86. package/tradelayer.js/oldTests/tally2.js +124 -0
  87. package/tradelayer.js/oldTests/tally3.js +142 -0
  88. package/tradelayer.js/oldTests/tallyDiag.js +38 -0
  89. package/tradelayer.js/oldTests/testGetRaw.js +40 -0
  90. package/tradelayer.js/oldTests/testHexConvert.js +47 -0
  91. package/tradelayer.js/oldTests/testNewEncoding.js +96 -0
  92. package/tradelayer.js/oldTests/testNewEncoding2.js +113 -0
  93. package/tradelayer.js/oldTests/testNewEncoding3 +112 -0
  94. package/tradelayer.js/oldTests/testNewEncoding3.js +168 -0
  95. package/tradelayer.js/oldTests/testOPReturn.js +102 -0
  96. package/tradelayer.js/oldTests/testPayload.js +23 -0
  97. package/tradelayer.js/oldTests/testRaw.js +50 -0
  98. package/tradelayer.js/oldTests/testSendTooMuch.js +20 -0
  99. package/tradelayer.js/oldTests/testTxBuild +28 -0
  100. package/tradelayer.js/oldTests/testTxBuild.js +42 -0
  101. package/tradelayer.js/oldTests/tokenOrderbook.js +243 -0
  102. package/tradelayer.js/oldTests/txUtilsA.js +515 -0
  103. package/tradelayer.js/oldTests/validityUnitTest.js +53 -0
  104. package/tradelayer.js/oldTests/vaults.js +72 -0
  105. package/tradelayer.js/oldTests/volumeIndex.js +117 -0
  106. package/tradelayer.js/oldTests/volumeIndex2.js +88 -0
  107. package/tradelayer.js/output_base64.txt +1 -0
  108. package/tradelayer.js/package-lock.json +9967 -0
  109. package/tradelayer.js/package.json +61 -0
  110. package/tradelayer.js/server/index.js +88 -0
  111. package/tradelayer.js/server/litecoind.exe +0 -0
  112. package/tradelayer.js/src/activation.js +303 -0
  113. package/tradelayer.js/src/adjuster.js +77 -0
  114. package/tradelayer.js/src/amm.js +400 -0
  115. package/tradelayer.js/src/base256.js +55 -0
  116. package/tradelayer.js/src/base94.js +79 -0
  117. package/tradelayer.js/src/channels.js +1163 -0
  118. package/tradelayer.js/src/clearing.js +3109 -0
  119. package/tradelayer.js/src/clearlist.js +364 -0
  120. package/tradelayer.js/src/client.js +295 -0
  121. package/tradelayer.js/src/consensus.js +613 -0
  122. package/tradelayer.js/src/contractRegistry.js +964 -0
  123. package/tradelayer.js/src/db.js +89 -0
  124. package/tradelayer.js/src/init.js +24 -0
  125. package/tradelayer.js/src/insurance.js +347 -0
  126. package/tradelayer.js/src/interface.js +218 -0
  127. package/tradelayer.js/src/interfaceExpress.js +178 -0
  128. package/tradelayer.js/src/iou.js +509 -0
  129. package/tradelayer.js/src/listener.js +226 -0
  130. package/tradelayer.js/src/logic.js +1702 -0
  131. package/tradelayer.js/src/main.js +927 -0
  132. package/tradelayer.js/src/marginMap.js +2165 -0
  133. package/tradelayer.js/src/options.js +126 -0
  134. package/tradelayer.js/src/oracle.js +394 -0
  135. package/tradelayer.js/src/orderbook.js +4123 -0
  136. package/tradelayer.js/src/persistence.js +554 -0
  137. package/tradelayer.js/src/property.js +411 -0
  138. package/tradelayer.js/src/reOrg.js +41 -0
  139. package/tradelayer.js/src/scaling.js +145 -0
  140. package/tradelayer.js/src/tally.js +1275 -0
  141. package/tradelayer.js/src/tradeHistoryManager.js +552 -0
  142. package/tradelayer.js/src/txDecoder.js +584 -0
  143. package/tradelayer.js/src/txEncoder.js +610 -0
  144. package/tradelayer.js/src/txIndex.js +502 -0
  145. package/tradelayer.js/src/txUtils.js +1392 -0
  146. package/tradelayer.js/src/types.js +429 -0
  147. package/tradelayer.js/src/validity.js +3077 -0
  148. package/tradelayer.js/src/vaults.js +430 -0
  149. package/tradelayer.js/src/vesting.js +491 -0
  150. package/tradelayer.js/src/volumeIndex.js +618 -0
  151. package/tradelayer.js/src/walletInterface.js +220 -0
  152. package/tradelayer.js/src/walletListener.js +665 -0
  153. package/tradelayer.js/tests/256decode.js +82 -0
  154. package/tradelayer.js/tests/UTXOracle.js +205 -0
  155. package/tradelayer.js/tests/base94test.js +23 -0
  156. package/tradelayer.js/tests/cancelTxTest.js +62 -0
  157. package/tradelayer.js/tests/contractInterfaceTest.js +48 -0
  158. package/tradelayer.js/tests/decimalTest.js +65 -0
  159. package/tradelayer.js/tests/decoderTest.js +100 -0
  160. package/tradelayer.js/tests/deltaCount.js +47 -0
  161. package/tradelayer.js/tests/deltaCount2.js +60 -0
  162. package/tradelayer.js/tests/interfaceTest.js +37 -0
  163. package/tradelayer.js/tests/mainTest.js +53 -0
  164. package/tradelayer.js/tests/makeActivationTest.js +24 -0
  165. package/tradelayer.js/tests/maxHeightTest.js +49 -0
  166. package/tradelayer.js/tests/reverseHash.js +72 -0
  167. package/tradelayer.js/tests/sensitiveConsoleOutput.txt +267 -0
  168. package/tradelayer.js/tests/tallyTest.js +40 -0
  169. package/tradelayer.js/tests/testBuybacks.js +46 -0
  170. package/tradelayer.js/tests/testCodeHash.js +49 -0
  171. package/tradelayer.js/tests/testConsensusHash.js +91 -0
  172. package/tradelayer.js/tests/testDecode.js +30 -0
  173. package/tradelayer.js/tests/testEncodingLengths.js +129 -0
  174. package/tradelayer.js/tests/testGetTx +32 -0
  175. package/tradelayer.js/tests/testGetTx.js +32 -0
  176. package/tradelayer.js/tests/testHexHash.js +32 -0
  177. package/tradelayer.js/tests/testIndexHash.js +35 -0
  178. package/tradelayer.js/tests/testInitContracts.js +38 -0
  179. package/tradelayer.js/tests/testMaxConsensus.js +12 -0
  180. package/tradelayer.js/tests/testMaxSynth.js +44 -0
  181. package/tradelayer.js/tests/testMint.js +21 -0
  182. package/tradelayer.js/tests/testNetwork.js +33 -0
  183. package/tradelayer.js/tests/testOrderbookLoad.js +62 -0
  184. package/tradelayer.js/tests/testRebates.js +32 -0
  185. package/tradelayer.js/tests/testRedeem.js +22 -0
  186. package/tradelayer.js/tests/testTokenTrade.js +39 -0
  187. package/tradelayer.js/tests/testTxBuild.js +42 -0
  188. package/tradelayer.js/tests/testUTXOTrade.js +27 -0
  189. package/tradelayer.js/tests/tokenTradeHistory.js +27 -0
  190. package/tradelayer.js/tests/tradeFutures.js +40 -0
  191. package/tradelayer.js/tests/tradeHistoryExample.js +35 -0
  192. package/tradelayer.js/tests/tradeHistoryLoad.js +15 -0
  193. package/tradelayer.js/tests/txScanTest.js +134 -0
  194. package/tradelayer.js/tests/validateTest.js +136 -0
  195. package/tradelayer.js/tests/vestingTest.js +37 -0
  196. package/tradelayer.js/utils/activateMainnet.js +59 -0
  197. package/tradelayer.js/utils/activateMainnetDoge.js +63 -0
  198. package/tradelayer.js/utils/autocompactdb.js +23 -0
  199. package/tradelayer.js/utils/base64toHex.js +32 -0
  200. package/tradelayer.js/utils/broadcastDoge.js +38 -0
  201. package/tradelayer.js/utils/calcRedeem.js +19 -0
  202. package/tradelayer.js/utils/checkNetwork.js +27 -0
  203. package/tradelayer.js/utils/createAddress.js +48 -0
  204. package/tradelayer.js/utils/createAttestation.js +133 -0
  205. package/tradelayer.js/utils/createContract.js +118 -0
  206. package/tradelayer.js/utils/createOracle.js +94 -0
  207. package/tradelayer.js/utils/createwallet.js +20 -0
  208. package/tradelayer.js/utils/crossFuturesTrades.js +57 -0
  209. package/tradelayer.js/utils/crossTokenTrades.js +62 -0
  210. package/tradelayer.js/utils/dumpPriv.js +29 -0
  211. package/tradelayer.js/utils/generateChannel.js +34 -0
  212. package/tradelayer.js/utils/getInfo.js +21 -0
  213. package/tradelayer.js/utils/hardWipe.js +20 -0
  214. package/tradelayer.js/utils/hexTo64.js +16 -0
  215. package/tradelayer.js/utils/importAddress.js +28 -0
  216. package/tradelayer.js/utils/importpriv.js +20 -0
  217. package/tradelayer.js/utils/issueOracleContract.js +67 -0
  218. package/tradelayer.js/utils/issueTokens.js +41 -0
  219. package/tradelayer.js/utils/listunspent.js +66 -0
  220. package/tradelayer.js/utils/litecoinClient.js +30 -0
  221. package/tradelayer.js/utils/loadwallet.js +20 -0
  222. package/tradelayer.js/utils/publishOracle.js +113 -0
  223. package/tradelayer.js/utils/sendActivation.js +21 -0
  224. package/tradelayer.js/utils/sendChannelContractTrade.js +34 -0
  225. package/tradelayer.js/utils/sendChannelTokenTrade.js +34 -0
  226. package/tradelayer.js/utils/sendCommit.js +24 -0
  227. package/tradelayer.js/utils/sendDoge.js +62 -0
  228. package/tradelayer.js/utils/sendDogeMain.js +67 -0
  229. package/tradelayer.js/utils/sendDogeTx.js +46 -0
  230. package/tradelayer.js/utils/sendLTC.js +63 -0
  231. package/tradelayer.js/utils/sendMainnet.js +62 -0
  232. package/tradelayer.js/utils/sendTransfer.js +19 -0
  233. package/tradelayer.js/utils/sendVestTest.js +88 -0
  234. package/tradelayer.js/utils/sendWithdrawal.js +26 -0
  235. package/tradelayer.js/utils/simpleStart.js +8 -0
  236. package/tradelayer.js/utils/startStop.js +27 -0
  237. package/tradelayer.js/utils/structuredTrades.js +136 -0
  238. package/tradelayer.js/utils/verifySignature.js +90 -0
  239. package/tradelayer.js/utils/verifyWitnessAndScriptPubkey.js +41 -0
  240. package/tradelayer.js/utils/walletCache.js +172 -0
  241. package/tradelayer.js/utils/walletContractInterface.js +48 -0
  242. package/tradelayer.js/utils/walletFetchTxs.js +66 -0
  243. package/tradelayer.js/utils/walletUtils.js +97 -0
  244. package/tradelayer.js/utils/wipeDB.js +55 -0
  245. package/tradelayer.js/utils/wipeDBNotTx.js +50 -0
  246. package/txEncoder.js +529 -0
  247. package/utility.js +28 -0
  248. package/verifymessage.js +38 -0
  249. package/ws-transport.js +311 -0
@@ -0,0 +1,411 @@
1
+ const db = require('./db.js');
2
+ const path = require('path');
3
+ const BigNumber = require('bignumber.js')
4
+
5
+ class PropertyManager {
6
+ static instance = null;
7
+
8
+ constructor() {
9
+ if (PropertyManager.instance) {
10
+ return PropertyManager.instance;
11
+ }
12
+
13
+ this.propertyIndex = new Map();
14
+ this.ammIndex = new Map(); // Initialize AMM index
15
+ //this.synthIndex= new Map()
16
+ PropertyManager.instance = this;
17
+ }
18
+
19
+ static getInstance() {
20
+ if (!PropertyManager.instance) {
21
+ PropertyManager.instance = new PropertyManager();
22
+ }
23
+ return PropertyManager.instance;
24
+ }
25
+
26
+ static async load() {
27
+ //console.log('loading property list');
28
+ try {
29
+ const instance = PropertyManager.getInstance();
30
+ const base = await db.getDatabase('propertyList')
31
+ const propertyIndexEntry = await base.findOneAsync({ _id: 'propertyIndex' });
32
+ if (propertyIndexEntry && propertyIndexEntry.value) {
33
+ // Check if the value is a string and parse it as JSON
34
+ const data = typeof propertyIndexEntry.value === 'string' ? JSON.parse(propertyIndexEntry.value) : propertyIndexEntry.value;
35
+
36
+ // Ensure the data is an array of arrays before converting it to a Map
37
+ if (Array.isArray(data) && data.every(item => Array.isArray(item) && item.length === 2)) {
38
+ instance.propertyIndex = new Map(data);
39
+ } else {
40
+ console.error('Invalid data format for propertyIndex:', data);
41
+ instance.propertyIndex = new Map();
42
+ }
43
+ } else {
44
+ instance.propertyIndex = new Map(); // Initialize with an empty Map if no data is found
45
+ }
46
+ } catch (error) {
47
+ console.error('Error loading data from NeDB:', error);
48
+ //instance.propertyIndex = new Map(); // Use an empty Map in case of an error
49
+ }
50
+ }
51
+
52
+
53
+ async getNextPropertyId() {
54
+ await PropertyManager.load();
55
+ let maxId = 0;
56
+ for (let key of this.propertyIndex.keys()) {
57
+ maxId = Math.max(maxId, key);
58
+ }
59
+ return maxId + 1;
60
+ }
61
+
62
+ async createToken(ticker, totalInCirculation, type, whitelistId, issuer, backupAddress) {
63
+ // Check if the ticker already exists
64
+
65
+ if (this.propertyIndex.has(ticker)) {
66
+ return new (`Error: Ticker "${ticker}" already exists.`);
67
+ }
68
+ for (let [key, value] of this.propertyIndex.entries()) {
69
+ if (value.ticker === ticker) {
70
+ return Error(`Ticker "${ticker}" already exists.`);
71
+ }
72
+ }
73
+
74
+ const propertyId = await this.getNextPropertyId();
75
+ await this.addProperty(propertyId, ticker, totalInCirculation, type, whitelistId, issuer, backupAddress);
76
+ console.log(`Token created: ID = ${propertyId}, Ticker = ${ticker}, Type = ${type}`);
77
+ return propertyId;
78
+ }
79
+
80
+ async addProperty(propertyId, ticker, totalInCirculation, type, whitelistId, issuer, backupAddress) {
81
+
82
+ const propertyTypeIndexes = {
83
+ 'Fixed': 1,
84
+ 'Managed': 2,
85
+ 'Native': 3,
86
+ 'Vesting': 4,
87
+ 'Synthetic': 5,
88
+ 'Non-Fungible': 6,
89
+ };
90
+
91
+ if (!propertyTypeIndexes[type]) {
92
+ throw new Error('Invalid property type.');
93
+ }
94
+
95
+ let existingProperty = this.propertyIndex.get(propertyId);
96
+
97
+ if(type=="Synthetic"){
98
+ console.log('creating synth property '+propertyId+' '+totalInCirculation+' '+existingProperty)
99
+ // Retrieve existing property entry if it exists
100
+ }
101
+
102
+ if (existingProperty) {
103
+ // If property exists, update totalInCirculation and other fields if necessary
104
+ existingProperty.totalInCirculation = BigNumber(existingProperty.totalInCirculation).plus(totalInCirculation).toNumber();
105
+ existingProperty.ticker = ticker || existingProperty.ticker;
106
+ existingProperty.type = propertyTypeIndexes[type];
107
+ existingProperty.whitelistId = whitelistId || existingProperty.whitelistId;
108
+ existingProperty.issuer = issuer || existingProperty.issuer;
109
+ existingProperty.backupAddress = backupAddress || existingProperty.backupAddress;
110
+ } else {
111
+ // If property does not exist, create a new one
112
+ existingProperty = {
113
+ ticker,
114
+ totalInCirculation,
115
+ type: propertyTypeIndexes[type],
116
+ whitelistId: whitelistId,
117
+ issuer: issuer,
118
+ backupAddress: backupAddress
119
+ };
120
+ }
121
+
122
+ let blob = {
123
+ ticker,
124
+ totalInCirculation,
125
+ type: propertyTypeIndexes[type],
126
+ whitelistId: whitelistId,
127
+ issuer: issuer,
128
+ backupAddress: backupAddress
129
+ }
130
+
131
+ this.propertyIndex.set(propertyId,existingProperty);
132
+ await this.save();
133
+ return console.log('updated Property Index '+this.propertyIndex)
134
+ }
135
+
136
+ async inspectPropertyIndex() {
137
+ const propertyManager = PropertyManager.getInstance();
138
+
139
+ // Load the properties
140
+ await PropertyManager.load();
141
+
142
+ // Convert the Map into an array of key-value pairs
143
+ const propertiesArray = Array.from(propertyManager.propertyIndex.entries());
144
+
145
+ // Alternatively, convert the Map into an object for easier visualization
146
+ const propertiesObject = Object.fromEntries(propertyManager.propertyIndex);
147
+
148
+ console.log('Properties as Array:', propertiesArray);
149
+ console.log('Properties as Object:', propertiesObject);
150
+ }
151
+
152
+ static async getAMM(propertyId1, propertyId2) {
153
+ const pairKey = `${propertyId1}-${propertyId2}`;
154
+ const ammInstance = PropertyRegistry.getInstance().ammIndex.get(pairKey);
155
+
156
+ if (ammInstance) {
157
+ return ammInstance;
158
+ } else {
159
+ // If AMM instance doesn't exist, initialize it
160
+ const newAMM = await initializeAMM(propertyId1, propertyId2); // You need to define the initialization logic
161
+ PropertyRegistry.getInstance().ammIndex.set(pairKey, newAMM);
162
+ return newAMM;
163
+ }
164
+ }
165
+
166
+ static async isManagedAndAdmin(propertyId,address) {
167
+ try {
168
+ // Load the property index from the database
169
+ const base = await db.getDatabase('propertyList');
170
+ const propertyIndex = await base.findOneAsync({ _id: 'propertyIndex' });
171
+
172
+ if (!propertyIndex || !propertyIndex.value) {
173
+ throw new Error('Property index not found.');
174
+ }
175
+
176
+ // Parse the JSON string to get the array of arrays
177
+ const parsedIndex = JSON.parse(propertyIndex.value);
178
+
179
+ // Find the property entry by propertyId
180
+ const propertyEntry = parsedIndex.find(entry => entry[0] === propertyId);
181
+
182
+ if (!propertyEntry) {
183
+ throw new Error(`Property with ID ${propertyId} not found.`);
184
+ }
185
+
186
+ // Check if the property type is 2 (Managed)
187
+ const propertyData = propertyEntry[1];
188
+ return propertyData.type === 2&&propertyData.issuer===address;
189
+ } catch (error) {
190
+ console.error(`Error checking if property ID ${propertyId} is managed:`, error);
191
+ return false;
192
+ }
193
+ }
194
+
195
+
196
+
197
+
198
+ static async updateTotalInCirculation(propertyId, amountChange) {
199
+ const propertyData = await PropertyManager.getPropertyData(propertyId);
200
+
201
+ if (!propertyData) {
202
+ throw new Error('Property not found');
203
+ }
204
+
205
+ propertyData.totalInCirculation = BigNumber(propertyData.totalInCirculation).plus(amountChange).toNumber();
206
+
207
+ // Update the property data in the database
208
+ const base= await db.getDatabase('propertyList')
209
+ const propertyIndex = await base.findOneAsync({ _id: 'propertyIndex' });
210
+ const parsedData = JSON.parse(propertyIndex.value);
211
+
212
+ const propertyEntry = parsedData.find(entry => entry[0] === propertyId);
213
+ if (propertyEntry) {
214
+ propertyEntry[1] = propertyData;
215
+ const base = db.getDatabase('propertyList')
216
+ await base.updateAsync({ _id: 'propertyIndex' }, { $set: { value: JSON.stringify(parsedData) } });
217
+ } else {
218
+ throw new Error('Failed to update totalInCirculation, property not found in index');
219
+ }
220
+ }
221
+
222
+
223
+ async save() {
224
+ const propertyIndexJSON = JSON.stringify([...this.propertyIndex.entries()]);
225
+ const propertyIndexData = { _id: 'propertyIndex', value: propertyIndexJSON };
226
+
227
+ try {
228
+ const propertyListDB = await db.getDatabase('propertyList');
229
+ await propertyListDB.updateAsync({ _id: 'propertyIndex' }, propertyIndexData, { upsert: true });
230
+ } catch (err) {
231
+ console.error('Error saving property index:', err);
232
+ throw err;
233
+ }
234
+ }
235
+
236
+
237
+
238
+ static async getPropertyIndex() {
239
+ const instance = PropertyManager.getInstance();
240
+
241
+ // If the propertyIndex is empty, load it first
242
+ if (instance.propertyIndex.size === 0) {
243
+ await PropertyManager.load();
244
+ }
245
+
246
+ // Transform the Map into an array of objects, each representing a property
247
+ return Array.from(instance.propertyIndex).map(([id, property]) => ({
248
+ id,
249
+ ticker: property.ticker,
250
+ totalInCirculation: property.totalInCirculation,
251
+ type: property.type
252
+ }));
253
+ }
254
+
255
+
256
+ /**
257
+ * Checks if the given ticker already exists in the property index.
258
+ * @param {string} ticker - The ticker to check for existence.
259
+ * @returns {boolean} - True if the ticker exists, false otherwise.
260
+ */
261
+ static async doesTickerExist(ticker) {
262
+ // Ensure the property index is loaded before checking
263
+ const base = await db.getDatabase('propertyList')
264
+ const index = await base.findOneAsync({ _id: 'propertyIndex' });
265
+
266
+ if(!index){
267
+ return false
268
+ }
269
+ // Parse the JSON string to get the actual array
270
+ const parsedIndex = JSON.parse(index.value);
271
+
272
+ // Iterate over the parsed array to check for the ticker
273
+ for (let [propertyId, propertyData] of parsedIndex) {
274
+ if (propertyData.ticker === ticker) {
275
+ return true;
276
+ }
277
+ }
278
+ return false;
279
+ }
280
+
281
+
282
+ /**
283
+ * Checks if the given propertyId is a synthetic token.
284
+ * @param {number} propertyId - The ID of the property to check.
285
+ * @returns {boolean} - True if the property is a synthetic token, false otherwise.
286
+ */
287
+ static async isSyntheticToken(propertyId) {
288
+ if(!this.propertyIndex){await this.load();} // Make sure the property list is loaded
289
+ const propertyInfo = this.propertyIndex.get(propertyId);
290
+ // Check if the propertyInfo is valid and the type is 5 (synthetic)
291
+ return propertyInfo && propertyInfo.type === 5;
292
+ }
293
+
294
+ async grantTokens(propertyId, recipient, amount,block) {
295
+ const propertyData = await this.getPropertyData(propertyId);
296
+ if (!propertyData) {
297
+ throw new Error(`Property with ID ${propertyId} not found.`);
298
+ }
299
+
300
+ // Update managed supply
301
+ propertyData.totalInCirculation += amount;
302
+
303
+ // Update tally map to credit the amount to recipient
304
+ await TallyMap.updateBalance(recipient, propertyId, amount,0,0,0,'grantToken',block);
305
+
306
+ // Save changes
307
+ await this.save();
308
+ console.log(`Granted ${amount} managed tokens to ${recipient} for property ${propertyId}.`);
309
+ }
310
+
311
+ async redeemTokens(propertyId, recipient, amount,block) {
312
+ const propertyData = await this.getPropertyData(propertyId);
313
+ if (!propertyData) {
314
+ throw new Error(`Property with ID ${propertyId} not found.`);
315
+ }
316
+
317
+ // Ensure enough managed tokens available for redemption
318
+ if (propertyData.totalInCirculation < amount) {
319
+ throw new Error(`Insufficient managed tokens for redemption for property ${propertyId}.`);
320
+ }
321
+
322
+ // Update managed supply
323
+ propertyData.totalInCirculation -= amount;
324
+
325
+ // Update tally map to debit the amount from recipient
326
+ await TallyMap.updateBalance(recipient, propertyId, -amount,0,0,0,'redeemToken',block);
327
+
328
+ // Save changes
329
+ await this.save();
330
+ console.log(`Redeemed ${amount} managed tokens from ${recipient} for property ${propertyId}.`);
331
+ }
332
+
333
+
334
+ static async getPropertyData(propertyId) {
335
+ try {
336
+ const base = await db.getDatabase('propertyList')
337
+ const propertyData = await base.findOneAsync({ _id: 'propertyIndex' });
338
+ //console.log('property list ' +JSON.stringify(propertyData))
339
+ if (propertyData && propertyData.value) {
340
+ const parsedData = JSON.parse(propertyData.value);
341
+ //console.log(propertyId)
342
+ // Check if propertyId is a synthetic ID
343
+ if (typeof propertyId === 'string' && propertyId.startsWith('s')) {
344
+ console.log('inside get property synthetic '+propertyId)
345
+ const syntheticEntry = parsedData.find(entry => entry[0] === propertyId);
346
+ console.log(JSON.stringify(syntheticEntry))
347
+ if (syntheticEntry) {
348
+ return syntheticEntry[1];
349
+ }/* else {
350
+ // Optionally, look for the synthetic ID in a separate registry
351
+ const syntheticData = await db.getDatabase('syntheticTokens').findOneAsync({ _id: propertyId });
352
+ return syntheticData ? JSON.parse(syntheticData.value) : null;
353
+ }*/
354
+ }
355
+
356
+ // Check for integer-based property ID
357
+ //console.log('propertyId:', propertyId, 'type:', typeof propertyId);
358
+ const propertyEntry = parsedData.find(entry => Number(entry[0]) === Number(propertyId));
359
+ //console.log('retrieving property data '+JSON.stringify(propertyEntry)+' '+JSON.stringify(parsedData))
360
+ if (propertyEntry) {
361
+ return propertyEntry[1];
362
+ } else {
363
+ return null;
364
+ }
365
+ } else {
366
+ return null; // Return null if no property data found in the database
367
+ }
368
+ } catch (error) {
369
+ console.error('Error fetching property data:', error);
370
+ return null; // Return null in case of any errors
371
+ }
372
+ }
373
+
374
+
375
+ static async updateAdmin(propertyId, newAddress, backup) {
376
+ try {
377
+ // Ensure the property index is loaded
378
+ await PropertyManager.load();
379
+
380
+ // Check if the property exists
381
+ if (!PropertyManager.instance.propertyIndex.has(propertyId)) {
382
+ throw new Error(`Property with ID ${propertyId} does not exist.`);
383
+ }
384
+
385
+ // Get the property data
386
+ const propertyData = await getPropertyData(propertyId);
387
+
388
+ if(backup){
389
+ properData.backupAddress=newAddress
390
+ }else{
391
+ // Update the admin address
392
+ propertyData.issuer = newAddress;
393
+ }
394
+
395
+ // Update the property index with the modified property data
396
+ this.propertyIndex.set(propertyId, propertyData);
397
+
398
+ await this.save();
399
+
400
+ console.log(`Admin address for property ID ${propertyId} updated to ${newAddress}.`);
401
+ } catch (error) {
402
+ console.error(`Error updating admin address for property ID ${propertyId}:`, error);
403
+ throw error;
404
+ }
405
+ }
406
+
407
+
408
+ // ... other methods like verifyIfManaged, updateAdmin ...
409
+ }
410
+
411
+ module.exports = PropertyManager;
@@ -0,0 +1,41 @@
1
+ const litecoin = require('litecoin');
2
+ const config = {host: '127.0.0.1',
3
+ port: 18332,
4
+ user: 'user',
5
+ pass: 'pass',
6
+ timeout: 10000}
7
+
8
+ class ReOrgChecker {
9
+ constructor(config) {
10
+ this.client = new litecoin.Client(config);
11
+ }
12
+
13
+ async getBlock(hash) {
14
+ try {
15
+ return await this.client.getBlock(hash);
16
+ } catch (error) {
17
+ console.error('Error fetching block:', error);
18
+ throw error;
19
+ }
20
+ }
21
+
22
+ async checkReOrg() {
23
+ try {
24
+ const chainTips = await this.client.cmd('getchaintips');
25
+ const potentialReorgs = chainTips.filter(tip => tip.status === 'valid-fork' || tip.status === 'headers-only');
26
+
27
+ for (const tip of potentialReorgs) {
28
+ const block = await this.getBlock(tip.hash);
29
+ // Compare this block with your database
30
+ // If this block is not in your main chain, a reorg might have occurred
31
+
32
+ console.log(`Potential reorg detected at block ${block.height}: ${block.hash}`);
33
+ // Implement additional logic to handle reorg if needed
34
+ }
35
+ } catch (error) {
36
+ console.error('Error in checkReOrg:', error);
37
+ }
38
+ }
39
+ }
40
+
41
+ module.exports = ReOrgChecker;
@@ -0,0 +1,145 @@
1
+ const data = require('./db.js');
2
+
3
+
4
+ const Scaling = {
5
+ // Check if a settlement has already been neutralized
6
+ async isThisSettlementAlreadyNeutralized(channel, txid) {
7
+ const settlements = await this.getFileByChannel(txid, channel);
8
+
9
+ // If settlements is undefined or empty, no settlement has been recorded yet
10
+ if (!settlements || settlements.length === 0) {
11
+ return false; // Return false if no settlements found
12
+ }
13
+
14
+ // Loop through settlements array to check if the txid exists and is neutralized
15
+ for (const settlement of settlements) {
16
+ if (settlement.txid === txid && settlement.status=='neutralized') {
17
+ return true; // Return true if the txid is found and is neutralized
18
+ }
19
+ }
20
+
21
+ return false; // Return false if txid is not found or not neutralized
22
+ },
23
+
24
+ // Mark a settlement as neutralized
25
+ async neutralizeSettlement(channel, txid){
26
+ let settlements = await this.getFileByChannel(channel, txid);
27
+ let settlement = null
28
+ for(const item of settlements){
29
+ if (item.txid === txid && item.status=='neutralized') {
30
+ settlement=item; // Return true if the txid is found and is neutralized
31
+ }
32
+ }
33
+ if (settlement==null) {
34
+ settlement = {txid: txid, status: 'neutralized' };
35
+ } else {
36
+ settlement.status = "neutralized";
37
+ }
38
+ await this.recordTransaction(channel,settlement);
39
+ },
40
+
41
+ // Check if a trade has been published or if it's in a certain status (live, expired, unpublished)
42
+ async isTradePublished(txidNeutralized1){
43
+ const trade = await this.getTradeByTxid(txidNeutralized1);
44
+ if (!trade) {
45
+ return { status: "unpublished" };
46
+ } else if (trade.expired && trade.type === "contract") {
47
+ return { status: "expiredContract", params: trade };
48
+ } else if (trade.expired && trade.type === "token") {
49
+ return { status: "expiredToken", params: trade };
50
+ } else {
51
+ return { status: trade.live ? "liveContract" : "liveToken", params: trade };
52
+ }
53
+ },
54
+
55
+ // Put settlement into a limbo state if trade is not yet published
56
+ async settlementLimbo(channel, txid) {
57
+ const limbo = { txid, status: "pending" };
58
+ await this.saveSettlement(channel, limbo);
59
+ },
60
+
61
+ // Generate an offset based on the trade parameters and the current mark price
62
+ generateOffset(tradeParams, markPrice) {
63
+ // Assume some logic here to calculate the offset based on the markPrice vs original trade price
64
+ const offsetAmount = calculatePNL(tradeParams, markPrice);
65
+ const offsetParams = { ...tradeParams, adjustedAmount: offsetAmount };
66
+ return { params: offsetParams };
67
+ },
68
+
69
+ // Query prior settlements related to the transaction for chaining logic
70
+ async queryPriorSettlements(txidNeutralized1, txidNeutralized2, channelAddress) {
71
+ // Assume logic here to look up prior settlements in the same channel
72
+ const settlements = await this.getFileByChannel(txidNeutralized1, channelAddress);
73
+ return settlements;
74
+ },
75
+
76
+ // Settle the PNL based on the mark price and previous settlements
77
+ async settlePNL(lastSettlement, markPrice, txidNeutralized1) {
78
+ const lastPrice = lastSettlement ? lastSettlement.markPrice : null;
79
+ const pnlAmount = calculatePNL({ previousPrice: lastPrice, markPrice });
80
+
81
+ // Store the final settlement
82
+ const finalSettlement = { txid: txidNeutralized1, markPrice, pnlAmount };
83
+ await this.saveSettlement(finalSettlement);
84
+
85
+ return finalSettlement;
86
+ },
87
+
88
+ // Helper function to get a settlement by its txid
89
+ async getSettlementByTxid(channel, txid) {
90
+ // Assume logic to get settlement from the database
91
+ const db = await data.getDatabase('scaling');
92
+ return await db.findOneAsync({ txid });
93
+ },
94
+
95
+
96
+ // Function to update a specific part of the document
97
+ async recordTransaction(channelAddress, txid, txType, status) {
98
+ // Fetch the full document or initialize a new one if it doesn't exist
99
+ let scalingData = await scalingDb.findOneAsync({ _id: channelAddress }) || {
100
+ _id: channelAddress,
101
+ contractTrades: [],
102
+ tokenTrades: [],
103
+ settlements: [],
104
+ misc: []
105
+ };
106
+
107
+ // Determine the transaction type and update the appropriate array
108
+ switch (txType) {
109
+ case 19: // Contract trade
110
+ scalingData.contractTrades.push({ txid: txid, status: status });
111
+ break;
112
+ case 20: // Token trade
113
+ scalingData.tokenTrades.push({ txid: txid, status: status });
114
+ break;
115
+ case 23: // Settlement
116
+ scalingData.settlements.push({ txid: txid, status: status });
117
+ break;
118
+ default: // Miscellaneous transactions
119
+ scalingData.misc.push({ txid: txid, status: status });
120
+ break;
121
+ }
122
+
123
+ // Save or update the document in the database
124
+ await scalingDb.updateAsync({ _id: channelAddress }, scalingData, { upsert: true });
125
+ },
126
+
127
+ // Helper function to get settlements based on txid and channel
128
+ async getFileByChannel(channelAddress, type) {
129
+ const db = await data.getDatabase('scaling');
130
+ const query = { _id: channelAddress }; // Searching by channelAddress
131
+ const doc = await db.findOneAsync(query);
132
+
133
+ // If no doc or settlements exist for the channel, return an empty array
134
+ return doc && doc.settlements ? doc.settlements : [];
135
+ },
136
+
137
+ // Mock function to calculate PNL (replace with your actual logic)
138
+ calculatePNL({ previousPrice, markPrice }) {
139
+ // Simple PNL calculation, replace with actual formula
140
+ return markPrice - previousPrice;
141
+ }
142
+
143
+ };
144
+
145
+ module.exports = Scaling;