diff --git a/CHANGELOG.md b/CHANGELOG.md index d993e99f..17ee14d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- added: Added eCash. + ## 3.7.0 (2025-04-15) - added: Added PIVX. diff --git a/src/common/utxobased/info/all.ts b/src/common/utxobased/info/all.ts index d523824e..67837cfd 100644 --- a/src/common/utxobased/info/all.ts +++ b/src/common/utxobased/info/all.ts @@ -11,6 +11,7 @@ import { info as dash } from './dash' import { info as digibyte } from './digibyte' import { info as dogecoin } from './dogecoin' import { info as eboost } from './eboost' +import { info as ecash } from './ecash' import { info as feathercoin } from './feathercoin' import { info as groestlcoin } from './groestlcoin' import { info as litecoin } from './litecoin' @@ -35,6 +36,7 @@ export { info as dash } from './dash' export { info as digibyte } from './digibyte' export { info as dogecoin } from './dogecoin' export { info as eboost } from './eboost' +export { info as ecash } from './ecash' export { info as feathercoin } from './feathercoin' export { info as groestlcoin } from './groestlcoin' export { info as litecoin } from './litecoin' @@ -60,6 +62,7 @@ export const all = [ digibyte, dogecoin, eboost, + ecash, feathercoin, groestlcoin, litecoin, diff --git a/src/common/utxobased/info/ecash.ts b/src/common/utxobased/info/ecash.ts new file mode 100644 index 00000000..9f1579a1 --- /dev/null +++ b/src/common/utxobased/info/ecash.ts @@ -0,0 +1,95 @@ +import { Psbt } from 'altcoin-js' +import { asCodec, asString } from 'cleaners' +import { EdgeCurrencyInfo } from 'edge-core-js/types' + +import { CoinInfo, EngineInfo, PluginInfo } from '../../plugin/types' +import { maximumFeeRateCalculator } from '../../plugin/util/maximumFeeRateCalculator' +import { + legacyMemoInfo, + utxoCustomFeeTemplate, + utxoMemoOptions +} from './commonInfo' + +const currencyInfo: EdgeCurrencyInfo = { + assetDisplayName: 'eCash', + chainDisplayName: 'eCash', + currencyCode: 'XEC', + customFeeTemplate: utxoCustomFeeTemplate, + memoOptions: utxoMemoOptions, + pluginId: 'ecash', + walletType: 'wallet:ecash', + + // Explorers: + blockExplorer: 'https://blockchair.com/ecash/block/%s', + addressExplorer: 'https://explorer.e.cash/address/ecash:%s', + transactionExplorer: 'https://explorer.e.cash/tx/%s', + + denominations: [ + { name: 'XEC', multiplier: '100', symbol: 'e' }, + { name: 'sats', multiplier: '1', symbol: 's' } + ], + // Deprecated: + ...legacyMemoInfo, + defaultSettings: { + customFeeSettings: ['satPerByte'], + blockbookServers: ['wss://blockbook.fabien.cash/websocket'], + enableCustomServers: false + }, + displayName: 'eCash', + metaTokens: [] +} + +const engineInfo: EngineInfo = { + serverConfigs: [ + { + type: 'blockbook-nownode', + uris: ['https://xec-blockbook.nownodes.io'] + } + ], + formats: ['bip44', 'bip32'], + gapLimit: 10, + feeUpdateInterval: 60000, + defaultFeeInfo: { + lowFeeFudgeFactor: '1', + standardFeeLowFudgeFactor: '1', + standardFeeHighFudgeFactor: '1', + highFeeFudgeFactor: '1', + + highFee: '20', + lowFee: '1', + standardFeeLow: '2', + standardFeeHigh: '20', + standardFeeLowAmount: '400000000', + standardFeeHighAmount: '650000000', + maximumFeeRate: maximumFeeRateCalculator(currencyInfo, 0.00003) + }, + asBlockbookAddress: asCodec( + raw => { + return asString(raw).split(':')[1] + }, + address => `ecash:${address}` + ) +} + +export const coinInfo: CoinInfo = { + name: 'ecash', + segwit: false, + sighash: Psbt.BCH_SIGHASH_ALL, + coinType: 899, + + prefixes: { + messagePrefix: ['\x18Bitcoin Signed Message::\n'], + wif: [0x80], + legacyXPriv: [0x0488ade4], + legacyXPub: [0x0488b21e], + pubkeyHash: [0x00], + scriptHash: [0x05], + cashaddr: ['ecash'] + } +} + +export const info: PluginInfo = { + currencyInfo, + engineInfo, + coinInfo +} diff --git a/test/common/utxobased/addressFormat/addressFormatIndex/fixtures.json b/test/common/utxobased/addressFormat/addressFormatIndex/fixtures.json index d370a0cd..0c38be56 100644 --- a/test/common/utxobased/addressFormat/addressFormatIndex/fixtures.json +++ b/test/common/utxobased/addressFormat/addressFormatIndex/fixtures.json @@ -440,6 +440,49 @@ "toLegacy": [], "toNewFormat": [] }, + { + "network": "ecash", + "valid": [ + "ecash:qpmq6uvs4sktft22lhlmsqpfr53hq03snc0s4nlwna", + "ecash:qrxcfwvkxumlnq28we8e9v0hjes45nw34gjjtvmlsw", + "ecash:qqp20qq7p89w9zmgmucl2cv4gqhk2usczsx4tw4zf3", + "ecash:qqpwwrwaazn747vvw25hyc8z89sh7k7dkv9yjj68pt", + "ecash:qzgyem0r2kxyajavqvce9ahk39dv92emtck9hkvdqa", + "ecash:qrqr0dfpf025jat7uk9axqm5r00sqsv6lyt40h0vv7", + "ecash:qz5dcpc4rqyal6v5xkt4jpj7jvfkgkt7yskj2za796", + "qpmq6uvs4sktft22lhlmsqpfr53hq03snc0s4nlwna", + "qrxcfwvkxumlnq28we8e9v0hjes45nw34gjjtvmlsw", + "qqp20qq7p89w9zmgmucl2cv4gqhk2usczsx4tw4zf3", + "qqpwwrwaazn747vvw25hyc8z89sh7k7dkv9yjj68pt", + "qzgyem0r2kxyajavqvce9ahk39dv92emtck9hkvdqa", + "qrqr0dfpf025jat7uk9axqm5r00sqsv6lyt40h0vv7", + "qz5dcpc4rqyal6v5xkt4jpj7jvfkgkt7yskj2za796" + ], + "invalid": [ + "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq", + "bc1qc7slrfxkknqcq2jevvvkdgvrt8080852dfjewde450xdlk4ugp7szw5tk9", + "XekiLaxnqpFb2m4NQAEcsKutZcZgcyfo6W", + "XiBQaGtW6y1C52YtPBD4PTMntpA9hkBq5p", + "XqWgAZEGdWDUhbS1YxSwxrK3GLGdJjSHus", + "XbtvGzi2JgjYTbTqabUjSREWeovDxznoyh", + "Xx9R3uriMAF2W71WH5kwpNdoHxqzGGih3c", + "Xm9TJiJ7nWjme8K7iEPUGsC5JjYGzPk2QU", + "XvwKzdsn46psqy6WhZ2wfhRPyRkD6GL2BG", + "LQL9pVH1LsMfKwt82Y2wGhNGkrjF8vwUst", + "LPpHectVSbk7YHa5X89Cm3FoFBfzkJBJc9", + "LRcYfbDMhwvXaGPFccaKuc3fZD1Nb55aGn", + "LY5fxZS74Ewuj1TTHwat23eUmZwimsksrU", + "LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL", + "Laub752qu81oWwkNKEyawyKruUC6cEyD2x", + "LbHBMZTQBq7aM5WS5TeKYJWH8pxeaLoRXe", + "LPpVeFSKvH593CChqP9qpV5toEXntekjiF", + "LfmG6qepmucU2aQaVJK4EJgBzQHeGz5ML4", + "MSS1jxX7vEjHi5ujzszwTsZCnSDhkWKrBd", + "M816EdyuvWV7oETCfQeZb5mGWm9nHczijH", + "MJiPwX84iBe4WnFDwsYGgtnz1XonPhUqhf" + ],"toLegacy": [], + "toNewFormat": [] + }, { "network": "feathercoin", "valid": [ diff --git a/test/common/utxobased/keymanager/coins/altcointestfixtures.ts b/test/common/utxobased/keymanager/coins/altcointestfixtures.ts index 59aba152..17d85409 100644 --- a/test/common/utxobased/keymanager/coins/altcointestfixtures.ts +++ b/test/common/utxobased/keymanager/coins/altcointestfixtures.ts @@ -330,6 +330,66 @@ export const fixtures: Fixture = { } ] }, + { + name: 'ecash', + mnemonic: + 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about', + seedToXPrivTests: [ + { + xpriv: + 'xprv9yBeEYevmwnuS3AsczyvenZkdSyFUHjUMx8jvaC5BE9RvswDGtzxSQDiFGfSBFPuAbR7LFJbnunBRfTUFzo3h2zbQKzmn6ZEZFL2q3gTouH', + type: BIP43PurposeTypeEnum.Legacy + } + ], + xprivToXPubTests: [ + { + xpriv: + 'xprv9yBeEYevmwnuS3AsczyvenZkdSyFUHjUMx8jvaC5BE9RvswDGtzxSQDiFGfSBFPuAbR7LFJbnunBRfTUFzo3h2zbQKzmn6ZEZFL2q3gTouH', + type: BIP43PurposeTypeEnum.Legacy, + xpub: + 'xpub6CAze4BpcKMCeXFLj2Ww1vWVBUojskTKjB4LixbgjZgQogGMpSKCzCYC6a7MnX9Pi2E7WREFVegFcSaKqSeSnk5sdnHETA8sfK3qUQPP7PY' + } + ], + xpubToPubkeyTests: [ + { + xpub: + 'xpub6CAze4BpcKMCeXFLj2Ww1vWVBUojskTKjB4LixbgjZgQogGMpSKCzCYC6a7MnX9Pi2E7WREFVegFcSaKqSeSnk5sdnHETA8sfK3qUQPP7PY', + type: BIP43PurposeTypeEnum.Legacy, + bip44ChangeIndex: 0, + bip44AddressIndex: 0, + scriptType: ScriptTypeEnum.p2pkh, + addressType: AddressTypeEnum.p2pkh, + address: 'qpluxjhhlxfjwsymf9nmctvsdrwzwygadsh2pq0ang', + legacyAddress: '1CeYmYk9KJGBNES5mzosy1wceZcQePcYNa' + } + ], + wifToPrivateKeyTests: [ + { + wifKey: 'L1Sdqjg1VSALZfHLLgqnFbEU5gnoVoY1ZDwJtRSKwRLPjwBN6K8v' + } + ], + addressToScriptPubkeyTests: [ + { + address: 'ecash:qpd9vwa8pyqrkh52znpee2nrp4czcn9k3yupckwzla', + scriptPubkey: '76a9145a563ba709003b5e8a14c39caa630d702c4cb68988ac' + }, + { + extraMessage: 'without prefix', + address: 'qpd9vwa8pyqrkh52znpee2nrp4czcn9k3yupckwzla', + scriptPubkey: '76a9145a563ba709003b5e8a14c39caa630d702c4cb68988ac' + }, + { + extraMessage: 'p2sh', + address: 'ecash:pryec382ctn0wlysa5vjkxx27wru7s8mf5lmgc96p8', + scriptPubkey: 'a914c99c44eac2e6f77c90ed192b18caf387cf40fb4d87' + }, + { + extraMessage: 'p2sh without prefix', + address: 'pryec382ctn0wlysa5vjkxx27wru7s8mf5lmgc96p8', + scriptPubkey: 'a914c99c44eac2e6f77c90ed192b18caf387cf40fb4d87' + } + ] + }, { name: 'dash', mnemonic: