diff --git a/apps/ecash-herald/config.js b/apps/ecash-herald/config.js --- a/apps/ecash-herald/config.js +++ b/apps/ecash-herald/config.js @@ -22,53 +22,4 @@ parse_mode: 'HTML', disable_web_page_preview: true, }, - knownMiners: [ - { - coinbaseScript: '566961425443', - miner: 'ViaBTC', - }, - { - coinbaseScript: '4d696e696e672d4475746368', - miner: 'Mining-Dutch', - }, - ], - opReturn: { - opReturnPrefix: '6a', - opReturnAppPrefixLength: '04', - opPushDataOne: '4c', - appPrefixes: { - '00746162': 'Cashtab Msg', - '2e786563': 'Alias', - }, - memo: { - 'prefix': '026d', - 'app': 'memo', - '01': 'Set name', - '02': 'Post memo', - '03': 'Reply to memo', - '04': 'Like / tip memo', - '05': 'Set profile text', - '06': 'Follow user', - '07': 'Unfollow user', - '0a': 'Set profile picture', - '0b': 'Repost memo', - '0c': 'Post topic message', - '0d': 'Topic follow', - '0e': 'Topic unfollow', - '10': 'Create poll', - '13': 'Add poll option', - '14': 'Poll vote', - '16': 'Mute user', - '17': 'Unmute user', - '24': 'Send money', - '30': 'Sell tokens Spec', - '31': 'Token buy offer Spec', - '32': 'Attach token sale signature Spec', - '35': 'Pin token post', - '20': 'Link request', - '21': 'Link accept', - '22': 'Link revoke', - '26': 'Set address alias', - }, - }, }; diff --git a/apps/ecash-herald/config.js b/apps/ecash-herald/constants.js copy from apps/ecash-herald/config.js copy to apps/ecash-herald/constants.js --- a/apps/ecash-herald/config.js +++ b/apps/ecash-herald/constants.js @@ -1,27 +1,15 @@ // Copyright (c) 2023 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. - 'use strict'; +/** + * constants.js + * App parameters that should require a diff to change, either because + * 1. changing them may require changes to unit tests, mocks, or other functions + * or + * 2. they aren't ever going to change + */ module.exports = { - chronik: 'https://chronik.fabien.cash', // URL of chronik instance - blockExplorer: 'https://explorer.e.cash', - priceApi: { - apiBase: 'https://api.coingecko.com/api/v3/simple/price', - cryptos: [ - { coingeckoSlug: 'ecash', ticker: 'XEC' }, - { coingeckoSlug: 'bitcoin', ticker: 'BTC' }, - { coingeckoSlug: 'ethereum', ticker: 'ETH' }, - ], - fiat: 'usd', - precision: 8, - }, - fiatReference: { usd: '$', jpy: '¥', eur: '€', gbp: '£' }, - ifpAddress: 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', - tgMsgOptions: { - parse_mode: 'HTML', - disable_web_page_preview: true, - }, knownMiners: [ { coinbaseScript: '566961425443', diff --git a/apps/ecash-herald/src/parse.js b/apps/ecash-herald/src/parse.js --- a/apps/ecash-herald/src/parse.js +++ b/apps/ecash-herald/src/parse.js @@ -4,6 +4,7 @@ 'use strict'; const config = require('../config'); +const constants = require('../constants'); const cashaddr = require('ecashaddrjs'); const BigNumber = require('bignumber.js'); const { @@ -39,7 +40,7 @@ return { hash, height, miner, numTxs, parsedTxs, tokenIds }; }, getMinerFromCoinbase: function (coinbaseHexString) { - const knownMiners = config.knownMiners; + const knownMiners = constants.knownMiners; let miner = 'unknown'; // Iterate over known miners to find a match for (let i = 0; i < knownMiners.length; i += 1) { @@ -160,7 +161,7 @@ // Don't parse OP_RETURN values of etoken txs, this info is available from chronik if ( thisOutput.outputScript.startsWith( - config.opReturn.opReturnPrefix, + constants.opReturn.opReturnPrefix, ) && !isTokenTx ) { @@ -229,7 +230,7 @@ // Determine if this is an OP_RETURN field const isOpReturn = - outputScript.slice(0, 2) === config.opReturn.opReturnPrefix; + outputScript.slice(0, 2) === constants.opReturn.opReturnPrefix; if (!isOpReturn) { return false; } @@ -237,7 +238,7 @@ // Determine if this is a memo tx // Memo txs have a shorter prefix and require special processing const isMemoTx = - outputScript.slice(2, 6) === config.opReturn.memo.prefix; + outputScript.slice(2, 6) === constants.opReturn.memo.prefix; if (isMemoTx) { // memo txs require special processing // Send the unprocessed remainder of the string to a specialized function @@ -248,12 +249,14 @@ // See https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/web/standards/op_return-prefix-guideline.md const hasAppPrefix = outputScript.slice(2, 4) === - config.opReturn.opReturnAppPrefixLength; + constants.opReturn.opReturnAppPrefixLength; if (hasAppPrefix) { const appPrefix = outputScript.slice(4, 12); - if (Object.keys(config.opReturn.appPrefixes).includes(appPrefix)) { - app = config.opReturn.appPrefixes[appPrefix]; + if ( + Object.keys(constants.opReturn.appPrefixes).includes(appPrefix) + ) { + app = constants.opReturn.appPrefixes[appPrefix]; } else { app = 'unknown app'; } @@ -300,7 +303,7 @@ // Check first byte for the message length or 4c + message length let byteValue = hexStr.slice(0, 2); let msgByteSize = 0; - if (byteValue === config.opReturn.opPushDataOne) { + if (byteValue === constants.opReturn.opPushDataOne) { // If this byte is 4c, then the next byte is the message byte size. // Retrieve the message byte size and convert from hex to decimal msgByteSize = parseInt(hexStr.substring(2, 4), 16); @@ -333,7 +336,7 @@ // Remove the memo prefix, already processed memoHexStr = memoHexStr.slice(6); // At the beginning of this function, we have already popped off '0d6d' - let app = config.opReturn.memo.app; + let app = constants.opReturn.memo.app; let msg = ''; for (let i = 0; memoHexStr !== 0; i++) { // Get the memo action code @@ -345,14 +348,16 @@ case '01' || '02' || '05' || '0a' || '0c' || '0d' || '0e': // Action codes where the entire string may be parsed to utf8 msg += `${ - config.opReturn.memo[actionCode] + constants.opReturn.memo[actionCode] }|${module.exports.hexOpReturnToUtf8(memoHexStr)}`; break; default: // parse the rest of the string like a normal op_return utf8 string msg += `${ - Object.keys(config.opReturn.memo).includes(actionCode) - ? config.opReturn.memo[actionCode] + Object.keys(constants.opReturn.memo).includes( + actionCode, + ) + ? constants.opReturn.memo[actionCode] : '' }|${module.exports.hexOpReturnToUtf8(memoHexStr)}`; } @@ -525,7 +530,7 @@ // Throw out OP_RETURN outputs for txs parsed as XEC send txs xecReceivingAddressOutputs.forEach((value, key, map) => { - if (key.startsWith(config.opReturn.opReturnPrefix)) { + if (key.startsWith(constants.opReturn.opReturnPrefix)) { map.delete(key); } }); diff --git a/apps/ecash-herald/test/mocks/memo.js b/apps/ecash-herald/test/mocks/memo.js --- a/apps/ecash-herald/test/mocks/memo.js +++ b/apps/ecash-herald/test/mocks/memo.js @@ -3,29 +3,29 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. 'use strict'; -const config = require('../../config'); +const constants = require('../../constants'); module.exports = [ // Set name { txid: '753e29e81cdea12dc5fa30ca89049ca7d538d4062c4bb1b19ecf2a209a3ac8d9', - action: config.opReturn.memo['01'], + action: constants.opReturn.memo['01'], outputScript: '6a026d0106746573742032', - parsed: `${config.opReturn.memo['01']}|test 2`, + parsed: `${constants.opReturn.memo['01']}|test 2`, }, // Post memo { txid: 'c7e91099923a28cf86685c9683c74c8c029c8965a5039f84ad79886b42720f9b', - action: config.opReturn.memo['02'], + action: constants.opReturn.memo['02'], outputScript: '6a026d02374c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e6720656c6974', - parsed: `${config.opReturn.memo['02']}|Lorem ipsum dolor sit amet, consectetur adipiscing elit`, + parsed: `${constants.opReturn.memo['02']}|Lorem ipsum dolor sit amet, consectetur adipiscing elit`, }, // Reply to memo, parsing not yet fully supported { txid: '28f3ec1f134dc8ea2e37a0645774fa2aa19e0bc2871b6edcc7e99cd86d77b1b6', - action: config.opReturn.memo['03'], + action: constants.opReturn.memo['03'], outputScript: '6a026d0320965689bc694d816ab0745b501c0e9dc8dbe7994a185fe37a37b808dc6b05750a4c8546726f6d20776861742049276d20676174686572696e672c206974207365656d73207468617420746865206d656469612077656e742066726f6d207175657374696f6e696e6720617574686f7269747920746f20646f696e672074686569722062696464696e67206173206120636f6c6c656374697665204e504320686976656d696e6421', - parsed: `${config.opReturn.memo['03']}|�V��iM�j�t[P\u001c\u000e����J\u0018_�z7�\b�k\u0005u\n|From what I'm gathering, it seems that the media went from questioning authority to doing their bidding as a collective NPC hivemind!`, + parsed: `${constants.opReturn.memo['03']}|�V��iM�j�t[P\u001c\u000e����J\u0018_�z7�\b�k\u0005u\n|From what I'm gathering, it seems that the media went from questioning authority to doing their bidding as a collective NPC hivemind!`, }, ]; diff --git a/apps/ecash-herald/test/parseTests.js b/apps/ecash-herald/test/parseTests.js --- a/apps/ecash-herald/test/parseTests.js +++ b/apps/ecash-herald/test/parseTests.js @@ -4,7 +4,7 @@ 'use strict'; const assert = require('assert'); -const config = require('../config'); +const constants = require('../constants'); const unrevivedBlocks = require('./mocks/blocks'); const { jsonReviver } = require('../src/utils'); const blocks = JSON.parse(JSON.stringify(unrevivedBlocks), jsonReviver); @@ -36,7 +36,7 @@ }); it(`parseMemoOutputScript correctly parses all tested memo actions in memo.js`, function () { memoOutputScripts.map(memoTestObj => { - const app = config.opReturn.memo.app; + const app = constants.opReturn.memo.app; const { outputScript, parsed } = memoTestObj; assert.deepEqual(parseMemoOutputScript(outputScript), { app,