@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.
- package/.claude/settings.local.json +13 -0
- package/.claude/skills/tl-algo/SKILL.md +255 -0
- package/.gitattributes +2 -0
- package/.github/workflows/publish.yaml +26 -0
- package/4mm.js +163 -0
- package/LICENSE +21 -0
- package/NPMSwapRefactor.zip +0 -0
- package/README.md +217 -0
- package/address.sh +26 -0
- package/algoAPI.js +581 -0
- package/analyzepsbt.js +92 -0
- package/apiEx.js +99 -0
- package/bb_hyperscalper.js +290 -0
- package/bbo_demo.js +111 -0
- package/buyer.js +622 -0
- package/client.js +50 -0
- package/createTxTest.js +26 -0
- package/createWallet.js +75 -0
- package/daytrader.js +531 -0
- package/decodeTest.js +69 -0
- package/fundingManager.js +144 -0
- package/index.js +4 -0
- package/listener.js +27 -0
- package/litecoreTxBuilder.js +1128 -0
- package/mmEx.js +356 -0
- package/networks.js +51 -0
- package/orderbook.js +200 -0
- package/package.json +34 -0
- package/perTradeQueue.js +36 -0
- package/projectsTLNPMTLNPM/package-lock.json +162 -0
- package/projectsTLNPMTLNPM/package.json +5 -0
- package/quick.js +32 -0
- package/quickFut.js +37 -0
- package/quickSell.js +37 -0
- package/relayerClient.js +117 -0
- package/run4mm.js +80 -0
- package/run_bbo_tracker.js +241 -0
- package/seller.js +443 -0
- package/session.js +45 -0
- package/setup-lin-ltc.sh +139 -0
- package/setup-lin.sh +203 -0
- package/setup-win-ltc.bat +108 -0
- package/setup-win.bat +167 -0
- package/spam_screamer_futures.js +222 -0
- package/tradelayer.js/.gitattributes +2 -0
- package/tradelayer.js/README.md +2 -0
- package/tradelayer.js/oldTests/activationTest.js +6 -0
- package/tradelayer.js/oldTests/base58.test.js +23 -0
- package/tradelayer.js/oldTests/base64Decode.test.js +16 -0
- package/tradelayer.js/oldTests/blocksRefactor.js +140 -0
- package/tradelayer.js/oldTests/checkVestBalance.js +25 -0
- package/tradelayer.js/oldTests/consensusHashProto.js +151 -0
- package/tradelayer.js/oldTests/contractOrderbook.js +243 -0
- package/tradelayer.js/oldTests/createPayload.js +0 -0
- package/tradelayer.js/oldTests/createTestnetAddr.js +43 -0
- package/tradelayer.js/oldTests/decode.js +205 -0
- package/tradelayer.js/oldTests/decodeTest.js +50 -0
- package/tradelayer.js/oldTests/displayTallyMap.js +19 -0
- package/tradelayer.js/oldTests/encodeDecode.js +340 -0
- package/tradelayer.js/oldTests/expressTest.js +29 -0
- package/tradelayer.js/oldTests/extractBlocksVanilla.js +214 -0
- package/tradelayer.js/oldTests/extractBlocksVanillaa.js +179 -0
- package/tradelayer.js/oldTests/extractPubkeyTest.js +60 -0
- package/tradelayer.js/oldTests/fillInputCacheProto.js +111 -0
- package/tradelayer.js/oldTests/getRawTxTest.js +22 -0
- package/tradelayer.js/oldTests/indexTest.js +26 -0
- package/tradelayer.js/oldTests/initTokensTest.js +32 -0
- package/tradelayer.js/oldTests/interfaceChild.js +129 -0
- package/tradelayer.js/oldTests/listenerChild.js +112 -0
- package/tradelayer.js/oldTests/opdecode.js +26 -0
- package/tradelayer.js/oldTests/options.js +79 -0
- package/tradelayer.js/oldTests/optxtest.js +116 -0
- package/tradelayer.js/oldTests/optxtest1.js +64 -0
- package/tradelayer.js/oldTests/oracle.test.js +32 -0
- package/tradelayer.js/oldTests/orderbook.test.js +36 -0
- package/tradelayer.js/oldTests/parsing.js +93 -0
- package/tradelayer.js/oldTests/payload.js +13 -0
- package/tradelayer.js/oldTests/persistenceUnitTest.js +23 -0
- package/tradelayer.js/oldTests/property.test.js +53 -0
- package/tradelayer.js/oldTests/propertyLevel.js +75 -0
- package/tradelayer.js/oldTests/propertyTest.js +32 -0
- package/tradelayer.js/oldTests/queryAddressTest.js +17 -0
- package/tradelayer.js/oldTests/salter.js +14 -0
- package/tradelayer.js/oldTests/tally.js +81 -0
- package/tradelayer.js/oldTests/tally.test.js +48 -0
- package/tradelayer.js/oldTests/tally2.js +124 -0
- package/tradelayer.js/oldTests/tally3.js +142 -0
- package/tradelayer.js/oldTests/tallyDiag.js +38 -0
- package/tradelayer.js/oldTests/testGetRaw.js +40 -0
- package/tradelayer.js/oldTests/testHexConvert.js +47 -0
- package/tradelayer.js/oldTests/testNewEncoding.js +96 -0
- package/tradelayer.js/oldTests/testNewEncoding2.js +113 -0
- package/tradelayer.js/oldTests/testNewEncoding3 +112 -0
- package/tradelayer.js/oldTests/testNewEncoding3.js +168 -0
- package/tradelayer.js/oldTests/testOPReturn.js +102 -0
- package/tradelayer.js/oldTests/testPayload.js +23 -0
- package/tradelayer.js/oldTests/testRaw.js +50 -0
- package/tradelayer.js/oldTests/testSendTooMuch.js +20 -0
- package/tradelayer.js/oldTests/testTxBuild +28 -0
- package/tradelayer.js/oldTests/testTxBuild.js +42 -0
- package/tradelayer.js/oldTests/tokenOrderbook.js +243 -0
- package/tradelayer.js/oldTests/txUtilsA.js +515 -0
- package/tradelayer.js/oldTests/validityUnitTest.js +53 -0
- package/tradelayer.js/oldTests/vaults.js +72 -0
- package/tradelayer.js/oldTests/volumeIndex.js +117 -0
- package/tradelayer.js/oldTests/volumeIndex2.js +88 -0
- package/tradelayer.js/output_base64.txt +1 -0
- package/tradelayer.js/package-lock.json +9967 -0
- package/tradelayer.js/package.json +61 -0
- package/tradelayer.js/server/index.js +88 -0
- package/tradelayer.js/server/litecoind.exe +0 -0
- package/tradelayer.js/src/activation.js +303 -0
- package/tradelayer.js/src/adjuster.js +77 -0
- package/tradelayer.js/src/amm.js +400 -0
- package/tradelayer.js/src/base256.js +55 -0
- package/tradelayer.js/src/base94.js +79 -0
- package/tradelayer.js/src/channels.js +1163 -0
- package/tradelayer.js/src/clearing.js +3109 -0
- package/tradelayer.js/src/clearlist.js +364 -0
- package/tradelayer.js/src/client.js +295 -0
- package/tradelayer.js/src/consensus.js +613 -0
- package/tradelayer.js/src/contractRegistry.js +964 -0
- package/tradelayer.js/src/db.js +89 -0
- package/tradelayer.js/src/init.js +24 -0
- package/tradelayer.js/src/insurance.js +347 -0
- package/tradelayer.js/src/interface.js +218 -0
- package/tradelayer.js/src/interfaceExpress.js +178 -0
- package/tradelayer.js/src/iou.js +509 -0
- package/tradelayer.js/src/listener.js +226 -0
- package/tradelayer.js/src/logic.js +1702 -0
- package/tradelayer.js/src/main.js +927 -0
- package/tradelayer.js/src/marginMap.js +2165 -0
- package/tradelayer.js/src/options.js +126 -0
- package/tradelayer.js/src/oracle.js +394 -0
- package/tradelayer.js/src/orderbook.js +4123 -0
- package/tradelayer.js/src/persistence.js +554 -0
- package/tradelayer.js/src/property.js +411 -0
- package/tradelayer.js/src/reOrg.js +41 -0
- package/tradelayer.js/src/scaling.js +145 -0
- package/tradelayer.js/src/tally.js +1275 -0
- package/tradelayer.js/src/tradeHistoryManager.js +552 -0
- package/tradelayer.js/src/txDecoder.js +584 -0
- package/tradelayer.js/src/txEncoder.js +610 -0
- package/tradelayer.js/src/txIndex.js +502 -0
- package/tradelayer.js/src/txUtils.js +1392 -0
- package/tradelayer.js/src/types.js +429 -0
- package/tradelayer.js/src/validity.js +3077 -0
- package/tradelayer.js/src/vaults.js +430 -0
- package/tradelayer.js/src/vesting.js +491 -0
- package/tradelayer.js/src/volumeIndex.js +618 -0
- package/tradelayer.js/src/walletInterface.js +220 -0
- package/tradelayer.js/src/walletListener.js +665 -0
- package/tradelayer.js/tests/256decode.js +82 -0
- package/tradelayer.js/tests/UTXOracle.js +205 -0
- package/tradelayer.js/tests/base94test.js +23 -0
- package/tradelayer.js/tests/cancelTxTest.js +62 -0
- package/tradelayer.js/tests/contractInterfaceTest.js +48 -0
- package/tradelayer.js/tests/decimalTest.js +65 -0
- package/tradelayer.js/tests/decoderTest.js +100 -0
- package/tradelayer.js/tests/deltaCount.js +47 -0
- package/tradelayer.js/tests/deltaCount2.js +60 -0
- package/tradelayer.js/tests/interfaceTest.js +37 -0
- package/tradelayer.js/tests/mainTest.js +53 -0
- package/tradelayer.js/tests/makeActivationTest.js +24 -0
- package/tradelayer.js/tests/maxHeightTest.js +49 -0
- package/tradelayer.js/tests/reverseHash.js +72 -0
- package/tradelayer.js/tests/sensitiveConsoleOutput.txt +267 -0
- package/tradelayer.js/tests/tallyTest.js +40 -0
- package/tradelayer.js/tests/testBuybacks.js +46 -0
- package/tradelayer.js/tests/testCodeHash.js +49 -0
- package/tradelayer.js/tests/testConsensusHash.js +91 -0
- package/tradelayer.js/tests/testDecode.js +30 -0
- package/tradelayer.js/tests/testEncodingLengths.js +129 -0
- package/tradelayer.js/tests/testGetTx +32 -0
- package/tradelayer.js/tests/testGetTx.js +32 -0
- package/tradelayer.js/tests/testHexHash.js +32 -0
- package/tradelayer.js/tests/testIndexHash.js +35 -0
- package/tradelayer.js/tests/testInitContracts.js +38 -0
- package/tradelayer.js/tests/testMaxConsensus.js +12 -0
- package/tradelayer.js/tests/testMaxSynth.js +44 -0
- package/tradelayer.js/tests/testMint.js +21 -0
- package/tradelayer.js/tests/testNetwork.js +33 -0
- package/tradelayer.js/tests/testOrderbookLoad.js +62 -0
- package/tradelayer.js/tests/testRebates.js +32 -0
- package/tradelayer.js/tests/testRedeem.js +22 -0
- package/tradelayer.js/tests/testTokenTrade.js +39 -0
- package/tradelayer.js/tests/testTxBuild.js +42 -0
- package/tradelayer.js/tests/testUTXOTrade.js +27 -0
- package/tradelayer.js/tests/tokenTradeHistory.js +27 -0
- package/tradelayer.js/tests/tradeFutures.js +40 -0
- package/tradelayer.js/tests/tradeHistoryExample.js +35 -0
- package/tradelayer.js/tests/tradeHistoryLoad.js +15 -0
- package/tradelayer.js/tests/txScanTest.js +134 -0
- package/tradelayer.js/tests/validateTest.js +136 -0
- package/tradelayer.js/tests/vestingTest.js +37 -0
- package/tradelayer.js/utils/activateMainnet.js +59 -0
- package/tradelayer.js/utils/activateMainnetDoge.js +63 -0
- package/tradelayer.js/utils/autocompactdb.js +23 -0
- package/tradelayer.js/utils/base64toHex.js +32 -0
- package/tradelayer.js/utils/broadcastDoge.js +38 -0
- package/tradelayer.js/utils/calcRedeem.js +19 -0
- package/tradelayer.js/utils/checkNetwork.js +27 -0
- package/tradelayer.js/utils/createAddress.js +48 -0
- package/tradelayer.js/utils/createAttestation.js +133 -0
- package/tradelayer.js/utils/createContract.js +118 -0
- package/tradelayer.js/utils/createOracle.js +94 -0
- package/tradelayer.js/utils/createwallet.js +20 -0
- package/tradelayer.js/utils/crossFuturesTrades.js +57 -0
- package/tradelayer.js/utils/crossTokenTrades.js +62 -0
- package/tradelayer.js/utils/dumpPriv.js +29 -0
- package/tradelayer.js/utils/generateChannel.js +34 -0
- package/tradelayer.js/utils/getInfo.js +21 -0
- package/tradelayer.js/utils/hardWipe.js +20 -0
- package/tradelayer.js/utils/hexTo64.js +16 -0
- package/tradelayer.js/utils/importAddress.js +28 -0
- package/tradelayer.js/utils/importpriv.js +20 -0
- package/tradelayer.js/utils/issueOracleContract.js +67 -0
- package/tradelayer.js/utils/issueTokens.js +41 -0
- package/tradelayer.js/utils/listunspent.js +66 -0
- package/tradelayer.js/utils/litecoinClient.js +30 -0
- package/tradelayer.js/utils/loadwallet.js +20 -0
- package/tradelayer.js/utils/publishOracle.js +113 -0
- package/tradelayer.js/utils/sendActivation.js +21 -0
- package/tradelayer.js/utils/sendChannelContractTrade.js +34 -0
- package/tradelayer.js/utils/sendChannelTokenTrade.js +34 -0
- package/tradelayer.js/utils/sendCommit.js +24 -0
- package/tradelayer.js/utils/sendDoge.js +62 -0
- package/tradelayer.js/utils/sendDogeMain.js +67 -0
- package/tradelayer.js/utils/sendDogeTx.js +46 -0
- package/tradelayer.js/utils/sendLTC.js +63 -0
- package/tradelayer.js/utils/sendMainnet.js +62 -0
- package/tradelayer.js/utils/sendTransfer.js +19 -0
- package/tradelayer.js/utils/sendVestTest.js +88 -0
- package/tradelayer.js/utils/sendWithdrawal.js +26 -0
- package/tradelayer.js/utils/simpleStart.js +8 -0
- package/tradelayer.js/utils/startStop.js +27 -0
- package/tradelayer.js/utils/structuredTrades.js +136 -0
- package/tradelayer.js/utils/verifySignature.js +90 -0
- package/tradelayer.js/utils/verifyWitnessAndScriptPubkey.js +41 -0
- package/tradelayer.js/utils/walletCache.js +172 -0
- package/tradelayer.js/utils/walletContractInterface.js +48 -0
- package/tradelayer.js/utils/walletFetchTxs.js +66 -0
- package/tradelayer.js/utils/walletUtils.js +97 -0
- package/tradelayer.js/utils/wipeDB.js +55 -0
- package/tradelayer.js/utils/wipeDBNotTx.js +50 -0
- package/txEncoder.js +529 -0
- package/utility.js +28 -0
- package/verifymessage.js +38 -0
- package/ws-transport.js +311 -0
|
@@ -0,0 +1,618 @@
|
|
|
1
|
+
const fetch = require('node-fetch'); // For HTTP requests (e.g., price lookups)
|
|
2
|
+
const db = require('./db.js')
|
|
3
|
+
const Litecoin = require('litecoin')
|
|
4
|
+
const util = require('util')
|
|
5
|
+
const Contracts = require('./contractRegistry.js')
|
|
6
|
+
const BigNumber = require('bignumber.js');
|
|
7
|
+
|
|
8
|
+
class VolumeIndex {
|
|
9
|
+
constructor(db) {
|
|
10
|
+
// Initialize data structures and database path
|
|
11
|
+
this.pairVolumes = {};
|
|
12
|
+
this.pairFees = {};
|
|
13
|
+
this.tokenPairCumulativeVolumes = 0;
|
|
14
|
+
this.ltcPairTotalVolume = 0;
|
|
15
|
+
this.contractCumulativeVolumes = 0;
|
|
16
|
+
this.cumulativeFees = 0;
|
|
17
|
+
this.dbPath = dbPath;
|
|
18
|
+
this.VWAPIndex = new Map()
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static async saveVolumeDataById(id, rawVolume,ltcVolume, price,blockHeight, type) {
|
|
22
|
+
console.log('saving volume index data '+id, typeof id, rawVolume, ltcVolume, price, blockHeight, type)
|
|
23
|
+
const base = await db.getDatabase('volumeIndex')
|
|
24
|
+
await base.updateAsync(
|
|
25
|
+
{ _id: id },
|
|
26
|
+
{ _id: id, value: { blockHeight:blockHeight, rawVolume: rawVolume, ltcVolume: ltcVolume, price:price, type } },
|
|
27
|
+
{ upsert: true }
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
// Update global cumulative volume variables
|
|
31
|
+
await VolumeIndex.updateCumulativeVolumes(ltcVolume, type,id,blockHeight);
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static async getUTXOEquivalentVolume(volume, id, type,collateralId, notionalValue,inverse,price){
|
|
36
|
+
console.log('inside get getUTXOEquivalentVolume '+type+collateralId+notionalValue+inverse)
|
|
37
|
+
if(type === "contract"&&collateralId&¬ionalValue&&inverse!==undefined){
|
|
38
|
+
const priceInLTC = await this.getTokenPriceInLTC(collateralId);
|
|
39
|
+
console.log('price in ltc for collateral '+collateralId+ ' '+priceInLTC+' trade price '+price+' volume '+volume)
|
|
40
|
+
const ltcPriceBN = new BigNumber(priceInLTC)
|
|
41
|
+
const volumeBN = new BigNumber(volume)
|
|
42
|
+
const tradePriceBN = new BigNumber(price)
|
|
43
|
+
const notionalBN = new BigNumber(notionalValue)
|
|
44
|
+
let volumeInLTC = volumeBN.times(ltcPriceBN).times(notionalBN)
|
|
45
|
+
if(inverse==false){
|
|
46
|
+
volumeInLTC = volumeInLTC.times(tradePriceBN)
|
|
47
|
+
}
|
|
48
|
+
console.log('result '+volumeInLTC.decimalPlaces(8).toNumber())
|
|
49
|
+
return volumeInLTC.decimalPlaces(8).toNumber()
|
|
50
|
+
}else if (type === "token") {
|
|
51
|
+
const [tokenId1, tokenId2] = id.split('-');
|
|
52
|
+
console.log('checking ids ' +tokenId1, tokenId2)
|
|
53
|
+
const priceInLTC1 = await this.getTokenPriceInLTC(tokenId1);
|
|
54
|
+
const priceInLTC2 = await this.getTokenPriceInLTC(tokenId2);
|
|
55
|
+
console.log('LTC prices of the tokens'+priceInLTC1, priceInLTC2)
|
|
56
|
+
const volumeInLTC = priceInLTC1*volume[0] + priceInLTC2*volume[1]
|
|
57
|
+
return volumeInLTC
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static async updateCumulativeVolumes(volume, type, id, block) {
|
|
62
|
+
// load existing totals, guard nulls
|
|
63
|
+
|
|
64
|
+
const base = await db.getDatabase('volumeIndex');
|
|
65
|
+
const globalDoc = await base.findOneAsync({ _id: 'globalCumulativeVolume' }) || { value: { globalCumulativeVolume: 0 }};
|
|
66
|
+
const ltcDoc = await base.findOneAsync({ _id: 'ltcPairCumulativeVolume' }) || { value: { ltcPairTotalVolume: 0 }};
|
|
67
|
+
|
|
68
|
+
const globalCumulativeVolume = globalDoc.value.globalCumulativeVolume
|
|
69
|
+
const ltcPairTotalVolume = ltcDoc.value.ltcPairTotalVolume
|
|
70
|
+
|
|
71
|
+
console.log('inside updateCumulativeVolumes '+JSON.stringify(globalDoc)+' '+JSON.stringify(ltcDoc))
|
|
72
|
+
const BNGlobal = new BigNumber(globalCumulativeVolume || 0);
|
|
73
|
+
const BNltc = new BigNumber(ltcPairTotalVolume || 0);
|
|
74
|
+
const BNVol = new BigNumber(volume || 0);
|
|
75
|
+
|
|
76
|
+
// global always increments
|
|
77
|
+
const newGlobal = BNVol.plus(BNGlobal).decimalPlaces(8).toNumber();
|
|
78
|
+
|
|
79
|
+
// ltc pair increments only if type === "UTXO"
|
|
80
|
+
let newLtcPair = BNltc.toNumber();
|
|
81
|
+
if (type === "UTXO") {
|
|
82
|
+
newLtcPair = BNVol.plus(BNltc).decimalPlaces(8).toNumber();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
await base.updateAsync(
|
|
86
|
+
{ _id: 'ltcPairCumulativeVolume' },
|
|
87
|
+
{ _id: 'ltcPairCumulativeVolume', value: { ltcPairTotalVolume: newLtcPair, block } },
|
|
88
|
+
{ upsert: true }
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
await base.updateAsync(
|
|
92
|
+
{ _id: 'globalCumulativeVolume' },
|
|
93
|
+
{ _id: 'globalCumulativeVolume', value: { globalCumulativeVolume: newGlobal, block } },
|
|
94
|
+
{ upsert: true }
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
static async getTokenPriceInLTC(tokenId) {
|
|
102
|
+
// Attempt to fetch the VWAP price from the database
|
|
103
|
+
const base = await db.getDatabase('volumeIndex')
|
|
104
|
+
const vwapData = await base.findOneAsync({ _id: `0-${tokenId}` });
|
|
105
|
+
console.log('get token LTC price '+JSON.stringify(vwapData))
|
|
106
|
+
if (vwapData && vwapData.value && vwapData.value.price) {
|
|
107
|
+
return vwapData.value.price;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// If VWAP price is not available, return a default low value
|
|
111
|
+
return 0.001; // Minimum price
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
static async calculateVolIndex(lookbackBlocks = 14400) {
|
|
115
|
+
const base = await db.getDatabase('volumeIndex');
|
|
116
|
+
const docs = await base.findAsync({}).sort({ 'value.blockHeight': -1 }).limit(lookbackBlocks);
|
|
117
|
+
|
|
118
|
+
if (!docs || docs.length < 2) {
|
|
119
|
+
return 0;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Collect log returns
|
|
123
|
+
let prices = docs.map(d => d.value.price).filter(p => p > 0);
|
|
124
|
+
let logReturns = [];
|
|
125
|
+
for (let i = 1; i < prices.length; i++) {
|
|
126
|
+
logReturns.push(Math.log(prices[i] / prices[i-1]));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Standard deviation of log returns
|
|
130
|
+
const mean = logReturns.reduce((a,b) => a+b, 0) / logReturns.length;
|
|
131
|
+
const variance = logReturns.reduce((a,b) => a + Math.pow(b-mean,2), 0) / (logReturns.length-1);
|
|
132
|
+
const stdev = Math.sqrt(variance);
|
|
133
|
+
|
|
134
|
+
// Annualize (assuming 144 blocks ≈ 1 day)
|
|
135
|
+
const blocksPerYear = 144 * 365;
|
|
136
|
+
const volIndex = stdev * Math.sqrt(blocksPerYear);
|
|
137
|
+
|
|
138
|
+
// Save volIndex in db
|
|
139
|
+
await base.updateAsync(
|
|
140
|
+
{ _id: 'volIndex' },
|
|
141
|
+
{ _id: 'volIndex', value: { vol: volIndex, updatedAt: Date.now() } },
|
|
142
|
+
{ upsert: true }
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
return volIndex;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Normalize ContractRegistry.getContractInfo(contractId) into a flat shape.
|
|
152
|
+
* Accepts either { data: {...} } or a flat object.
|
|
153
|
+
*/
|
|
154
|
+
static async _normalizeContractInfo(contractId) {
|
|
155
|
+
const Contracts = require('./contractRegistry.js')
|
|
156
|
+
const raw = await Contracts.getContractInfo(contractId);
|
|
157
|
+
const d = (raw && raw.data) ? raw.data : (raw || {});
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
contractId: d.id ?? raw?.id ?? contractId,
|
|
161
|
+
ticker: d.ticker,
|
|
162
|
+
native: !!d.native,
|
|
163
|
+
inverse: !!d.inverse,
|
|
164
|
+
// definitive fields from your sample
|
|
165
|
+
notionalPropertyId: d.notionalPropertyId ?? 0, // 0 => LTC
|
|
166
|
+
notionalValue: Number(d.notionalValue ?? 1),
|
|
167
|
+
collateralPropertyId: d.collateralPropertyId,
|
|
168
|
+
leverage: Number(d.leverage ?? 1) || 1,
|
|
169
|
+
onChainData: Array.isArray(d.onChainData) ? d.onChainData : [],
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* LTC value per 1 contract unit:
|
|
175
|
+
* ltcPerContract = (notionalValue * price(notionalPropertyId in LTC)) / leverage
|
|
176
|
+
* Handles inverse/native the same, since notional is explicit in (value, property).
|
|
177
|
+
*/
|
|
178
|
+
static async getContractUnitLTCValue(contractId) {
|
|
179
|
+
try {
|
|
180
|
+
const c = await this._normalizeContractInfo(contractId);
|
|
181
|
+
|
|
182
|
+
// Price for the notional token in LTC
|
|
183
|
+
let tokenPriceInLTC = 1;
|
|
184
|
+
if (!(c.notionalPropertyId === 0 || c.notionalPropertyId === '0' || c.notionalPropertyId === 'LTC')) {
|
|
185
|
+
tokenPriceInLTC = await this.getTokenPriceInLTC(c.notionalPropertyId);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const notionalLTC = c.notionalValue * Number(tokenPriceInLTC || 0);
|
|
189
|
+
if (!Number.isFinite(notionalLTC) || notionalLTC <= 0) return 0;
|
|
190
|
+
|
|
191
|
+
const ltcPerContract = notionalLTC / (c.leverage || 1);
|
|
192
|
+
console.log('inside LTC contract value '+ltcPerContract.toFixed(8)+' '+notionalLTC+' '+c.leverage)
|
|
193
|
+
return Number(ltcPerContract.toFixed(8));
|
|
194
|
+
} catch (e) {
|
|
195
|
+
console.error('getContractUnitLTCValue error', e);
|
|
196
|
+
return 0;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Debug/telemetry variant with all the inputs broken out.
|
|
202
|
+
*/
|
|
203
|
+
static async getContractUnitLTCValueDetails(contractId) {
|
|
204
|
+
const c = await this._normalizeContractInfo(contractId);
|
|
205
|
+
|
|
206
|
+
let tokenPriceInLTC = 1;
|
|
207
|
+
if (!(c.notionalPropertyId === 0 || c.notionalPropertyId === '0' || c.notionalPropertyId === 'LTC')) {
|
|
208
|
+
tokenPriceInLTC = await this.getTokenPriceInLTC(c.notionalPropertyId);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const notionalLTC = c.notionalValue * Number(tokenPriceInLTC || 0);
|
|
212
|
+
console.log('inside get contract unit LTC Value '+notionalLTC+' '+JSON.stringify(c))
|
|
213
|
+
const ltcPerContract = Number.isFinite(notionalLTC) && c.leverage
|
|
214
|
+
? Number((notionalLTC / c.leverage).toFixed(8))
|
|
215
|
+
: 0;
|
|
216
|
+
|
|
217
|
+
if(ltcPerContract==0){throw new Error()}
|
|
218
|
+
return ltcPerContract
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Function to get the last price for a given token pair and block height.
|
|
224
|
+
* @param {string} tokenPair - The token pair in the format "X-Y".
|
|
225
|
+
* @param {number} blockHeight - The block height to compare against.
|
|
226
|
+
* @returns {Promise<number|null>} - The last price if found, otherwise null.
|
|
227
|
+
*/
|
|
228
|
+
static async getLastPrice(tokenPair, blockHeight) {
|
|
229
|
+
try {
|
|
230
|
+
const base = await db.getDatabase('volumeIndex');
|
|
231
|
+
console.log('inside get last price ' + blockHeight);
|
|
232
|
+
|
|
233
|
+
// Try direct pair first
|
|
234
|
+
const direct = await base.findOneAsync({ _id: tokenPair });
|
|
235
|
+
|
|
236
|
+
if (direct && direct.value && direct.value.price) {
|
|
237
|
+
return direct.value.price;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// If not found, try the inverse pair
|
|
241
|
+
const [a, b] = tokenPair.split('-');
|
|
242
|
+
const inversePair = `${b}-${a}`;
|
|
243
|
+
const inverse = await base.findOneAsync({ _id: inversePair });
|
|
244
|
+
|
|
245
|
+
if (inverse && inverse.value && inverse.value.price) {
|
|
246
|
+
// invert the price for the obverse pair
|
|
247
|
+
const inverted = new BigNumber(1).div(inverse.value.price).toNumber();
|
|
248
|
+
console.log(
|
|
249
|
+
`Using inverse pair ${inversePair}, original tokenPair ${tokenPair}, inverted price=${inverted}`
|
|
250
|
+
);
|
|
251
|
+
return inverted;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
console.error(
|
|
255
|
+
`No data found for token pair: ${tokenPair} or its inverse at or below block height ${blockHeight}`
|
|
256
|
+
);
|
|
257
|
+
return null;
|
|
258
|
+
} catch (error) {
|
|
259
|
+
console.error('Error fetching last price:', error);
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
static async getCumulativeVolumes(block) {
|
|
265
|
+
const base = await db.getDatabase('volumeIndex');
|
|
266
|
+
|
|
267
|
+
// Default values
|
|
268
|
+
let globalCumulativeVolume = 0;
|
|
269
|
+
let contractCumulativeVolume = 0;
|
|
270
|
+
let ltcPairTotalVolume = 0;
|
|
271
|
+
|
|
272
|
+
try {
|
|
273
|
+
const globalDocs = await base.findAsync({ _id: 'globalCumulativeVolume', 'value.block': { $lt: block } });
|
|
274
|
+
if (Array.isArray(globalDocs) && globalDocs.length) {
|
|
275
|
+
globalDocs.sort((a, b) => b.value.block - a.value.block);
|
|
276
|
+
globalCumulativeVolume = globalDocs[0].value.globalCumulativeVolume || 0;
|
|
277
|
+
}
|
|
278
|
+
} catch (err) {
|
|
279
|
+
console.error("Error fetching global cumulative volume:", err);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
try {
|
|
283
|
+
const contractDocs = await base.findAsync({ _id: 'contractCumulativeVolume', 'value.block': { $lt: block } });
|
|
284
|
+
if (Array.isArray(contractDocs) && contractDocs.length) {
|
|
285
|
+
contractDocs.sort((a, b) => b.value.block - a.value.block);
|
|
286
|
+
contractCumulativeVolume = contractDocs[0].value.contractCumulativeVolume || 0;
|
|
287
|
+
}
|
|
288
|
+
} catch (err) {
|
|
289
|
+
console.error("Error fetching contract cumulative volume:", err);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
try {
|
|
293
|
+
const ltcDocs = await base.findAsync({ _id: 'ltcPairCumulativeVolume', 'value.block': { $lt: block } });
|
|
294
|
+
if (Array.isArray(ltcDocs) && ltcDocs.length) {
|
|
295
|
+
ltcDocs.sort((a, b) => b.value.block - a.value.block);
|
|
296
|
+
ltcPairTotalVolume = ltcDocs[0].value.ltcPairTotalVolume || 0;
|
|
297
|
+
}
|
|
298
|
+
} catch (err) {
|
|
299
|
+
console.error("Error fetching LTC pair total volume:", err);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return {
|
|
303
|
+
globalCumulativeVolume,
|
|
304
|
+
ltcPairTotalVolume,
|
|
305
|
+
contractCumulativeVolume,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
static async getBlockVolumes(blockHeight) {
|
|
311
|
+
try {
|
|
312
|
+
// Query the VolumeIndex.db for trades with the given blockHeight
|
|
313
|
+
const base = await db.getDatabase('volumeIndex')
|
|
314
|
+
const trades = await base.findAsync({
|
|
315
|
+
"value.blockHeight": blockHeight
|
|
316
|
+
});
|
|
317
|
+
// If no trades are found, return 0
|
|
318
|
+
if (!trades || trades.length === 0) {
|
|
319
|
+
return 0;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
console.log('getting block volumes '+JSON.stringify(trades))
|
|
323
|
+
// Sum the total volume from the trades found
|
|
324
|
+
let totalLTCVolume = new BigNumber(0);
|
|
325
|
+
let totalVolume = new BigNumber(0)
|
|
326
|
+
trades.forEach(trade => {
|
|
327
|
+
const tradeVolume = new BigNumber(trade.value.ltcVolume);
|
|
328
|
+
|
|
329
|
+
if(trade._id.toString().includes('0')){
|
|
330
|
+
console.log(tradeVolume)
|
|
331
|
+
totalLTCVolume = totalLTCVolume.plus(tradeVolume);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
totalVolume=totalVolume.plus(tradeVolume)
|
|
335
|
+
|
|
336
|
+
});
|
|
337
|
+
totalLTCVolume= totalLTCVolume.toNumber()
|
|
338
|
+
totalVolume= totalVolume.toNumber()
|
|
339
|
+
console.log(totalLTCVolume+' '+totalVolume)
|
|
340
|
+
// Return the total volume for the block
|
|
341
|
+
return {ltcPairs:totalLTCVolume,global:totalVolume};
|
|
342
|
+
} catch (error) {
|
|
343
|
+
return console.error(`Error fetching block volumes for block ${blockHeight}:`, error);
|
|
344
|
+
//throw new Error(`Failed to fetch block volumes for block ${blockHeight}`);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
static async getVolumeDataById(id) {
|
|
349
|
+
return await db.getDatabase('volumeIndex').findOneAsync({ _id: id });
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
static async sampleVolumesByBlock(blockHeight) {
|
|
353
|
+
const volumeIndexData = await db.getDatabase('volumeIndex').findAsync({ blockHeight });
|
|
354
|
+
return volumeIndexData.map(entry => ({ id: entry._id, volume: entry.volume }));
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
static async sampleVolumesByBlockRange(startBlockHeight, endBlockHeight) {
|
|
358
|
+
const volumeIndexData = await db.getDatabase('volumeIndex').findAsync({
|
|
359
|
+
blockHeight: { $gte: startBlockHeight, $lte: endBlockHeight }
|
|
360
|
+
});
|
|
361
|
+
return volumeIndexData.map(entry => ({ id: entry._id, volume: entry.volume }));
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
static async calculateCumulativeVolume(id1, id2) {
|
|
365
|
+
const volumeIndexData = await db.getDatabase('volumeIndex').findAsync({ _id: { $regex: `^${id1}-${id2}-` } });
|
|
366
|
+
let cumulativeVolume = 0;
|
|
367
|
+
volumeIndexData.forEach(entry => cumulativeVolume += entry.volume);
|
|
368
|
+
return cumulativeVolume;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
static async saveCumulativeVolume(id1, id2, cumulativeVolume) {
|
|
372
|
+
const id = `cumulative-${id1}-${id2}`;
|
|
373
|
+
await saveVolumeDataById(id, null, cumulativeVolume);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
static async auditVWAP(blockHeight) {
|
|
377
|
+
const volumeData = await this.sampleVolumesByBlock(blockHeight);
|
|
378
|
+
|
|
379
|
+
// Calculate total volume and sum of (volume * price)
|
|
380
|
+
let totalVolume = 0;
|
|
381
|
+
let sumVolumeTimesPrice = 0;
|
|
382
|
+
|
|
383
|
+
for (const entry of volumeData) {
|
|
384
|
+
const price = await this.getTokenPriceInLTC(entry.id);
|
|
385
|
+
const volume = entry.volume;
|
|
386
|
+
|
|
387
|
+
totalVolume += volume;
|
|
388
|
+
sumVolumeTimesPrice += volume * price;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Avoid division by zero
|
|
392
|
+
if (totalVolume === 0) {
|
|
393
|
+
return null;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Calculate VWAP
|
|
397
|
+
const vwap = sumVolumeTimesPrice / totalVolume;
|
|
398
|
+
return vwap;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
static calculateVWAP(data, contract = false) {
|
|
402
|
+
// Calculate total volume and sum of (volume * price)
|
|
403
|
+
let totalVolume = 0;
|
|
404
|
+
let sumVolumeTimesPrice = 0;
|
|
405
|
+
|
|
406
|
+
for (const entry of data) {
|
|
407
|
+
let volume;
|
|
408
|
+
let price;
|
|
409
|
+
|
|
410
|
+
if (entry.amount1 !== undefined && entry.amount2 !== undefined) {
|
|
411
|
+
volume = contract ? entry.amount2 : entry.amount1;
|
|
412
|
+
price = contract ? entry.amount1 : entry.amount2;
|
|
413
|
+
} else if (entry.amount !== undefined && entry.price !== undefined) {
|
|
414
|
+
volume = entry.amount;
|
|
415
|
+
price = entry.price;
|
|
416
|
+
} else {
|
|
417
|
+
throw new Error("Invalid data format. Each entry must contain either 'amount1' and 'amount2', or 'amount' and 'price'.");
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
totalVolume += volume;
|
|
421
|
+
sumVolumeTimesPrice += volume * price;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Avoid division by zero
|
|
425
|
+
if (totalVolume === 0) {
|
|
426
|
+
return null;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// Calculate VWAP
|
|
430
|
+
const vwap = sumVolumeTimesPrice / totalVolume;
|
|
431
|
+
return vwap;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
static async getVwapData(propertyId1, propertyId2, trailingBlocks) {
|
|
435
|
+
try {
|
|
436
|
+
// Fetch the N most recent VWAP entries for the specified property pair
|
|
437
|
+
const vwapData = await db.getDatabase('volumeIndex').findAsync({
|
|
438
|
+
_id: { $regex: `${propertyId1}-${propertyId2}-` }
|
|
439
|
+
}, {
|
|
440
|
+
sort: { blockHeight: -1 }, // Sort by blockHeight in descending order
|
|
441
|
+
limit: trailingBlocks // Limit to the N most recent entries
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
// Calculate total volume and sum of (volume * price)
|
|
445
|
+
let totalVolume = 0;
|
|
446
|
+
let sumVolumeTimesPrice = 0;
|
|
447
|
+
|
|
448
|
+
for (const entry of vwapData) {
|
|
449
|
+
const price = entry.value.price;
|
|
450
|
+
const volume = entry.value.volume;
|
|
451
|
+
|
|
452
|
+
totalVolume += volume;
|
|
453
|
+
sumVolumeTimesPrice += volume * price;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Avoid division by zero
|
|
457
|
+
if (totalVolume === 0) {
|
|
458
|
+
return null;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// Calculate VWAP
|
|
462
|
+
const vwap = sumVolumeTimesPrice / totalVolume;
|
|
463
|
+
return vwap;
|
|
464
|
+
} catch (error) {
|
|
465
|
+
console.error('Error fetching VWAP data:', error);
|
|
466
|
+
throw new Error('Failed to fetch VWAP data.');
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
static async saveVWAP(id, blockHeight, vwap) {
|
|
471
|
+
console.log('saving VWAP'+ id, blockHeight, vwap)
|
|
472
|
+
const base = await db.getDatabase('volumeIndex')
|
|
473
|
+
await base.updateAsync(
|
|
474
|
+
{ _id: 'vwap-'+id },
|
|
475
|
+
{ value: { blockHeight:blockHeight, volume: volume, price:price } },
|
|
476
|
+
{ upsert: true }
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
static async calculateLiquidityReward(tradeVolume, token) {
|
|
481
|
+
|
|
482
|
+
if (!this.globalCumulativeVolume || this.globalCumulativeVolume === 0) {
|
|
483
|
+
const blob = await getCumulativeVolumes; // Assuming this function fetches or initializes globalCumulativeVolume
|
|
484
|
+
this.globalCumulativeVolume=blob.globalCumulativeVolume
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
if(token!=0){
|
|
488
|
+
const tokenPriceInLTC = await this.getTokenPriceInLTC(token);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
tradeVolume=tradeVolume*tokenPriceInLTC
|
|
492
|
+
const totalVolume = this.globalCumulativeVolume - tradeVolume;
|
|
493
|
+
|
|
494
|
+
// Calculate logarithmic value
|
|
495
|
+
const logVolume = Math.log10(totalVolume / 1e9); // Log base 10 with cap at 1 billion LTC
|
|
496
|
+
|
|
497
|
+
// Calculate liquidity reward based on log value
|
|
498
|
+
let liquidityReward = 0;
|
|
499
|
+
if (logVolume > 0) {
|
|
500
|
+
liquidityReward = logVolume * 3e6 / 3; // Adjust 3e6 for percentage calculation
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
return liquidityReward;
|
|
504
|
+
}
|
|
505
|
+
static async getVWAP(propertyId1, propertyId2, blockHeight, trailingBlocks) {
|
|
506
|
+
try {
|
|
507
|
+
const base = await db.getDatabase('volumeIndex');
|
|
508
|
+
const blockStart = blockHeight - trailingBlocks;
|
|
509
|
+
|
|
510
|
+
// Query volume index within the block range
|
|
511
|
+
const vwapData = await base.findAsync({
|
|
512
|
+
_id: { $in: [`${propertyId1}-${propertyId2}`, `${propertyId2}-${propertyId1}`] }, // Check both pair orders
|
|
513
|
+
"value.blockHeight": { $gte: blockStart, $lte: blockHeight }
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
if (!vwapData || vwapData.length === 0) {
|
|
517
|
+
//console.warn(`⚠️ No VWAP data for ${propertyId1}-${propertyId2} in blocks ${blockStart}-${blockHeight}`);
|
|
518
|
+
return null;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// Calculate VWAP
|
|
522
|
+
let totalVolume = new BigNumber(0);
|
|
523
|
+
let sumVolumeTimesPrice = new BigNumber(0);
|
|
524
|
+
|
|
525
|
+
for (const entry of vwapData) {
|
|
526
|
+
const price = new BigNumber(entry.value.price);
|
|
527
|
+
const volume = new BigNumber(entry.value.volume);
|
|
528
|
+
|
|
529
|
+
totalVolume = totalVolume.plus(volume);
|
|
530
|
+
sumVolumeTimesPrice = sumVolumeTimesPrice.plus(volume.times(price));
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
if (totalVolume.isZero()) return null;
|
|
534
|
+
|
|
535
|
+
return sumVolumeTimesPrice.dividedBy(totalVolume).decimalPlaces(8).toNumber();
|
|
536
|
+
} catch (error) {
|
|
537
|
+
console.error(`❌ Error fetching VWAP for ${propertyId1}-${propertyId2}:`, error);
|
|
538
|
+
return null;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
static async baselineLiquidityReward(tradeVolume, fee, token) {
|
|
544
|
+
const totalVolume = this.globalCumulativeVolume - tradeVolume;
|
|
545
|
+
let tlPriceInLTC = 0.001
|
|
546
|
+
if(token!=0){
|
|
547
|
+
|
|
548
|
+
// Step 1: Get LTC price of the token in question
|
|
549
|
+
const tokenPriceInLTC = await this.getTokenPriceInLTC(token);
|
|
550
|
+
|
|
551
|
+
// Step 2: Get TL/LTC price (assuming TL is a specific token or currency)
|
|
552
|
+
tlPriceInLTC = await this.getTLPriceInLTC();
|
|
553
|
+
|
|
554
|
+
// Step 3: Calculate fee in TL
|
|
555
|
+
const feeInTL = fee * tokenPriceInLTC * tlPriceInLTC;
|
|
556
|
+
}else{
|
|
557
|
+
const feeInTL= fee * tlPriceInLTC
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
// Calculate logarithmic value
|
|
562
|
+
const logVolume = Math.log10(totalVolume);
|
|
563
|
+
|
|
564
|
+
// Calculate liquidity reward based on log value and fee
|
|
565
|
+
let liquidityReward = 0;
|
|
566
|
+
if (logVolume > 0) {
|
|
567
|
+
const feeAdjustment = 1/logVolume; // Reducing by 10% per log 10
|
|
568
|
+
liquidityReward = feeInTL * feeAdjustment;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
return liquidityReward;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
static async getTLPriceInLTC() {
|
|
575
|
+
// Attempt to fetch the VWAP price from the database
|
|
576
|
+
const base = await db.getDatabase('volumeIndex')
|
|
577
|
+
const vwapData = await base.findOneAsync({ _id: `vwap-1` });
|
|
578
|
+
|
|
579
|
+
if (vwapData && vwapData.value && vwapData.value.price) {
|
|
580
|
+
return vwapData.value.price;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// If VWAP price is not available, return a default low value
|
|
584
|
+
return 0.001; // Minimum price
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
static vestTokens(tradeVolume) {
|
|
590
|
+
// Calculate logarithmic value
|
|
591
|
+
const logVolume = Math.log10(this.globalCumulativeVolume / 1e9); // Log base 10 with cap at 100 billion LTC
|
|
592
|
+
|
|
593
|
+
// Tier 1 vesting tokens (1000 to 100,000,000 LTC)
|
|
594
|
+
let tier1Tokens = 0;
|
|
595
|
+
if (logVolume > 0) {
|
|
596
|
+
if (totalVolume >= 1000 && totalVolume <= 1e8) {
|
|
597
|
+
tier1Tokens = logVolume * 1e6; // Adjust 1e6 for tokens calculation
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
// Tier 2 vesting tokens (100,000,000 to 100 billion LTC)
|
|
602
|
+
let tier2Tokens = 0;
|
|
603
|
+
if (logVolume > 0) {
|
|
604
|
+
if (totalVolume > 1e8 && totalVolume <= 1e11) {
|
|
605
|
+
tier2Tokens = logVolume * 3e6; // Adjust 3e6 for tokens calculation
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
return {
|
|
610
|
+
tier1Tokens,
|
|
611
|
+
tier2Tokens
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
module.exports = VolumeIndex;
|