@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,243 @@
|
|
|
1
|
+
const BigNumber = require('bignumber.js');
|
|
2
|
+
const level = require('level');
|
|
3
|
+
|
|
4
|
+
class TokenOrderbook {
|
|
5
|
+
constructor(dbPath, tickSize = new BigNumber('0.000000001')) {
|
|
6
|
+
this.tickSize = tickSize;
|
|
7
|
+
this.db = level(dbPath);
|
|
8
|
+
this.orderBooks = {}; // This will be populated from LevelDB
|
|
9
|
+
this.loadOrderBooks(); // Load existing order books from LevelDB
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async loadOrderBooks() {
|
|
13
|
+
// Load order books from LevelDB
|
|
14
|
+
for await (const [key, value] of this.db.iterator({ gt: 'book-', lt: 'book-\xFF' })) {
|
|
15
|
+
this.orderBooks[key.split('-')[1]] = JSON.parse(value);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async saveOrderBook(pair) {
|
|
20
|
+
// Save order book to LevelDB
|
|
21
|
+
await this.db.put(`book-${pair}`, JSON.stringify(this.orderBooks[pair]));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Adds a token order to the order book
|
|
25
|
+
addTokenOrder({ propertyIdNumber, propertyIdNumberDesired, amountOffered, amountExpected, time }) {
|
|
26
|
+
const price = this.calculatePrice(amountOffered, amountExpected);
|
|
27
|
+
const order = { propertyIdNumber, propertyIdNumberDesired, amountOffered, amountExpected, price, time };
|
|
28
|
+
|
|
29
|
+
const orderBookKey = `${propertyIdNumber}-${propertyIdNumberDesired}`;
|
|
30
|
+
this.insertOrder(order, orderBookKey);
|
|
31
|
+
this.matchOrders(orderBookKey);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
addContractOrder({ contractId, amount, price, time, sell }) {
|
|
35
|
+
// Create a contract order object with the sell parameter
|
|
36
|
+
const contractOrder = { contractId, amount, price, time, sell };
|
|
37
|
+
|
|
38
|
+
// The orderBookKey is based on the contractId since it's a derivative contract
|
|
39
|
+
const orderBookKey = `contract-${contractId}`;
|
|
40
|
+
|
|
41
|
+
// Insert the contract order into the order book
|
|
42
|
+
this.insertOrder(contractOrder, orderBookKey, true);
|
|
43
|
+
|
|
44
|
+
// Match orders in the derivative contract order book
|
|
45
|
+
this.matchOrders(orderBookKey);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
insertOrder(order, orderBookKey, isContractOrder = false) {
|
|
49
|
+
// If order book does not exist, create it
|
|
50
|
+
if (!this.orderBooks[orderBookKey]) {
|
|
51
|
+
this.orderBooks[orderBookKey] = { buy: [], sell: [] };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Determine if it's a buy or sell order based on the property IDs
|
|
55
|
+
if(isContractOrder==false){
|
|
56
|
+
const side = order.propertyIdNumber < order.propertyIdNumberDesired ? 'buy' : 'sell';
|
|
57
|
+
}else if(isContractOrder==true&&sell==true){
|
|
58
|
+
const side = 'sell';
|
|
59
|
+
}else if(isContractOrder==true&&sell==false){
|
|
60
|
+
const side = 'buy'
|
|
61
|
+
}
|
|
62
|
+
// Insert the order into the correct side of the book
|
|
63
|
+
const bookSide = this.orderBooks[orderBookKey][side];
|
|
64
|
+
const index = bookSide.findIndex((o) => o.time > order.time);
|
|
65
|
+
if (index === -1) {
|
|
66
|
+
bookSide.push(order);
|
|
67
|
+
} else {
|
|
68
|
+
bookSide.splice(index, 0, order);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Save the updated order book
|
|
72
|
+
this.saveOrderBook(orderBookKey);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
calculatePrice(amountOffered, amountExpected) {
|
|
76
|
+
const priceRatio = new BigNumber(amountOffered).dividedBy(amountExpected);
|
|
77
|
+
return priceRatio.decimalPlaces(8, BigNumber.ROUND_HALF_UP);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
matchOrders(orderBookKey, isContract = false) {
|
|
81
|
+
const orderBook = this.orderBooks[orderBookKey];
|
|
82
|
+
if (!orderBook || orderBook.buy.length === 0 || orderBook.sell.length === 0) {
|
|
83
|
+
return; // Nothing to match
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const matches = [];
|
|
87
|
+
|
|
88
|
+
// Sort buy orders from highest to lowest price and sell orders from lowest to highest price
|
|
89
|
+
orderBook.buy.sort((a, b) => b.price.comparedTo(a.price) || a.time - b.time); // Highest price and oldest first
|
|
90
|
+
orderBook.sell.sort((a, b) => a.price.comparedTo(b.price) || a.time - b.time); // Lowest price and oldest first
|
|
91
|
+
|
|
92
|
+
// While there is still potential for matches
|
|
93
|
+
while (orderBook.sell.length > 0 && orderBook.buy.length > 0 &&
|
|
94
|
+
orderBook.sell[0].price.lte(orderBook.buy[0].price)) {
|
|
95
|
+
|
|
96
|
+
// Match the top of the buy and sell orders
|
|
97
|
+
let sellOrder = orderBook.sell[0];
|
|
98
|
+
let buyOrder = orderBook.buy[0];
|
|
99
|
+
|
|
100
|
+
// Determine the amount to trade which is the minimum of the two orders
|
|
101
|
+
const amountToTrade = BigNumber.minimum(sellOrder.amountOffered, buyOrder.amountExpected);
|
|
102
|
+
|
|
103
|
+
// Update orders
|
|
104
|
+
sellOrder.amountOffered = sellOrder.amountOffered.minus(amountToTrade);
|
|
105
|
+
buyOrder.amountExpected = buyOrder.amountExpected.minus(amountToTrade);
|
|
106
|
+
|
|
107
|
+
// Deduct taker fee from buyer and give maker rebate to seller
|
|
108
|
+
if(isContract==false){
|
|
109
|
+
const takerFee = amountToTrade.times(0.0002);
|
|
110
|
+
const makerRebate = takerFee.div(2);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if(isContract==true){
|
|
114
|
+
const takerFee = amountToTrade.times(0.0001);
|
|
115
|
+
const makerRebate = takerFee.div(2);
|
|
116
|
+
}
|
|
117
|
+
buyOrder.amountExpected = buyOrder.amountExpected.minus(takerFee);
|
|
118
|
+
sellOrder.amountOffered = sellOrder.amountOffered.plus(makerRebate);
|
|
119
|
+
|
|
120
|
+
// If an order is completely filled, remove it from the order book
|
|
121
|
+
if (sellOrder.amountOffered.isZero()) {
|
|
122
|
+
orderBook.sell.shift(); // Remove the sell order
|
|
123
|
+
}
|
|
124
|
+
if (buyOrder.amountExpected.isZero()) {
|
|
125
|
+
orderBook.buy.shift(); // Remove the buy order
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const matchedOrderDetails = {
|
|
129
|
+
sellOrderId: sellOrder.id, // Assuming we have unique IDs for orders
|
|
130
|
+
buyOrderId: buyOrder.id,
|
|
131
|
+
amountToTrade: amountToTrade.toString(),
|
|
132
|
+
price: sellOrder.price.toString(),
|
|
133
|
+
takerFee: takerFee.toString(),
|
|
134
|
+
makerRebate: makerRebate.toString()
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
matches.push(matchedOrderDetails);
|
|
138
|
+
|
|
139
|
+
// Partial matches: remaining amounts stay in the order book
|
|
140
|
+
// (They are already updated in the order objects)
|
|
141
|
+
}// Process the matches differently based on whether they're token or contract matches
|
|
142
|
+
|
|
143
|
+
const matchResults = {
|
|
144
|
+
orderBook: this.orderBooks[orderBookKey],
|
|
145
|
+
matches
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
if (isContract) {
|
|
149
|
+
this.processContractMatches(matchResults.matches);
|
|
150
|
+
} else {
|
|
151
|
+
this.processTokenMatches(matchResults.matches);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
this.saveOrderBook(orderBookKey);
|
|
155
|
+
|
|
156
|
+
// Return the updated order book and the matches
|
|
157
|
+
return {
|
|
158
|
+
orderBook: this.orderBooks[orderBookKey],
|
|
159
|
+
matches
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
processTokenMatches(matches) {
|
|
165
|
+
matches.forEach(match => {
|
|
166
|
+
const sellOrder = this.getAddressBalances(match.sellOrderId);
|
|
167
|
+
const buyOrder = this.getAddressBalances(match.buyOrderId);
|
|
168
|
+
|
|
169
|
+
// Debit the reserve balances from the seller and buyer
|
|
170
|
+
sellOrder.reserveAmount = sellOrder.reserveAmount.minus(match.amountToTrade);
|
|
171
|
+
buyOrder.reserveAmount = buyOrder.reserveAmount.minus(match.amountToTrade);
|
|
172
|
+
|
|
173
|
+
// Credit the available balances to the buyer and seller
|
|
174
|
+
sellOrder.available = sellOrder.available.plus(match.amountToTrade);
|
|
175
|
+
buyOrder.available = buyOrder.available.plus(match.amountToTrade);
|
|
176
|
+
|
|
177
|
+
// Apply fees and rebates
|
|
178
|
+
buyOrder.available = buyOrder.available.minus(match.takerFee);
|
|
179
|
+
sellOrder.available = sellOrder.available.plus(match.makerRebate);
|
|
180
|
+
|
|
181
|
+
// Save the updated balances back to the TallyMap
|
|
182
|
+
this.updateBalance(match.sellOrderId, sellOrder);
|
|
183
|
+
this.updateBalance(match.buyOrderId, buyOrder);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
processContractMatches(matches) {
|
|
188
|
+
matches.forEach(match => {
|
|
189
|
+
// Logic for identifying and updating the marginMap for contracts
|
|
190
|
+
// You can go to negative balances for contracts, so the logic here
|
|
191
|
+
// will need to be different than for tokens.
|
|
192
|
+
|
|
193
|
+
// Example logic (you'll need to replace this with your actual logic):
|
|
194
|
+
const contract = this.marginMap.get(match.contractId);
|
|
195
|
+
if (match.sell) {
|
|
196
|
+
// Update seller's margin balance
|
|
197
|
+
contract.sellerMargin = contract.sellerMargin.minus(match.amountToTrade);
|
|
198
|
+
// Update buyer's balance (can go negative)
|
|
199
|
+
contract.buyerMargin = contract.buyerMargin.plus(match.amountToTrade.minus(match.takerFee));
|
|
200
|
+
} else {
|
|
201
|
+
// Update buyer's margin balance
|
|
202
|
+
contract.buyerMargin = contract.buyerMargin.minus(match.amountToTrade);
|
|
203
|
+
// Update seller's balance (can go negative)
|
|
204
|
+
contract.sellerMargin = contract.sellerMargin.plus(match.amountToTrade.plus(match.makerRebate));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Save the updated contract margins back to the marginMap
|
|
208
|
+
this.marginMap.set(match.contractId, contract);
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
async processContractMatches(matches, currentBlockHeight) {
|
|
213
|
+
for (const match of matches) {
|
|
214
|
+
try {
|
|
215
|
+
// Load the margin map for the given series ID and block height
|
|
216
|
+
const marginMap = await MarginMap.loadMarginMap(match.contractSeriesId, currentBlockHeight);
|
|
217
|
+
|
|
218
|
+
// Update contract balances for the buyer and seller
|
|
219
|
+
marginMap.updateContractBalances(match.buyerAddress, match.amount, match.price, true);
|
|
220
|
+
marginMap.updateContractBalances(match.sellerAddress, match.amount, match.price, false);
|
|
221
|
+
marginMap.updateMargin(match.buyerAddress, match.amount, match.price);
|
|
222
|
+
marginMap.updateMargin(match.sellerAddress, -match.amount, match.price);
|
|
223
|
+
|
|
224
|
+
// Realize PnL for the buyer and seller
|
|
225
|
+
const buyerPnl = marginMap.realizePnl(match.buyerAddress, match.amount, match.price, match.buyerAvgPrice);
|
|
226
|
+
const sellerPnl = marginMap.realizePnl(match.sellerAddress, -match.amount, match.price, match.sellerAvgPrice);
|
|
227
|
+
|
|
228
|
+
// Save the updated margin map
|
|
229
|
+
await marginMap.saveMarginMap(currentBlockHeight);
|
|
230
|
+
|
|
231
|
+
// Optionally handle the PnL if needed, e.g., logging or further processing
|
|
232
|
+
// ...
|
|
233
|
+
|
|
234
|
+
} catch (error) {
|
|
235
|
+
console.error(`Error processing contract match ${match.id}:`, error);
|
|
236
|
+
// Handle error, potentially rolling back any partial updates or retrying
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
module.exports = TokenOrderbook;
|
|
File without changes
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const litecoin = require('litecoin');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
const client = new litecoin.Client({
|
|
6
|
+
host: '127.0.0.1',
|
|
7
|
+
port: 18332,
|
|
8
|
+
user: 'user',
|
|
9
|
+
pass: 'pass',
|
|
10
|
+
timeout: 10000
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
/*client.cmd('createwallet','', function(err, walletInfo) {
|
|
14
|
+
if (err) {
|
|
15
|
+
console.error('Error creating new wallet:', err);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
console.log('New Wallet Info:', walletInfo);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
client.getBalance('*', 1, function(err, balance) {
|
|
22
|
+
if (err) {
|
|
23
|
+
console.error('Error fetching balance:', err);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
console.log('Total Wallet Balance:', balance, 'LTC');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
client.listUnspent(1, 9999999, function(err, unspent) {
|
|
30
|
+
if (err) {
|
|
31
|
+
console.error('Error listing unspent transactions:', err);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
console.log('Unspent Transactions:', unspent);
|
|
35
|
+
});*/
|
|
36
|
+
|
|
37
|
+
client.getNewAddress(function(err, address) {
|
|
38
|
+
if (err) {
|
|
39
|
+
console.error('Error fetching new address:', err);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
console.log('New Address:', address);
|
|
43
|
+
});
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
function decodeOmniPayload(hexPayload) {
|
|
2
|
+
// Remove the "OP_RETURN" prefix (4 bytes) and convert the hex payload to a Buffer
|
|
3
|
+
const payloadBuffer = Buffer.from(hexPayload.slice(8), 'hex');
|
|
4
|
+
|
|
5
|
+
// Extract the markers (each marker is 4 bytes)
|
|
6
|
+
const markers = [];
|
|
7
|
+
for (let i = 0; i < payloadBuffer.length; i += 4) {
|
|
8
|
+
const markerBuffer = payloadBuffer.slice(i, i + 4);
|
|
9
|
+
const marker = markerBuffer.toString('ascii');
|
|
10
|
+
markers.push(marker);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Extract the payload data as a Buffer (skip markers)
|
|
14
|
+
const dataBuffer = payloadBuffer.slice(markers.length * 4);
|
|
15
|
+
|
|
16
|
+
// Check if there is enough data to read a 32-bit integer
|
|
17
|
+
let numericValue = null;
|
|
18
|
+
if (dataBuffer.length >= 4) {
|
|
19
|
+
numericValue = dataBuffer.readInt32LE(0);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Convert markers to plain text
|
|
23
|
+
const markersText = markers.join(' ');
|
|
24
|
+
|
|
25
|
+
// Convert payload data to plain text
|
|
26
|
+
const dataText = dataBuffer.toString('utf8');
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
markers: markersText,
|
|
30
|
+
data: dataText,
|
|
31
|
+
numericValue
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Example usage:
|
|
36
|
+
const hexPayload = "6f6d6e6900000032010002000000000000537175697272656c20636f696e00004e55545300001dd7c1681d0000";
|
|
37
|
+
const decodedPayload = decodeOmniPayload(hexPayload);
|
|
38
|
+
console.log(decodedPayload.markers); // "omni coin NUTS"
|
|
39
|
+
console.log(decodedPayload.data); // "Squirrel coin"
|
|
40
|
+
console.log(decodedPayload.numericValue); // 84000000
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
/*function decodeOmniPayload(hexPayload) {
|
|
45
|
+
// Remove the "OP_RETURN" prefix (4 bytes) and convert the hex payload to a Buffer
|
|
46
|
+
const payloadBuffer = Buffer.from(hexPayload.slice(8), 'hex');
|
|
47
|
+
|
|
48
|
+
// Extract the Omni marker (4 bytes) as an ASCII string
|
|
49
|
+
const marker = payloadBuffer.slice(0, 4).toString('ascii');
|
|
50
|
+
|
|
51
|
+
// Decode the payload data to a string while handling non-printable characters
|
|
52
|
+
let decodedData = '';
|
|
53
|
+
for (let i = 4; i < payloadBuffer.length; i++) {
|
|
54
|
+
const charCode = payloadBuffer.readUInt8(i);
|
|
55
|
+
if (charCode >= 32 && charCode <= 126) {
|
|
56
|
+
// Printable ASCII characters
|
|
57
|
+
decodedData += String.fromCharCode(charCode);
|
|
58
|
+
} else {
|
|
59
|
+
// Non-printable characters, represent as \xHH
|
|
60
|
+
decodedData += `\\x${charCode.toString(16).padStart(2, '0').toUpperCase()}`;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
marker,
|
|
66
|
+
data: decodedData
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Example usage:
|
|
71
|
+
const hexPayload = "6f6d6e6900000032010002000000000000537175697272656c20636f696e00004e55545300001dd7c1681d0000";
|
|
72
|
+
const decodedPayload = decodeOmniPayload(hexPayload);
|
|
73
|
+
console.log(decodedPayload.marker); // "omni"
|
|
74
|
+
console.log(decodedPayload.data); // "Squirrel coinNUTS\x1D\xD7\xC1\x68\x1D"
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
/*function decodeOmniPayload(hexPayload) {
|
|
78
|
+
// Remove the "OP_RETURN" prefix (4 bytes) and convert the hex payload to a Buffer
|
|
79
|
+
const payloadBuffer = Buffer.from(hexPayload.slice(8), 'hex');
|
|
80
|
+
|
|
81
|
+
// Extract the Omni marker (4 bytes) as a hexadecimal string
|
|
82
|
+
const markerHex = payloadBuffer.slice(0, 4).toString('hex');
|
|
83
|
+
|
|
84
|
+
// Define a mapping for known Omni markers
|
|
85
|
+
const markerMap = {
|
|
86
|
+
'6f6d6e69': 'omni',
|
|
87
|
+
// Add more markers as needed
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// Decode the payload data to a string while handling non-printable characters
|
|
91
|
+
let decodedData = '';
|
|
92
|
+
for (let i = 4; i < payloadBuffer.length; i++) {
|
|
93
|
+
const charCode = payloadBuffer.readUInt8(i);
|
|
94
|
+
if (charCode >= 32 && charCode <= 126) {
|
|
95
|
+
// Printable ASCII characters
|
|
96
|
+
decodedData += String.fromCharCode(charCode);
|
|
97
|
+
} else {
|
|
98
|
+
// Non-printable characters, represent as \xHH
|
|
99
|
+
decodedData += `\\x${charCode.toString(16).padStart(2, '0').toUpperCase()}`;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Determine the marker name based on the hexadecimal value
|
|
104
|
+
const markerName = markerMap[markerHex] || 'Unknown';
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
marker: markerName,
|
|
108
|
+
data: decodedData
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Example usage:
|
|
113
|
+
const hexPayload = "6f6d6e6900000032010002000000000000537175697272656c20636f696e00004e55545300001dd7c1681d0000";
|
|
114
|
+
const decodedPayload = decodeOmniPayload(hexPayload);
|
|
115
|
+
console.log(decodedPayload.marker); // "omni"
|
|
116
|
+
console.log(decodedPayload.data); // "Squirrel coinNUTS\x1D\xD7\xC1\x68\x1D"*/
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
/*function decodeOmniPayload(hexPayload) {
|
|
120
|
+
// Remove the "OP_RETURN" prefix (4 bytes) and convert the hex payload to a Buffer
|
|
121
|
+
const payloadBuffer = Buffer.from(hexPayload.slice(8), 'hex');
|
|
122
|
+
|
|
123
|
+
// Extract the Omni marker (4 bytes)
|
|
124
|
+
const marker = payloadBuffer.slice(0, 4).toString('hex');
|
|
125
|
+
|
|
126
|
+
// Extract the payload data (after the marker)
|
|
127
|
+
const payloadData = payloadBuffer.slice(4);
|
|
128
|
+
|
|
129
|
+
// Decode the payload data to a string while handling non-printable characters
|
|
130
|
+
let decodedData = '';
|
|
131
|
+
for (let i = 0; i < payloadData.length; i++) {
|
|
132
|
+
const charCode = payloadData.readUInt8(i);
|
|
133
|
+
if (charCode >= 32 && charCode <= 126) {
|
|
134
|
+
// Printable ASCII characters
|
|
135
|
+
decodedData += String.fromCharCode(charCode);
|
|
136
|
+
} else {
|
|
137
|
+
// Non-printable characters, represent as \xHH
|
|
138
|
+
decodedData += `\\x${charCode.toString(16).padStart(2, '0').toUpperCase()}`;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
marker: marker,
|
|
144
|
+
data: decodedData
|
|
145
|
+
};
|
|
146
|
+
}*/
|
|
147
|
+
|
|
148
|
+
// Example usage:
|
|
149
|
+
/*const hexPayload = "6f6d6e6900000032010002000000000000537175697272656c20636f696e00004e55545300001dd7c1681d0000";
|
|
150
|
+
const decodedPayload = decodeOmniPayload(hexPayload);
|
|
151
|
+
console.log(decodedPayload.marker); // "omni"
|
|
152
|
+
console.log(decodedPayload.data); // "Squirrel coinNUTS\x1D\xD7\xC1\x68\x1D*/
|
|
153
|
+
|
|
154
|
+
/*function decodeOmniPayload(hexPayload) {
|
|
155
|
+
// Remove the "OP_RETURN" prefix (4 bytes) and convert the hex payload to a Buffer
|
|
156
|
+
const payloadBuffer = Buffer.from(hexPayload.slice(8), 'hex');
|
|
157
|
+
|
|
158
|
+
// Extract the Omni marker (4 bytes)
|
|
159
|
+
const marker = payloadBuffer.slice(0, 4).toString('hex');
|
|
160
|
+
|
|
161
|
+
// Extract the payload data (after the marker)
|
|
162
|
+
const payloadData = payloadBuffer.slice(4);
|
|
163
|
+
|
|
164
|
+
// Decode the payload data to a string
|
|
165
|
+
let decodedData = '';
|
|
166
|
+
for (let i = 0; i < payloadData.length; i++) {
|
|
167
|
+
decodedData += String.fromCharCode(payloadData[i]);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return {
|
|
171
|
+
marker: marker,
|
|
172
|
+
data: decodedData
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Example usage:
|
|
177
|
+
const hexPayload = "6f6d6e6900000032010002000000000000537175697272656c20636f696e00004e55545300001dd7c1681d0000";
|
|
178
|
+
const decodedPayload = decodeOmniPayload(hexPayload);
|
|
179
|
+
console.log(decodedPayload.marker); // "omni"
|
|
180
|
+
console.log(decodedPayload.data); // "Squirrel coinNUTSh"
|
|
181
|
+
*/
|
|
182
|
+
|
|
183
|
+
/*
|
|
184
|
+
function decodeOmniPayload(hexPayload) {
|
|
185
|
+
// Remove the "OP_RETURN" prefix (4 bytes) and convert the hex payload to a Buffer
|
|
186
|
+
const payloadBuffer = Buffer.from(hexPayload.slice(8), 'hex');
|
|
187
|
+
|
|
188
|
+
// Extract the Omni marker (4 bytes)
|
|
189
|
+
const marker = payloadBuffer.slice(0, 4).toString('hex');
|
|
190
|
+
|
|
191
|
+
// Extract the payload data (after the marker)
|
|
192
|
+
const payloadData = payloadBuffer.slice(4).toString('utf8');
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
marker: marker,
|
|
196
|
+
data: payloadData
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Example usage:
|
|
201
|
+
const hexPayload = "6f6d6e6900000032010002000000000000537175697272656c20636f696e00004e55545300001dd7c1681d0000";
|
|
202
|
+
const decodedPayload = decodeOmniPayload(hexPayload);
|
|
203
|
+
console.log(decodedPayload.marker); // "omni"
|
|
204
|
+
console.log(decodedPayload.data); // "Squirrel coinNUTSh"
|
|
205
|
+
*/
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const Litecoin = require('litecoin'); // Replace with actual library import
|
|
2
|
+
const util = require('util');
|
|
3
|
+
const client = new Litecoin.Client({
|
|
4
|
+
host: '127.0.0.1',
|
|
5
|
+
port: 18332,
|
|
6
|
+
user: 'user',
|
|
7
|
+
pass: 'pass',
|
|
8
|
+
timeout: 10000
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
const decoderawtransactionAsync = util.promisify(client.cmd.bind(client,'decoderawtransaction'));
|
|
12
|
+
const getTransactionAsync = util.promisify(client.cmd.bind(client, 'gettransaction'))
|
|
13
|
+
|
|
14
|
+
async function testDecodeRawTransaction(rawTx) {
|
|
15
|
+
try {
|
|
16
|
+
const decodedTx = await decoderawtransactionAsync('decoderawtransaction', rawTx);
|
|
17
|
+
console.log('Decoded Transaction:', decodedTx);
|
|
18
|
+
|
|
19
|
+
const opReturnOutput = decodedTx.vout.find(output => output.scriptPubKey.type === 'nulldata');
|
|
20
|
+
|
|
21
|
+
if (opReturnOutput) {
|
|
22
|
+
const opReturnData = opReturnOutput.scriptPubKey.hex;
|
|
23
|
+
console.log('OP_RETURN Data:', opReturnData);
|
|
24
|
+
|
|
25
|
+
// Extract and log the "tl" marker
|
|
26
|
+
const markerHex = opReturnData.substring(4, 8); // '746c' for 'tl'
|
|
27
|
+
const marker = Buffer.from(markerHex, 'hex').toString();
|
|
28
|
+
console.log('Marker:', marker);
|
|
29
|
+
|
|
30
|
+
// Extract and log the actual payload
|
|
31
|
+
const payloadHex = opReturnData.substring(8);
|
|
32
|
+
const payload = Buffer.from(payloadHex, 'hex').toString();
|
|
33
|
+
console.log('Decoded Payload:', payload);
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
return { marker, payload };
|
|
37
|
+
} else {
|
|
38
|
+
console.log('No OP_RETURN output found.');
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error('Error decoding raw transaction:', error);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const rawTx = '02000000000101be64c98a4c17b5861b45b2602873212cb0ada374539c7b61593b2d3e47b8e5cd0100000000ffffffff020000000000000000066a04746c303080b9ff0600000000160014ebecd536259ef21bc6ecc18e45b35412f04722900247304402201ac4b0e373e7555d502e80b5424683dd1da2ca8052793bd2c62d64b2e9370367022014e72b32507262b3c78848b81558acfb2c9f9cb2a8c7968b65615888e7f04d0b012103d6521aea309f7a2768a1cabcb917664966cabc28bc23874b12f73c1989972c5f00000000';
|
|
47
|
+
client.cmd('gettransaction','0513576fa72ffdd721176dfc5a971af50958102070f55fce6d50aa604c6d0cb0',function(err,data){
|
|
48
|
+
console.log(data.hex)
|
|
49
|
+
testDecodeRawTransaction(data.hex);
|
|
50
|
+
})
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const TallyMap = require('./tally.js'); // Adjust the path to your TallyMap class file
|
|
2
|
+
|
|
3
|
+
async function displayTallyMap() {
|
|
4
|
+
try {
|
|
5
|
+
console.log('Loading TallyMap from Database...');
|
|
6
|
+
|
|
7
|
+
// Assuming the block height is not relevant for just loading and displaying
|
|
8
|
+
const tallyMapInstance = await TallyMap.getInstance();
|
|
9
|
+
tallyMapInstance.loadFromDB()
|
|
10
|
+
// Convert the Map to an Object for easier JSON stringification
|
|
11
|
+
const tallyMapObject = Object.fromEntries(tallyMapInstance.addresses);
|
|
12
|
+
console.log('tallyMap: '+JSON.stringify(tallyMapInstance.addresses))
|
|
13
|
+
console.log('TallyMap:', JSON.stringify(tallyMapObject, null, 2));
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.error('Error loading and displaying TallyMap:', error);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
displayTallyMap();
|