@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,89 @@
1
+ const Datastore = require('nedb');
2
+ const path = require('path');
3
+ const util = require('util');
4
+ const ClientWrapper = require('./client')
5
+
6
+
7
+ class Database {
8
+ constructor() {
9
+ this.databases = {};
10
+ this.initialized = false;
11
+ this.initializing = false
12
+ this.path = ''
13
+ this.test=false
14
+ }
15
+
16
+ async init(chain) {
17
+ if(this.initializing||this.initialized){
18
+ return
19
+ }
20
+ this.initializing= true
21
+
22
+ const instance = await ClientWrapper.getInstance();
23
+ if (!chain) {
24
+
25
+ chain = await instance.getChain();
26
+ }
27
+
28
+ this.test = await instance.getTest()
29
+
30
+ while (!chain) {
31
+ console.log('Waiting for chain...');
32
+ await new Promise(resolve => setTimeout(resolve, 300));
33
+ const instance = await ClientWrapper.getInstance();
34
+ chain = instance.chain;
35
+ }
36
+ let test = 'test'
37
+ if(this.test==false){
38
+ test = 'main'
39
+ }
40
+ const folderName = chain.toLowerCase()+'-'+test
41
+ const dbPath = path.join(__dirname, '..', 'nedb-data', folderName);
42
+ this.path=dbPath
43
+ const categories = ['ammRegistry', 'ammState','txIndex', 'propertyList',
44
+ 'oracleList', 'oracleData', 'contractList','tallyMap', 'tallyMapDelta',
45
+ 'marginMapDelta', 'marginMaps', 'clearlists','attestations', 'clearing',
46
+ 'consensus', 'persistence','volumeIndex','channels', 'withdrawQueue',
47
+ 'activations', 'insurance','orderBooks','feeCache', 'tradeHistory',
48
+ 'fundingEvents', 'vaults','syntheticTokens','liquidations', 'scaling',
49
+ 'channelDelta','iou'
50
+ ];
51
+
52
+ categories.forEach(category => {
53
+ try {
54
+ const db = new Datastore({
55
+ filename: path.join(dbPath, `${category}.db`),
56
+ autoload: true
57
+ });
58
+
59
+ db.findAsync = util.promisify(db.find.bind(db));
60
+ db.insertAsync = util.promisify(db.insert.bind(db));
61
+ db.removeAsync = util.promisify(db.remove.bind(db));
62
+ db.updateAsync = util.promisify(db.update.bind(db));
63
+ db.findOneAsync = util.promisify(db.findOne.bind(db));
64
+ db.countAsync = util.promisify(db.count.bind(db));
65
+
66
+ this.databases[category] = db;
67
+ } catch (error) {
68
+ console.error(`Error initializing database for category ${category}:`, error);
69
+ throw error; // Re-throw error after logging
70
+ }
71
+ });
72
+
73
+ this.initialized = true;
74
+ }
75
+
76
+ async getDatabase(category) {
77
+ if (!this.initialized) {
78
+ await this.init();
79
+ }
80
+ return this.databases[category];
81
+ }
82
+ }
83
+
84
+ const databaseInstance = new Database();
85
+ (async () => {
86
+ await databaseInstance.init();
87
+ })();
88
+
89
+ module.exports = databaseInstance;
@@ -0,0 +1,24 @@
1
+ // init.js
2
+ const ClientWrapper = require('./client');
3
+ const Database = require('./db');
4
+
5
+ async function waitForClientChain(client, timeout = 5000, interval = 150) {
6
+ const startTime = Date.now();
7
+ while (!client) {
8
+
9
+ await new Promise(resolve => setTimeout(resolve, interval));
10
+ }
11
+ }
12
+
13
+ // Inside your initialize function
14
+ async function initialize() {
15
+ const Client = await ClientWrapper.getInstance();
16
+ await waitForClientChain(Client); // Wait for Client.chain to be defined
17
+ await new Promise(resolve => setTimeout(resolve, 500));
18
+ console.log('showing chain in startup '+Client.chain)
19
+ await Database.init(Client.chain);
20
+ return { Client, Db: Database };
21
+ }
22
+
23
+
24
+ module.exports = initialize;
@@ -0,0 +1,347 @@
1
+ const db = require('./db.js');
2
+ const path = require('path');
3
+ const TxUtils = require('./txUtils.js');
4
+ const TallyMap = require('./tally.js');
5
+ const BigNumber = require('bignumber.js');
6
+
7
+ class InsuranceFund {
8
+ static instances = new Map(); // Store instances for each contract
9
+
10
+ constructor(contractSeriesId, oracle = false) {
11
+ this.contractSeriesId = contractSeriesId;
12
+ this.balances = []; // { propertyId: '', amountAvailable: 0, amountVesting: 0 }
13
+ this.hedgeRatio = 0.5; // Default 50% hedging
14
+ this.oracle = oracle;
15
+ }
16
+
17
+ /** 🔄 Get or create an instance for a given contract ID */
18
+ static async getInstance(contractId, oracle = false) {
19
+ const key = `${contractId}${oracle ? "-oracle" : ""}`;
20
+
21
+ if (!this.instances.has(key)) {
22
+ const instance = new InsuranceFund(contractId, oracle);
23
+ await instance.loadFromSnapshot(); // Load data if available
24
+ this.instances.set(key, instance);
25
+ }
26
+ return this.instances.get(key);
27
+ }
28
+
29
+ /** 🔄 Load saved snapshot from DB */
30
+ async loadFromSnapshot() {
31
+ let key = this.contractSeriesId.toString();
32
+ if (this.oracle) key += "-oracle";
33
+
34
+ const dbInstance = await db.getDatabase("insurance");
35
+ const doc = await dbInstance.findOneAsync({ key });
36
+
37
+ if (doc && doc.value) {
38
+ this.balances = doc.value.balances || [];
39
+ this.hedgeRatio = doc.value.hedgeRatio || 0.5;
40
+ }
41
+ }
42
+
43
+ /** 💰 Deposit funds into the insurance fund */
44
+ async deposit(propertyId, amount, block){
45
+ // Always load latest state
46
+ await this.loadFromSnapshot();
47
+
48
+ // Normalize and prepare precise inputs
49
+ const propId = propertyId != null ? propertyId.toString() : "unknown";
50
+ const amtBN = new BigNumber(amount || 0);
51
+ if (!amtBN.isFinite() || amtBN.lte(0)) {
52
+ console.warn(`⚠️ Ignoring invalid or zero deposit for ${propId}`);
53
+ return;
54
+ }
55
+
56
+ // Find existing balance (match tolerant to numeric/string)
57
+ let balance = this.balances.find(b => String(b.propertyId) === propId);
58
+
59
+ if (balance) {
60
+ const before = new BigNumber(balance.amountAvailable || 0);
61
+ balance.amountAvailable = before
62
+ .plus(amtBN)
63
+ .decimalPlaces(8, BigNumber.ROUND_DOWN)
64
+ .toFixed();
65
+ } else {
66
+ balance = {
67
+ propertyId: propId,
68
+ amountAvailable: amtBN.decimalPlaces(8, BigNumber.ROUND_DOWN).toFixed()
69
+ };
70
+ this.balances.push(balance);
71
+ }
72
+
73
+ console.log(`🏦 Depositing ${amtBN.toFixed(8)} into property ${propId} on contract ${this.contractSeriesId}`);
74
+ console.log(`✅ Updated balances:`, this.balances);
75
+
76
+ // Log and snapshot
77
+ await this.recordEvent("deposit", {
78
+ contractId: this.contractSeriesId?.toString() ?? "unknown",
79
+ propertyId: propId,
80
+ amount: amtBN.decimalPlaces(8, BigNumber.ROUND_DOWN).toFixed()
81
+ }, block);
82
+
83
+ const snapshot = {
84
+ balances: this.balances,
85
+ contractSeriesId: this.contractSeriesId?.toString() ?? "unknown",
86
+ hedgeRatio: this.hedgeRatio,
87
+ block
88
+ };
89
+
90
+ await this.saveSnapshot(snapshot);
91
+ }
92
+
93
+ /** 💸 Withdraw from the insurance fund */
94
+ async withdraw(amount, propertyId,block) {
95
+ const balanceEntry = this.balances.find(b => b.propertyId === propertyId);
96
+ if (!balanceEntry || balanceEntry.amountAvailable < amount) {
97
+ throw new Error("Insufficient balance in the insurance fund");
98
+ }
99
+ balanceEntry.amountAvailable -= amount;
100
+ await this.recordEvent("withdraw", { contractId: this.contractSeriesId, propertyId, amount }, block);
101
+ await this.saveSnapshot();
102
+ }
103
+
104
+ /** 💾 Save the insurance fund state */
105
+ async saveSnapshot(snapshot = null) {
106
+ let key = `${this.contractSeriesId}`;
107
+ if (this.oracle) key += "-oracle";
108
+
109
+ const block = await TxUtils.getBlockCount();
110
+ const finalSnapshot = snapshot || {
111
+ balances: this.balances,
112
+ contractSeriesId: this.contractSeriesId,
113
+ hedgeRatio: this.hedgeRatio,
114
+ block
115
+ };
116
+
117
+ console.log("💾 Saving snapshot for", key, ":", finalSnapshot);
118
+ const dbInstance = await db.getDatabase("insurance");
119
+ await dbInstance.updateAsync({ key }, { $set: { value: finalSnapshot } }, { upsert: true });
120
+ }
121
+
122
+ /** 📜 Fetch a stored snapshot */
123
+ async getSnapshot() {
124
+ const dbInstance = await db.getDatabase("insurance");
125
+ const doc = await dbInstance.findOneAsync({ key: this.contractSeriesId.toString() });
126
+ return doc ? doc.value : null;
127
+ }
128
+
129
+ /** 📌 Record important events in the insurance fund */
130
+ async recordEvent(eventType, eventData,block) {
131
+ const eventRecord = {
132
+ type: eventType,
133
+ data: eventData,
134
+ timestamp: block
135
+ };
136
+
137
+ const dbInstance = await db.getDatabase("insurance");
138
+ await dbInstance.insertAsync({ key: `event-${eventRecord.timestamp}`, value: eventRecord });
139
+ }
140
+
141
+ /** 🔥 Liquidate insurance fund to an admin address */
142
+ static async liquidate(adminAddress, contractId, isOracle = false) {
143
+ try {
144
+ const instance = await InsuranceFund.getInstance(contractId, isOracle);
145
+ let key = instance.contractSeriesId.toString();
146
+ if (isOracle) key += "-oracle";
147
+
148
+ const snapshot = await instance.getSnapshot();
149
+ if (!snapshot) {
150
+ throw new Error("Insurance fund snapshot not found");
151
+ }
152
+
153
+ let totalBalance = snapshot.balances.reduce((sum, b) => sum + b.amountAvailable, 0);
154
+ if (totalBalance === 0) {
155
+ console.log("⚠️ No funds available for liquidation.");
156
+ return;
157
+ }
158
+
159
+ const payoutAmount = totalBalance / 2;
160
+ const feeCache = totalBalance / 2;
161
+
162
+ console.log(`💰 Half sent to admin (${payoutAmount}), half added to fee cache (${feeCache})`);
163
+
164
+ await TallyMap.updateBalance(adminAddress, contractId, payoutAmount, 0, 0, 0, "credit", snapshot.block);
165
+ await InsuranceFund.updateFeeCache(contractId, feeCache);
166
+ } catch (error) {
167
+ console.error(`🚨 Error liquidating insurance fund:`, error);
168
+ }
169
+ }
170
+
171
+ /** 📊 Calculate payouts for a range of blocks */
172
+ async getPayouts(contractId, startBlock, endBlock) {
173
+ // Get the insurance database instance
174
+ const dbInstance = await db.getDatabase("insurance");
175
+
176
+ // Query for all payout events for this contract in the given block range.
177
+ // Assumes events are stored with keys of the form "payout-<contractId>-<block>"
178
+ const query = {
179
+ key: { $regex: `^payout-${contractId}-` },
180
+ "value.block": { $gte: startBlock, $lte: endBlock }
181
+ };
182
+
183
+ // Using findAsync which returns an array of documents.
184
+ const docs = await dbInstance.findAsync(query);
185
+ // Map to just the payout event values
186
+ const payouts = docs.map(doc => doc.value);
187
+ return payouts;
188
+ }
189
+
190
+
191
+ /**
192
+ * Calculate required payout from the insurance fund and update the fund accordingly.
193
+ * Debits the fund by the actual payout (which may be less than totalLoss if funds are insufficient),
194
+ * records the payout event under a dedicated key, and saves the updated snapshot.
195
+ *
196
+ * @param {number|string} totalLoss - The total loss amount (negative for losses).
197
+ * @param {number} block - The block number at which the payout is computed.
198
+ */
199
+ async calcPayout(totalLoss, block) {
200
+ // Convert totalLoss to a BigNumber.
201
+ const lossBN = totalLoss;
202
+
203
+ // Calculate the total available funds in the insurance fund.
204
+ let totalAvailable = new BigNumber(0);
205
+ for (const balance of this.balances) {
206
+ totalAvailable = totalAvailable.plus(new BigNumber(balance.amountAvailable));
207
+ }
208
+
209
+ // Determine the actual payout amount:
210
+ // If the absolute loss exceeds available funds, pay out only what's available (preserving the sign)
211
+ let payoutAmount;
212
+ if (lossBN.abs().isGreaterThan(totalAvailable)) {
213
+ payoutAmount = totalAvailable;
214
+ } else {
215
+ payoutAmount = lossBN;
216
+ }
217
+
218
+ // Debit funds from available balances until the payout is covered.
219
+ let remaining = payoutAmount.abs();
220
+ for (const balance of this.balances) {
221
+ if (remaining.isLessThanOrEqualTo(0)) break;
222
+ const availableBN = new BigNumber(balance.amountAvailable);
223
+ if (availableBN.gt(0)) {
224
+ const debit = BigNumber.minimum(availableBN, remaining);
225
+ // Update the balance with strict 8-decimal precision.
226
+ balance.amountAvailable = availableBN.minus(debit).decimalPlaces(8).toNumber();
227
+ remaining = remaining.minus(debit);
228
+ }
229
+ }
230
+ console.log('payout: '+payoutAmount+' '+payoutAmount.decimalPlaces(8).toNumber())
231
+ if (remaining.gt(0)) {
232
+ // Not enough funds available—this is a deficit.
233
+ console.error(`Insurance fund insufficient: deficit of ${remaining.decimalPlaces(8).toNumber()} tokens`);
234
+ await this.handleDeficit(remaining.decimalPlaces(8).toNumber());
235
+ }
236
+
237
+ // Build the payout event record. Note that we include the block and enforce 8‑decimal precision.
238
+ const payoutEvent = {
239
+ type: "payout",
240
+ contractId: this.contractSeriesId,
241
+ block,
242
+ totalLoss: lossBN.decimalPlaces(8).toNumber(),
243
+ payoutAmount: payoutAmount.decimalPlaces(8).toNumber(),
244
+ timestamp: new Date().toISOString()
245
+ };
246
+
247
+ // Get the insurance DB instance.
248
+ const dbInstance = await db.getDatabase("insurance");
249
+
250
+ // Save the payout event under a dedicated key.
251
+ const payoutKey = `payout-${this.contractSeriesId}-${block}`;
252
+ await dbInstance.insertAsync({ key: payoutKey, value: payoutEvent });
253
+
254
+ // Also record the event with the standard recordEvent method.
255
+ await this.recordEvent("payout", {
256
+ contractId: this.contractSeriesId,
257
+ block,
258
+ totalLoss: lossBN.decimalPlaces(8).toNumber(),
259
+ payoutAmount: payoutAmount.decimalPlaces(8).toNumber()
260
+ });
261
+
262
+ // Save the updated snapshot to reflect the debited funds.
263
+ await this.saveSnapshot();
264
+
265
+ return payoutAmount.decimalPlaces(8)
266
+
267
+ }
268
+
269
+ static async getTotalBalanceForProperty(propertyId) {
270
+ const dbInstance = await db.getDatabase("insurance");
271
+ const insuranceEntries = await dbInstance.findAsync({}); // Fetch all insurance entries
272
+
273
+ let totalBalance = new BigNumber(0);
274
+ console.log(`🔍 Calculating total insurance balance for propertyId: ${propertyId}`);
275
+ let matchCount = 0;
276
+
277
+ for (const entry of insuranceEntries) {
278
+ if (entry.value && entry.value.balances) {
279
+ for (const balance of entry.value.balances) {
280
+ if (String(balance.propertyId) === String(propertyId)) {
281
+ matchCount++;
282
+ const amount = new BigNumber(balance.amountAvailable || 0);
283
+ console.log(`✅ Found balance for ${entry.key || entry._id}: +${amount.toFixed(8)}`);
284
+ totalBalance = totalBalance.plus(amount);
285
+ }
286
+ }
287
+ } else {
288
+ }
289
+ }
290
+
291
+ console.log(`📊 Total balance for property ${propertyId}: ${totalBalance.toFixed(8)} from ${matchCount} entries`);
292
+ return totalBalance;
293
+ }
294
+
295
+
296
+ /** 🔄 Updates a centralized summary of insurance balances by propertyId */
297
+ static async updateInsuranceSummary() {
298
+ const dbInstance = await db.getDatabase("insurance");
299
+
300
+ // Fetch all insurance fund entries
301
+ const insuranceEntries = await dbInstance.findAsync({});
302
+
303
+ let insuranceSummary = {};
304
+
305
+ for (const entry of insuranceEntries) {
306
+ if (entry.value && entry.value.balances) {
307
+ for (const balance of entry.value.balances) {
308
+ const propertyId = balance.propertyId;
309
+ const amountAvailable = new BigNumber(balance.amountAvailable || 0);
310
+
311
+ if (!insuranceSummary[propertyId]) {
312
+ insuranceSummary[propertyId] = new BigNumber(0);
313
+ }
314
+
315
+ insuranceSummary[propertyId] = insuranceSummary[propertyId].plus(amountAvailable);
316
+ }
317
+ }
318
+ }
319
+
320
+ // Convert BigNumber values to standard numbers before storing
321
+ const summaryToStore = Object.fromEntries(
322
+ Object.entries(insuranceSummary).map(([propertyId, total]) => [propertyId, total.toFixed(8)])
323
+ );
324
+
325
+ console.log("📌 Updated insuranceSummary:", summaryToStore);
326
+
327
+ // Store the summary in the insurance database
328
+ await dbInstance.updateAsync(
329
+ { _id: "insuranceSummary" },
330
+ { $set: { totals: summaryToStore } },
331
+ { upsert: true }
332
+ );
333
+ }
334
+
335
+ static async getInsuranceFundBalance(propertyId) {
336
+ const base = await db.getDatabase('insurance');
337
+ const insuranceEntry = await base.findOneAsync({ _id: propertyId });
338
+
339
+ if (insuranceEntry) {
340
+ return new BigNumber(insuranceEntry.amount);
341
+ } else {
342
+ return new BigNumber(0);
343
+ }
344
+ }
345
+ }
346
+
347
+ module.exports = InsuranceFund;
@@ -0,0 +1,218 @@
1
+ const fs = require('fs');
2
+ const stream = require('stream');
3
+ const { promisify } = require('util');
4
+ const pipeline = promisify(stream.pipeline);
5
+
6
+ // Import all necessary modules
7
+ const TradeLayerManager = require('./vesting.js');
8
+ const Persistence = require('./persistence.js');
9
+ const Orderbook = require('./orderbook.js');
10
+ const InsuranceFund = require('./insurance.js');
11
+ //const VolumeIndex = require('./VolumeIndex.js');
12
+ const TxIndex = require('./txIndex.js');
13
+ const ReOrgChecker = require('./reOrg.js');
14
+ const Validity = require('./validity.js');
15
+ const TxUtils = require('./txUtils.js');
16
+ const TradeChannel = require('./channels.js');
17
+ const TallyMap = require('./tally.js');
18
+ const MarginMap = require('./marginMap.js');
19
+ const PropertyManager = require('./property.js');
20
+ const ContractsRegistry = require('./contractRegistry.js');
21
+ const Consensus = require('./consensus.js');
22
+ const Encode = require('./txEncoder.js');
23
+ const Types = require('./types.js');
24
+ const Decode = require('./txDecoder.js');
25
+ const Clearing = require('./clearing.js');
26
+
27
+ class Interface {
28
+ constructor() {
29
+ // Singleton instances or references to the modules can be set up here if necessary
30
+ //this.tallyMap = TallyMap.getInstance();
31
+ }
32
+
33
+ async JSONAuditTallyMap() {
34
+ await TallyMap.load(); // Load the TallyMap
35
+ const tallyMapData = TallyMap.getTallyMapData();
36
+ const tallyMapStream = this.createReadableStreamFromIterable(tallyMapData);
37
+ const writableStream = fs.createWriteStream('tallyMapAudit.json');
38
+
39
+ try {
40
+ await pipeline(
41
+ tallyMapStream,
42
+ writableStream
43
+ );
44
+ console.log('Tally map audit saved to tallyMapAudit.json');
45
+ } catch (error) {
46
+ console.error('Error streaming tally map to file:', error);
47
+ }
48
+ }
49
+
50
+ createReadableStreamFromIterable(iterable) {
51
+ const iterator = iterable[Symbol.iterator]();
52
+ return new stream.Readable({
53
+ objectMode: true,
54
+ read() {
55
+ const { value, done } = iterator.next();
56
+ if (done) {
57
+ this.push(null);
58
+ } else {
59
+ this.push(JSON.stringify(value, null, 4) + '\n');
60
+ }
61
+ }
62
+ });
63
+ }
64
+
65
+ async getConsensusHashForBlock(blockHeight) {
66
+ return await Consensus.getData(`consensusHash_${blockHeight}`);
67
+ }
68
+
69
+ async getFeatureActivationStatus(featureId) {
70
+ return TradeLayerManager.isTxTypeActive(featureId) ? { status: 'active' } : { status: 'inactive', message: `Feature ID ${featureId} not found or not active.` };
71
+ }
72
+
73
+ async getAllBalancesForAddress(address) {
74
+ return await TallyMap.getAddressBalances(address);
75
+ }
76
+
77
+ getTotalTokens(propertyId) {
78
+ return TallyMap.totalTokens(propertyId);
79
+ }
80
+
81
+ async getBalancesAcrossAllWallets() {
82
+ // Assuming a function in TradeLayerManager to get all wallet balances
83
+ return TradeLayerManager.getAllBalances();
84
+ }
85
+
86
+ async isTransactionTypeActive(txType) {
87
+ return TradeLayerManager.isTxTypeActive(txType);
88
+ }
89
+
90
+ async getAllActiveTransactionTypes() {
91
+ return TradeLayerManager.getActiveTransactionTypes();
92
+ }
93
+
94
+ async getAddressesWithBalanceForProperty(propertyId) {
95
+ return await TallyMap.getAddressesWithBalanceForProperty(propertyId);
96
+ }
97
+
98
+ async getTransaction(txid) {
99
+ return await TxIndex.getTransactionDetails(txid);
100
+ }
101
+
102
+ async getProperty(propertyId) {
103
+ return await PropertyManager.getPropertyDetails(propertyId);
104
+ }
105
+
106
+ async listProperties() {
107
+ return await PropertyManager.getAllProperties();
108
+ }
109
+
110
+ async getGrants(propertyId) {
111
+ return await PropertyManager.getPropertyGrants(propertyId);
112
+ }
113
+
114
+ async getPayToToken(propertyId) {
115
+ return await TxUtils.getPayToTokenTransactions(propertyId);
116
+ }
117
+
118
+ async listBlockTransactions(blockIndex) {
119
+ return await BlockHistory.getBlockTransactions(blockIndex);
120
+ }
121
+
122
+ async listBlocksTransactions(firstBlock, lastBlock) {
123
+ return await BlockHistory.getTransactionsInRange(firstBlock, lastBlock);
124
+ }
125
+
126
+ async listPendingTransactions(addressFilter = '') {
127
+ return await TxUtils.getPendingTransactions(addressFilter);
128
+ }
129
+
130
+ async getBalancesAcrossAllWallets() {
131
+ // Assuming WalletCache provides a method to get all balances across wallets
132
+ return await WalletCache.getAllBalances();
133
+ }
134
+
135
+ // Add other wallet-related methods as needed...
136
+ // For example, a method to update the wallet cache
137
+ async updateWalletCache() {
138
+ await WalletCache.updateCache();
139
+ return 'Wallet cache updated';
140
+ }
141
+
142
+ async listOracles() {
143
+ // Assuming a method in the OracleManager module that lists all oracles
144
+ return await OracleManager.listAllOracles();
145
+ }
146
+
147
+ /**
148
+ * Retrieves a list of all whitelists.
149
+ */
150
+ async listWhitelists() {
151
+ // Assuming a method in the WhitelistManager module that lists all whitelists
152
+ return await WhitelistManager.listAllWhitelists();
153
+ }
154
+
155
+ /**
156
+ * Retrieves a list of vaults for a given synthetic property ID.
157
+ * @param {number} propertyId - The synthetic property ID.
158
+ */
159
+ async listVaultsBySyntheticProperty(propertyId) {
160
+ // Assuming a method in the VaultManager module that lists vaults by property ID
161
+ return await VaultManager.listVaultsForProperty(propertyId);
162
+ }
163
+
164
+ /**
165
+ * Retrieves options chains by series ID.
166
+ * @param {number} seriesId - The series ID.
167
+ */
168
+ async getOptionsChainBySeriesId(seriesId) {
169
+ // Assuming a method in the OptionsChainManager module that gets an options chain by series ID
170
+ return await OptionsChainManager.getOptionsChain(seriesId);
171
+ }
172
+
173
+ /**
174
+ * Retrieves the balance of the insurance fund for a given contract ID.
175
+ * @param {number} contractId - The contract ID.
176
+ */
177
+ async getInsuranceFundBalance(contractId) {
178
+ // Assuming a method in the InsuranceFund module that retrieves the balance for a specific contract
179
+ return await InsuranceFund.getBalanceForContract(contractId);
180
+ }
181
+
182
+ /**
183
+ * Retrieves the insurance fund payout history for a given contract ID between specified blocks.
184
+ * If endBlock is not provided, it defaults to the latest block height.
185
+ * @param {number} contractId - The contract ID.
186
+ * @param {number} startBlock - The starting block number.
187
+ * @param {number|null} endBlock - The ending block number (defaults to the latest block).
188
+ */
189
+ async getInsuranceFundPayoutHistory(contractId, startBlock, endBlock = null) {
190
+ if (endBlock === null) {
191
+ // Assuming a method in a suitable module (e.g., BlockChainInfo) that retrieves the latest block height
192
+ endBlock = await BlockChainInfo.getLatestBlockHeight();
193
+ }
194
+
195
+ // Assuming a method in the InsuranceFund module that retrieves the payout history
196
+ return await InsuranceFund.getPayoutHistoryForContract(contractId, startBlock, endBlock);
197
+ }
198
+
199
+ /**
200
+ * Retrieves audit data for a specific block and contract.
201
+ * @param {number} blockHeight - The block height for which to retrieve audit data.
202
+ * @param {number} contractId - The contract ID to focus on.
203
+ * @returns {Promise<Object>} - The audit data, or an error if not found.
204
+ */
205
+ async getAuditData(blockHeight, contractId) {
206
+ try {
207
+ const auditDataKey = `contract-${contractId}-block-${blockHeight}`;
208
+ const auditData = await this.clearing.fetchAuditData(auditDataKey);
209
+ return auditData;
210
+ } catch (error) {
211
+ console.error('Error retrieving audit data:', error);
212
+ throw error; // Or handle it more gracefully depending on your application's needs
213
+ }
214
+ }
215
+
216
+ }
217
+
218
+ module.exports = Interface;