1 | "use strict";
|
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
4 | };
|
5 | Object.defineProperty(exports, "__esModule", { value: true });
|
6 | exports.computePaymentChannelHash = exports.computeEscrowHash = exports.computeLedgerHash = exports.computeStateTreeHash = exports.computeTransactionTreeHash = exports.computeTrustlineHash = exports.computeOrderID = exports.computeSignerListLedgerObjectID = exports.computeAccountLedgerObjectID = exports.computeBinaryTransactionSigningHash = exports.computeTransactionHash = exports.computeBinaryTransactionHash = void 0;
|
7 | const bignumber_js_1 = __importDefault(require("bignumber.js"));
|
8 | const ripple_address_codec_1 = require("ripple-address-codec");
|
9 | const sha512Half_1 = __importDefault(require("./sha512Half"));
|
10 | const hash_prefix_1 = __importDefault(require("./hash-prefix"));
|
11 | const shamap_1 = require("./shamap");
|
12 | const ripple_binary_codec_1 = require("ripple-binary-codec");
|
13 | const ledgerspaces_1 = __importDefault(require("./ledgerspaces"));
|
14 | const padLeftZero = (string, length) => {
|
15 | return Array(length - string.length + 1).join('0') + string;
|
16 | };
|
17 | const intToHex = (integer, byteLength) => {
|
18 | return padLeftZero(Number(integer).toString(16), byteLength * 2);
|
19 | };
|
20 | const bytesToHex = (bytes) => {
|
21 | return Buffer.from(bytes).toString('hex');
|
22 | };
|
23 | const bigintToHex = (integerString, byteLength) => {
|
24 | const hex = new bignumber_js_1.default(integerString).toString(16);
|
25 | return padLeftZero(hex, byteLength * 2);
|
26 | };
|
27 | const ledgerSpaceHex = (name) => {
|
28 | return intToHex(ledgerspaces_1.default[name].charCodeAt(0), 2);
|
29 | };
|
30 | const addressToHex = (address) => {
|
31 | return Buffer.from(ripple_address_codec_1.decodeAccountID(address)).toString('hex');
|
32 | };
|
33 | const currencyToHex = (currency) => {
|
34 | if (currency.length === 3) {
|
35 | const bytes = new Array(20 + 1).join('0').split('').map(parseFloat);
|
36 | bytes[12] = currency.charCodeAt(0) & 0xff;
|
37 | bytes[13] = currency.charCodeAt(1) & 0xff;
|
38 | bytes[14] = currency.charCodeAt(2) & 0xff;
|
39 | return bytesToHex(bytes);
|
40 | }
|
41 | return currency;
|
42 | };
|
43 | const addLengthPrefix = (hex) => {
|
44 | const length = hex.length / 2;
|
45 | if (length <= 192) {
|
46 | return bytesToHex([length]) + hex;
|
47 | }
|
48 | else if (length <= 12480) {
|
49 | const x = length - 193;
|
50 | return bytesToHex([193 + (x >>> 8), x & 0xff]) + hex;
|
51 | }
|
52 | else if (length <= 918744) {
|
53 | const x = length - 12481;
|
54 | return bytesToHex([241 + (x >>> 16), (x >>> 8) & 0xff, x & 0xff]) + hex;
|
55 | }
|
56 | throw new Error('Variable integer overflow.');
|
57 | };
|
58 | exports.computeBinaryTransactionHash = (txBlobHex) => {
|
59 | const prefix = hash_prefix_1.default.TRANSACTION_ID.toString(16).toUpperCase();
|
60 | return sha512Half_1.default(prefix + txBlobHex);
|
61 | };
|
62 | exports.computeTransactionHash = (txJSON) => {
|
63 | return exports.computeBinaryTransactionHash(ripple_binary_codec_1.encode(txJSON));
|
64 | };
|
65 | exports.computeBinaryTransactionSigningHash = (txBlobHex) => {
|
66 | const prefix = hash_prefix_1.default.TRANSACTION_SIGN.toString(16).toUpperCase();
|
67 | return sha512Half_1.default(prefix + txBlobHex);
|
68 | };
|
69 | exports.computeAccountLedgerObjectID = (address) => {
|
70 | return sha512Half_1.default(ledgerSpaceHex('account') + addressToHex(address));
|
71 | };
|
72 | exports.computeSignerListLedgerObjectID = (address) => {
|
73 | return sha512Half_1.default(ledgerSpaceHex('signerList') + addressToHex(address) + '00000000');
|
74 | };
|
75 | exports.computeOrderID = (address, sequence) => {
|
76 | const prefix = '00' + intToHex(ledgerspaces_1.default.offer.charCodeAt(0), 1);
|
77 | return sha512Half_1.default(prefix + addressToHex(address) + intToHex(sequence, 4));
|
78 | };
|
79 | exports.computeTrustlineHash = (address1, address2, currency) => {
|
80 | const address1Hex = addressToHex(address1);
|
81 | const address2Hex = addressToHex(address2);
|
82 | const swap = new bignumber_js_1.default(address1Hex, 16).isGreaterThan(new bignumber_js_1.default(address2Hex, 16));
|
83 | const lowAddressHex = swap ? address2Hex : address1Hex;
|
84 | const highAddressHex = swap ? address1Hex : address2Hex;
|
85 | const prefix = ledgerSpaceHex('rippleState');
|
86 | return sha512Half_1.default(prefix + lowAddressHex + highAddressHex + currencyToHex(currency));
|
87 | };
|
88 | exports.computeTransactionTreeHash = (transactions) => {
|
89 | const shamap = new shamap_1.SHAMap();
|
90 | transactions.forEach((txJSON) => {
|
91 | const txBlobHex = ripple_binary_codec_1.encode(txJSON);
|
92 | const metaHex = ripple_binary_codec_1.encode(txJSON.metaData);
|
93 | const txHash = exports.computeBinaryTransactionHash(txBlobHex);
|
94 | const data = addLengthPrefix(txBlobHex) + addLengthPrefix(metaHex);
|
95 | shamap.addItem(txHash, data, shamap_1.NodeType.TRANSACTION_METADATA);
|
96 | });
|
97 | return shamap.hash;
|
98 | };
|
99 | exports.computeStateTreeHash = (entries) => {
|
100 | const shamap = new shamap_1.SHAMap();
|
101 | entries.forEach((ledgerEntry) => {
|
102 | const data = ripple_binary_codec_1.encode(ledgerEntry);
|
103 | shamap.addItem(ledgerEntry.index, data, shamap_1.NodeType.ACCOUNT_STATE);
|
104 | });
|
105 | return shamap.hash;
|
106 | };
|
107 | exports.computeLedgerHash = (ledgerHeader) => {
|
108 | const prefix = hash_prefix_1.default.LEDGER.toString(16).toUpperCase();
|
109 | return sha512Half_1.default(prefix +
|
110 | intToHex(ledgerHeader.ledger_index, 4) +
|
111 | bigintToHex(ledgerHeader.total_coins, 8) +
|
112 | ledgerHeader.parent_hash +
|
113 | ledgerHeader.transaction_hash +
|
114 | ledgerHeader.account_hash +
|
115 | intToHex(ledgerHeader.parent_close_time, 4) +
|
116 | intToHex(ledgerHeader.close_time, 4) +
|
117 | intToHex(ledgerHeader.close_time_resolution, 1) +
|
118 | intToHex(ledgerHeader.close_flags, 1));
|
119 | };
|
120 | exports.computeEscrowHash = (address, sequence) => {
|
121 | return sha512Half_1.default(ledgerSpaceHex('escrow') + addressToHex(address) + intToHex(sequence, 4));
|
122 | };
|
123 | exports.computePaymentChannelHash = (address, dstAddress, sequence) => {
|
124 | return sha512Half_1.default(ledgerSpaceHex('paychan') +
|
125 | addressToHex(address) +
|
126 | addressToHex(dstAddress) +
|
127 | intToHex(sequence, 4));
|
128 | };
|
129 |
|
\ | No newline at end of file |