diff --git a/CHANGELOG.md b/CHANGELOG.md index 5653df9bf..a87374643 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,11 @@ ## Unreleased +- added: (Solana/Ethereum) Add optional `lightMode` support to disable transaction query +- added: Add optional `testPrivateKeys` function to `parseUriCommon` - changed: (Zcash) Updated address explorer - changed: (Tron) Special case the `usdt-trc20` uri prefix +- changed: Upgrade edge-core-js to v2.9.0 - fixed: Prevent fatal error reporting for missing txlist json file - fixed: (Zcash) Use additional insufficient funds check before sending amount to synchronizer diff --git a/package.json b/package.json index 2e3479b8a..baae2b246 100644 --- a/package.json +++ b/package.json @@ -135,7 +135,7 @@ "chai": "^4.2.0", "clipanion": "^4.0.0-rc.2", "crypto-browserify": "^3.12.0", - "edge-core-js": "^2.5.0", + "edge-core-js": "^2.9.0", "esbuild-loader": "^2.20.0", "eslint": "^8.19.0", "eslint-config-standard-kit": "0.15.1", diff --git a/src/algorand/AlgorandTools.ts b/src/algorand/AlgorandTools.ts index a74d6fcf3..2be7d19dc 100644 --- a/src/algorand/AlgorandTools.ts +++ b/src/algorand/AlgorandTools.ts @@ -92,14 +92,14 @@ export class AlgorandTools implements EdgeCurrencyTools { const { pluginId } = this.currencyInfo const networks = { [pluginId]: true } - const { parsedUri, edgeParsedUri } = parseUriCommon( - this.currencyInfo, + const { parsedUri, edgeParsedUri } = await parseUriCommon({ + currencyInfo: this.currencyInfo, uri, networks, - this.builtinTokens, - currencyCode ?? this.currencyInfo.currencyCode, + builtinTokens: this.builtinTokens, + currencyCode: currencyCode ?? this.currencyInfo.currencyCode, customTokens - ) + }) let address = '' diff --git a/src/binance/BinanceTools.ts b/src/binance/BinanceTools.ts index 30de9f6ce..bac11eb1c 100644 --- a/src/binance/BinanceTools.ts +++ b/src/binance/BinanceTools.ts @@ -101,14 +101,14 @@ export class BinanceTools implements EdgeCurrencyTools { ): Promise { const networks = { binance: true } - const { parsedUri, edgeParsedUri } = parseUriCommon( - this.currencyInfo, + const { parsedUri, edgeParsedUri } = await parseUriCommon({ + currencyInfo: this.currencyInfo, uri, networks, - this.builtinTokens, - currencyCode ?? 'BNB', + builtinTokens: this.builtinTokens, + currencyCode: currencyCode ?? 'BNB', customTokens - ) + }) const address = edgeParsedUri.publicAddress ?? '' const valid = checkAddress(address, 'bnb') diff --git a/src/cardano/CardanoTools.ts b/src/cardano/CardanoTools.ts index 40deddc27..6d1c2ed57 100644 --- a/src/cardano/CardanoTools.ts +++ b/src/cardano/CardanoTools.ts @@ -146,14 +146,14 @@ export class CardanoTools implements EdgeCurrencyTools { ): Promise { const networks = { cardano: true } - const { parsedUri, edgeParsedUri } = parseUriCommon( - this.currencyInfo, + const { parsedUri, edgeParsedUri } = await parseUriCommon({ + currencyInfo: this.currencyInfo, uri, networks, - this.builtinTokens, - currencyCode ?? 'ADA', + builtinTokens: this.builtinTokens, + currencyCode: currencyCode ?? 'ADA', customTokens - ) + }) Cardano.Address.from_bech32(edgeParsedUri.publicAddress ?? '') diff --git a/src/common/CurrencyEngine.ts b/src/common/CurrencyEngine.ts index 2ca4231de..3f7a3473d 100644 --- a/src/common/CurrencyEngine.ts +++ b/src/common/CurrencyEngine.ts @@ -25,7 +25,11 @@ import { } from 'edge-core-js/types' import { PluginEnvironment } from './innerPlugin' -import { makeMetaTokens, validateToken } from './tokenHelpers' +import { + getTokenIdFromCurrencyCode, + makeMetaTokens, + validateToken +} from './tokenHelpers' import { asWalletLocalData, DATA_STORE_FILE, @@ -568,7 +572,13 @@ export class CurrencyEngine< this.walletLocalData.totalBalances[currencyCode] = balance this.walletLocalDataDirty = true this.warn(`${currencyCode}: token Address balance: ${balance}`) - this.currencyEngineCallbacks.onBalanceChanged(currencyCode, balance) + const tokenId = getTokenIdFromCurrencyCode( + currencyCode, + this.currencyInfo.currencyCode, + this.allTokensMap + ) + if (tokenId === undefined) return + this.currencyEngineCallbacks.onTokenBalanceChanged(tokenId, balance) } this.tokenCheckBalanceStatus[currencyCode] = 1 this.updateOnAddressesChecked() @@ -634,8 +644,14 @@ export class CurrencyEngine< protected doInitialBalanceCallback(): void { for (const currencyCode of this.enabledTokens) { try { - this.currencyEngineCallbacks.onBalanceChanged( + const tokenId = getTokenIdFromCurrencyCode( currencyCode, + this.currencyInfo.currencyCode, + this.allTokensMap + ) + if (tokenId === undefined) continue + this.currencyEngineCallbacks.onTokenBalanceChanged( + tokenId, this.walletLocalData.totalBalances[currencyCode] ?? '0' ) } catch (e: any) { diff --git a/src/common/tokenHelpers.ts b/src/common/tokenHelpers.ts index fb9f7eada..8b1d44a73 100644 --- a/src/common/tokenHelpers.ts +++ b/src/common/tokenHelpers.ts @@ -1,6 +1,11 @@ import { gt, lt } from 'biggystring' import { asMaybe, asObject, asString } from 'cleaners' -import { EdgeMetaToken, EdgeToken, EdgeTokenMap } from 'edge-core-js/types' +import { + EdgeMetaToken, + EdgeToken, + EdgeTokenId, + EdgeTokenMap +} from 'edge-core-js/types' /** * The `networkLocation` field is untyped, @@ -35,8 +40,10 @@ export function makeMetaTokens(tokens: EdgeTokenMap): EdgeMetaToken[] { export const getTokenIdFromCurrencyCode = ( currencyCode: string, + mainnetCurrencyCode: string, allTokensMap: EdgeTokenMap -): string | undefined => { +): EdgeTokenId | undefined => { + if (currencyCode === mainnetCurrencyCode) return null for (const tokenId of Object.keys(allTokensMap)) { if (allTokensMap[tokenId].currencyCode === currencyCode) return tokenId } diff --git a/src/common/uriHelpers.ts b/src/common/uriHelpers.ts index 6b1a20d31..6e2a0d082 100644 --- a/src/common/uriHelpers.ts +++ b/src/common/uriHelpers.ts @@ -4,7 +4,8 @@ import { EdgeEncodeUri, EdgeMetaToken, EdgeParsedUri, - EdgeTokenMap + EdgeTokenMap, + JsonObject } from 'edge-core-js/types' import { serialize } from 'uri-js' import parse from 'url-parse' @@ -13,14 +14,25 @@ import { getLegacyDenomination } from './utils' type ParsedUri = parse> -export function parseUriCommon( - currencyInfo: EdgeCurrencyInfo, - uri: string, - networks: { [network: string]: boolean }, - builtinTokens: EdgeTokenMap, - currencyCode?: string, - customTokens: EdgeMetaToken[] = [] -): { edgeParsedUri: EdgeParsedUri; parsedUri: ParsedUri } { +export async function parseUriCommon(opts: { + currencyInfo: EdgeCurrencyInfo + uri: string + networks: { [network: string]: boolean } + builtinTokens: EdgeTokenMap + currencyCode?: string + customTokens?: EdgeMetaToken[] + testPrivateKeys?: (input: string) => Promise +}): Promise<{ edgeParsedUri: EdgeParsedUri; parsedUri: ParsedUri }> { + const { + currencyInfo, + uri, + networks, + builtinTokens, + customTokens = [], + testPrivateKeys + } = opts + let { currencyCode } = opts + const parsedUri = { ...parse(uri, {}, true) } // Add support for renproject Gateway URI type @@ -90,6 +102,14 @@ export function parseUriCommon( edgeParsedUri.currencyCode = currencyCode } + if (testPrivateKeys != null) { + try { + await testPrivateKeys(uri) + edgeParsedUri.privateKeys = [uri] + edgeParsedUri.publicAddress = undefined + } catch (e) {} + } + return { edgeParsedUri, parsedUri } } diff --git a/src/cosmos/CosmosTools.ts b/src/cosmos/CosmosTools.ts index 81538c22d..cc9227d54 100644 --- a/src/cosmos/CosmosTools.ts +++ b/src/cosmos/CosmosTools.ts @@ -168,14 +168,14 @@ export class CosmosTools implements EdgeCurrencyTools { const { pluginId } = this.currencyInfo const networks = { [pluginId]: true } - const { parsedUri, edgeParsedUri } = parseUriCommon( - this.currencyInfo, + const { parsedUri, edgeParsedUri } = await parseUriCommon({ + currencyInfo: this.currencyInfo, uri, networks, - this.builtinTokens, - currencyCode ?? this.currencyInfo.currencyCode, + builtinTokens: this.builtinTokens, + currencyCode: currencyCode ?? this.currencyInfo.currencyCode, customTokens - ) + }) let address = '' diff --git a/src/declare-modules.d.ts b/src/declare-modules.d.ts index ec3cdada2..c2d6f6426 100644 --- a/src/declare-modules.d.ts +++ b/src/declare-modules.d.ts @@ -1,10 +1,46 @@ declare module 'eosjs-ecc' declare module 'ethereumjs-abi' -declare module 'ethereumjs-util' declare module 'ethereumjs-wallet' declare module 'ethereumjs-wallet/hdkey' declare module 'eztz.js' +declare module 'ethereumjs-util' { + export const isValidAddress: (address: string) => boolean + export const isValidChecksumAddress: (address: string) => boolean + export const isValidPrivate: (privateKeyBuffer: Buffer) => boolean + export const toChecksumAddress: (address: string) => string + export const pubToAddress: ( + pubKey: Buffer | Uint8Array, + sanitize?: boolean + ) => Buffer | Uint8Array + export const privateToAddress: ( + privateKey: Buffer | Uint8Array + ) => Buffer | Uint8Array + + export const hashPersonalMessage: ( + message: Buffer | Uint8Array | any[] + ) => Buffer | Uint8Array + export const ecsign: ( + msgHash: Buffer | Uint8Array, + privateKey: Buffer | Uint8Array + ) => { [k: string]: any } + export const toRpcSig: ( + v: number, + r: Buffer | Uint8Array, + s: Buffer | Uint8Array + ) => string + export const keccak256: ( + a: Buffer | Uint8Array | any[] | string | number + ) => Buffer | Uint8Array + export const bufferToHex: (buf: Buffer | Uint8Array) => string + export const setLengthLeft: ( + msg: Buffer | Uint8Array, + length: number, + right?: boolean + ) => Buffer | Uint8Array + export const toBuffer: (v: any) => Buffer | Uint8Array +} + declare module 'react-native' { export const NativeModules: { EdgeCurrencyAccountbasedModule: { diff --git a/src/eos/EosTools.ts b/src/eos/EosTools.ts index 28365c1d4..7f2b43e90 100644 --- a/src/eos/EosTools.ts +++ b/src/eos/EosTools.ts @@ -155,14 +155,14 @@ export class EosTools implements EdgeCurrencyTools { } async parseUri(uri: string): Promise { - const { edgeParsedUri } = parseUriCommon( - this.currencyInfo, + const { edgeParsedUri } = await parseUriCommon({ + currencyInfo: this.currencyInfo, uri, - { + networks: { [this.networkInfo.uriProtocol]: true }, - this.builtinTokens - ) + builtinTokens: this.builtinTokens + }) if (!checkAddress(edgeParsedUri.publicAddress ?? '')) { throw new Error('InvalidPublicAddressError') diff --git a/src/ethereum/EthereumEngine.ts b/src/ethereum/EthereumEngine.ts index 7d5a9ebc9..fb654ef51 100644 --- a/src/ethereum/EthereumEngine.ts +++ b/src/ethereum/EthereumEngine.ts @@ -95,6 +95,7 @@ export class EthereumEngine extends CurrencyEngine< SafeEthWalletInfo > { otherData!: EthereumWalletOtherData + lightMode: boolean initOptions: EthereumInitOptions networkInfo: EthereumNetworkInfo ethNetwork: EthereumNetwork @@ -113,6 +114,7 @@ export class EthereumEngine extends CurrencyEngine< currencyInfo: EdgeCurrencyInfo ) { super(env, tools, walletInfo, opts) + this.lightMode = opts.lightMode ?? false this.initOptions = initOptions this.networkInfo = env.networkInfo this.ethNetwork = new EthereumNetwork(this) @@ -991,7 +993,7 @@ export class EthereumEngine extends CurrencyEngine< if (publicAddress == null) throw new Error('makeSpend Missing publicAddress') if (nativeAmount == null) throw new NoAmountSpecifiedError() - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions + if (!EthereumUtil.isValidAddress(publicAddress)) { throw new TypeError(`Invalid ${this.currencyInfo.pluginId} address`) } diff --git a/src/ethereum/EthereumNetwork.ts b/src/ethereum/EthereumNetwork.ts index 57b90e7e0..6135d692f 100644 --- a/src/ethereum/EthereumNetwork.ts +++ b/src/ethereum/EthereumNetwork.ts @@ -377,14 +377,26 @@ export class EthereumNetwork { // Send an empty tokenTxs network update if no network adapters // qualify for 'fetchTxs': - if (this.qualifyNetworkAdapters('fetchTxs').length === 0) { + if ( + this.qualifyNetworkAdapters('fetchTxs').length === 0 || + this.ethEngine.lightMode + ) { + const tokenTxs: { + [currencyCode: string]: EdgeTransactionsBlockHeightTuple + } = { + [this.ethEngine.currencyInfo.currencyCode]: { + blockHeight: params.startBlock, + edgeTransactions: [] + } + } + for (const token of Object.values(this.ethEngine.allTokensMap)) { + tokenTxs[token.currencyCode] = { + blockHeight: params.startBlock, + edgeTransactions: [] + } + } return { - tokenTxs: { - [this.ethEngine.currencyInfo.currencyCode]: { - blockHeight: params.startBlock, - edgeTransactions: [] - } - }, + tokenTxs, server: 'none' } } diff --git a/src/ethereum/EthereumTools.ts b/src/ethereum/EthereumTools.ts index 74f163ef5..ccaa06aef 100644 --- a/src/ethereum/EthereumTools.ts +++ b/src/ethereum/EthereumTools.ts @@ -70,7 +70,6 @@ export class EthereumTools implements EdgeCurrencyTools { if (/^(0x)?[0-9a-fA-F]{64}$/.test(userInput)) { // It looks like a private key, so validate the hex: const keyBuffer = Buffer.from(userInput.replace(/^0x/, ''), 'hex') - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (!EthereumUtil.isValidPrivate(keyBuffer)) { throw new Error('Invalid private key') } @@ -80,8 +79,7 @@ export class EthereumTools implements EdgeCurrencyTools { const keys = { [pluginRegularKeyName]: hexKey } - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.derivePublicKey({ + await this.derivePublicKey({ type: `wallet:${pluginId}`, id: 'fake', keys @@ -146,13 +144,12 @@ export class EthereumTools implements EdgeCurrencyTools { walletInfo.keys[pluginRegularKeyName].replace(/^0x/, ''), 'hex' ) - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (!EthereumUtil.isValidPrivate(keyBuffer)) { throw new Error('Invalid private key') } address = `0x${EthereumUtil.privateToAddress(keyBuffer).toString('hex')}` } - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions + if (!EthereumUtil.isValidAddress(address)) { throw new Error('Invalid address') } @@ -179,26 +176,30 @@ export class EthereumTools implements EdgeCurrencyTools { networks[network] = true }) - const { parsedUri, edgeParsedUri } = parseUriCommon( - this.currencyInfo, + const { parsedUri, edgeParsedUri } = await parseUriCommon({ + currencyInfo: this.currencyInfo, uri, networks, - this.builtinTokens, - currencyCode ?? this.currencyInfo.currencyCode, - customTokens - ) + builtinTokens: this.builtinTokens, + currencyCode: currencyCode ?? this.currencyInfo.currencyCode, + customTokens, + testPrivateKeys: this.importPrivateKey.bind(this) + }) + + if (edgeParsedUri.privateKeys != null) { + return edgeParsedUri + } let address = '' - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - if (edgeParsedUri.publicAddress) { + if (edgeParsedUri.publicAddress != null) { address = edgeParsedUri.publicAddress edgeParsedUri.publicAddress = edgeParsedUri.publicAddress.toLowerCase() } let [prefix, contractAddress] = address.split('-') // Split the address to get the prefix according to EIP-681 // If contractAddress is null or undefined it means there is no prefix - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - if (!contractAddress) { + + if (contractAddress == null) { contractAddress = prefix // Set the contractAddress to be the prefix when the prefix is missing. prefix = 'pay' // The default prefix according to EIP-681 is "pay" } @@ -207,7 +208,6 @@ export class EthereumTools implements EdgeCurrencyTools { // Verify checksum if it's present in the address if ( /[A-F]/.test(address) && - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions !EthereumUtil.isValidChecksumAddress(address) ) { throw new Error('InvalidPublicAddressError') @@ -215,24 +215,20 @@ export class EthereumTools implements EdgeCurrencyTools { // Verify address is valid address = address.toLowerCase() - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - if (!EthereumUtil.isValidAddress(address || '')) { + if (!EthereumUtil.isValidAddress(address)) { throw new Error('InvalidPublicAddressError') } // Parse according to EIP-961 if (prefix === 'token' || prefix === 'token_info') { - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - if (!parsedUri.query) throw new Error('InvalidUriError') + if (parsedUri.query == null) throw new Error('InvalidUriError') - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions const currencyCode = parsedUri.query.symbol ?? 'SYM' if (currencyCode.length < 2 || currencyCode.length > 5) { throw new Error('Wrong Token symbol') } - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions + const currencyName = parsedUri.query.name ?? currencyCode - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions const decimalsInput = parsedUri.query.decimals ?? '18' let multiplier = '1000000000000000000' const decimals = parseInt(decimalsInput) @@ -290,11 +286,9 @@ export class EthereumTools implements EdgeCurrencyTools { } // Validate addresses - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (!EthereumUtil.isValidAddress(publicAddress)) { throw new Error('InvalidPublicAddressError') } - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (!EthereumUtil.isValidAddress(contractAddress)) { throw new Error('InvalidContractAddressError') } @@ -331,7 +325,6 @@ export class EthereumTools implements EdgeCurrencyTools { ): Promise { const { publicAddress, nativeAmount, currencyCode } = obj const valid = EthereumUtil.isValidAddress(publicAddress) - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (!valid) { throw new Error('InvalidPublicAddressError') } @@ -352,7 +345,6 @@ export class EthereumTools implements EdgeCurrencyTools { return encodedUri } - // eslint-disable-next-line @typescript-eslint/no-unused-vars getSplittableTypes(walletInfo: EdgeWalletInfo): string[] { return Object.keys(ethereumPlugins).map(plugin => `wallet:${plugin}`) } @@ -362,7 +354,6 @@ export class EthereumTools implements EdgeCurrencyTools { const cleanLocation = asMaybeContractLocation(token.networkLocation) if ( cleanLocation == null || - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions !EthereumUtil.isValidAddress(cleanLocation.contractAddress) ) { throw new Error('ErrorInvalidContractAddress') diff --git a/src/filecoin/FilecoinTools.ts b/src/filecoin/FilecoinTools.ts index 079c2b927..047f321f8 100644 --- a/src/filecoin/FilecoinTools.ts +++ b/src/filecoin/FilecoinTools.ts @@ -60,14 +60,12 @@ export class FilecoinTools implements EdgeCurrencyTools { // Verify checksum if it's present in the address if ( /[A-F]/.test(addressString) && - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions !EthereumUtil.isValidChecksumAddress(addressString) ) { return false } - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - if (!EthereumUtil.isValidAddress(addressString.toLowerCase() || '')) { + if (!EthereumUtil.isValidAddress(addressString.toLowerCase() ?? '')) { return false } } @@ -171,14 +169,14 @@ export class FilecoinTools implements EdgeCurrencyTools { const { edgeParsedUri, edgeParsedUri: { publicAddress } - } = parseUriCommon( - this.currencyInfo, + } = await parseUriCommon({ + currencyInfo: this.currencyInfo, uri, networks, - this.builtinTokens, - currencyCode ?? this.currencyInfo.currencyCode, + builtinTokens: this.builtinTokens, + currencyCode: currencyCode ?? this.currencyInfo.currencyCode, customTokens - ) + }) if (publicAddress == null || !this.isValidAddress(publicAddress)) { throw new Error('InvalidPublicAddressError') diff --git a/src/fio/FioTools.ts b/src/fio/FioTools.ts index 5885c9aa3..5cf1dfce4 100644 --- a/src/fio/FioTools.ts +++ b/src/fio/FioTools.ts @@ -150,15 +150,13 @@ export class FioTools implements EdgeCurrencyTools { } async parseUri(uri: string): Promise { - const { edgeParsedUri } = parseUriCommon( - this.currencyInfo, + const { edgeParsedUri } = await parseUriCommon({ + currencyInfo: this.currencyInfo, uri, - { - fio: true - }, - this.builtinTokens, - FIO_CURRENCY_CODE - ) + networks: { fio: true }, + builtinTokens: this.builtinTokens, + currencyCode: FIO_CURRENCY_CODE + }) const valid = checkAddress(edgeParsedUri.publicAddress ?? '') if (!valid) { throw new Error('InvalidPublicAddressError') diff --git a/src/hedera/HederaTools.ts b/src/hedera/HederaTools.ts index 9b2195b3b..0af123a66 100644 --- a/src/hedera/HederaTools.ts +++ b/src/hedera/HederaTools.ts @@ -143,13 +143,13 @@ export class HederaTools implements EdgeCurrencyTools { const { edgeParsedUri, edgeParsedUri: { publicAddress } - } = parseUriCommon( - this.currencyInfo, + } = await parseUriCommon({ + currencyInfo: this.currencyInfo, uri, - { [`${pluginId}`]: true }, - this.builtinTokens, - this.currencyInfo.currencyCode - ) + networks: { [`${pluginId}`]: true }, + builtinTokens: this.builtinTokens, + currencyCode: this.currencyInfo.currencyCode + }) if (publicAddress != null) { const { checksumNetworkID } = this.networkInfo diff --git a/src/piratechain/PiratechainTools.ts b/src/piratechain/PiratechainTools.ts index 79b960211..89f958ff9 100644 --- a/src/piratechain/PiratechainTools.ts +++ b/src/piratechain/PiratechainTools.ts @@ -162,14 +162,14 @@ export class PiratechainTools implements EdgeCurrencyTools { const { edgeParsedUri, edgeParsedUri: { publicAddress } - } = parseUriCommon( - this.currencyInfo, + } = await parseUriCommon({ + currencyInfo: this.currencyInfo, uri, networks, - this.builtinTokens, - currencyCode ?? this.currencyInfo.currencyCode, + builtinTokens: this.builtinTokens, + currencyCode: currencyCode ?? this.currencyInfo.currencyCode, customTokens - ) + }) if (publicAddress == null || !(await this.isValidAddress(publicAddress))) { throw new Error('InvalidPublicAddressError') diff --git a/src/polkadot/PolkadotTools.ts b/src/polkadot/PolkadotTools.ts index c9eed958d..6fcfbeb9a 100644 --- a/src/polkadot/PolkadotTools.ts +++ b/src/polkadot/PolkadotTools.ts @@ -107,14 +107,14 @@ export class PolkadotTools implements EdgeCurrencyTools { const { pluginId } = this.currencyInfo const networks = { [pluginId]: true } - const { parsedUri, edgeParsedUri } = parseUriCommon( - this.currencyInfo, + const { parsedUri, edgeParsedUri } = await parseUriCommon({ + currencyInfo: this.currencyInfo, uri, networks, - this.builtinTokens, - currencyCode ?? this.currencyInfo.currencyCode, + builtinTokens: this.builtinTokens, + currencyCode: currencyCode ?? this.currencyInfo.currencyCode, customTokens - ) + }) const address = edgeParsedUri.publicAddress ?? '' if (!isAddress(address)) { diff --git a/src/ripple/RippleEngine.ts b/src/ripple/RippleEngine.ts index af3d3127f..8a3a6afdd 100644 --- a/src/ripple/RippleEngine.ts +++ b/src/ripple/RippleEngine.ts @@ -671,6 +671,7 @@ export class XrpEngine extends CurrencyEngine< if (match == null) { const tokenId = getTokenIdFromCurrencyCode( tokenCurrencyCode, + this.currencyInfo.currencyCode, this.allTokensMap ) if (tokenId != null) { @@ -688,6 +689,7 @@ export class XrpEngine extends CurrencyEngine< // All tokens are not activated if this address is not activated const tokenId = getTokenIdFromCurrencyCode( tokenCurrencyCode, + this.currencyInfo.currencyCode, this.allTokensMap ) if (tokenId != null) { @@ -883,6 +885,7 @@ export class XrpEngine extends CurrencyEngine< } else { const tokenId = getTokenIdFromCurrencyCode( currencyCode, + this.currencyInfo.currencyCode, this.allTokensMap ) if (tokenId == null) { @@ -1059,7 +1062,7 @@ export class XrpEngine extends CurrencyEngine< `Must specify activateTokenIds for ${this.currencyInfo.currencyCode}` ) const { wallet, tokenId } = paymentInfo ?? { tokenId: null } - if (tokenId != null) + if (tokenId !== null) throw new Error(`Must activate with ${this.currencyInfo.currencyCode}`) if (wallet?.id !== this.walletId) throw new Error('Must pay with same wallet you are activating token with') diff --git a/src/ripple/RippleTools.ts b/src/ripple/RippleTools.ts index 8f311ad26..75734961b 100644 --- a/src/ripple/RippleTools.ts +++ b/src/ripple/RippleTools.ts @@ -153,12 +153,12 @@ export class RippleTools implements EdgeCurrencyTools { } } - const { parsedUri, edgeParsedUri } = parseUriCommon( - this.currencyInfo, + const { parsedUri, edgeParsedUri } = await parseUriCommon({ + currencyInfo: this.currencyInfo, uri, networks, - this.builtinTokens - ) + builtinTokens: this.builtinTokens + }) const valid = isValidAddress(edgeParsedUri.publicAddress ?? '') if (!valid) { throw new Error('InvalidPublicAddressError') diff --git a/src/solana/SolanaEngine.ts b/src/solana/SolanaEngine.ts index 8570f7d6e..8e036f1c1 100644 --- a/src/solana/SolanaEngine.ts +++ b/src/solana/SolanaEngine.ts @@ -74,6 +74,7 @@ export class SolanaEngine extends CurrencyEngine< SolanaTools, SafeSolanaWalletInfo > { + lightMode: boolean networkInfo: SolanaNetworkInfo base58PublicKey: string feePerSignature: string @@ -90,9 +91,10 @@ export class SolanaEngine extends CurrencyEngine< env: PluginEnvironment, tools: SolanaTools, walletInfo: SafeSolanaWalletInfo, - opts: any // EdgeCurrencyEngineOptions + opts: EdgeCurrencyEngineOptions ) { super(env, tools, walletInfo, opts) + this.lightMode = opts.lightMode ?? false this.networkInfo = env.networkInfo this.chainCode = tools.currencyInfo.currencyCode this.fetchCors = getFetchCors(env.io) @@ -194,7 +196,7 @@ export class SolanaEngine extends CurrencyEngine< const balance = tokenBal?.result?.value?.amount ?? '0' this.updateBalance(this.allTokensMap[tokenId].currencyCode, balance) - if (gt(balance, '0') && !this.enabledTokenIds.includes(tokenId)) { + if (gt(balance, '0')) { detectedTokenIds.push(tokenId) } } @@ -547,9 +549,16 @@ export class SolanaEngine extends CurrencyEngine< this.queryBlockhash().catch(() => {}) this.addToLoop('queryBalance', ACCOUNT_POLL_MILLISECONDS).catch(() => {}) - this.addToLoop('queryTransactions', TRANSACTION_POLL_MILLISECONDS).catch( - () => {} - ) + if (this.lightMode) { + this.tokenCheckTransactionsStatus[this.currencyInfo.currencyCode] = 1 + for (const edgeToken of Object.values(this.allTokensMap)) { + this.tokenCheckTransactionsStatus[edgeToken.currencyCode] = 1 + } + } else { + this.addToLoop('queryTransactions', TRANSACTION_POLL_MILLISECONDS).catch( + () => {} + ) + } await super.startEngine() } diff --git a/src/solana/SolanaTools.ts b/src/solana/SolanaTools.ts index 3752e35ff..e25ed6c08 100644 --- a/src/solana/SolanaTools.ts +++ b/src/solana/SolanaTools.ts @@ -128,21 +128,26 @@ export class SolanaTools implements EdgeCurrencyTools { const { pluginId } = this.currencyInfo const networks = { [pluginId]: true } - const { parsedUri, edgeParsedUri } = parseUriCommon( - this.currencyInfo, + const { parsedUri, edgeParsedUri } = await parseUriCommon({ + currencyInfo: this.currencyInfo, uri, networks, - this.builtinTokens, - currencyCode ?? this.currencyInfo.currencyCode, - customTokens - ) - let address = '' - if (edgeParsedUri.publicAddress != null) { - address = edgeParsedUri.publicAddress + builtinTokens: this.builtinTokens, + currencyCode: currencyCode ?? this.currencyInfo.currencyCode, + customTokens, + testPrivateKeys: this.importPrivateKey.bind(this) + }) + + if (edgeParsedUri.privateKeys != null) { + return edgeParsedUri } - if (!PublicKey.isOnCurve(new PublicKey(address).toBytes())) + if ( + edgeParsedUri.publicAddress != null && + !PublicKey.isOnCurve(new PublicKey(edgeParsedUri.publicAddress).toBytes()) + ) { throw new Error('InvalidPublicAddressError') + } edgeParsedUri.uniqueIdentifier = parsedUri.query.memo return edgeParsedUri diff --git a/src/stellar/StellarTools.ts b/src/stellar/StellarTools.ts index 6a29e1973..2c8cad424 100644 --- a/src/stellar/StellarTools.ts +++ b/src/stellar/StellarTools.ts @@ -139,12 +139,12 @@ export class StellarTools implements EdgeCurrencyTools { } } - const { parsedUri, edgeParsedUri } = parseUriCommon( - this.currencyInfo, + const { parsedUri, edgeParsedUri } = await parseUriCommon({ + currencyInfo: this.currencyInfo, uri, networks, - this.builtinTokens - ) + builtinTokens: this.builtinTokens + }) // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/prefer-nullish-coalescing const valid = this.checkAddress(edgeParsedUri.publicAddress || '') diff --git a/src/tezos/TezosTools.ts b/src/tezos/TezosTools.ts index 928f6d686..0f8bc4eb5 100644 --- a/src/tezos/TezosTools.ts +++ b/src/tezos/TezosTools.ts @@ -11,6 +11,7 @@ import { eztz } from 'eztz.js' import { decodeMainnet, encodeMainnet } from 'tezos-uri' import { PluginEnvironment } from '../common/innerPlugin' +import { parseUriCommon } from '../common/uriHelpers' import { mergeDeeply } from '../common/utils' import { asSafeTezosWalletInfo, @@ -108,6 +109,17 @@ export class TezosTools implements EdgeCurrencyTools { } async parseUri(uri: string): Promise { + const { currencyCode, pluginId } = this.currencyInfo + const networks = { [pluginId]: true, 'web+tezos': true } + + const { edgeParsedUri } = await parseUriCommon({ + currencyInfo: this.currencyInfo, + uri, + networks, + builtinTokens: this.builtinTokens, + currencyCode + }) + let address let operation let content @@ -127,13 +139,11 @@ export class TezosTools implements EdgeCurrencyTools { } else { throw new Error('InvalidUriError') } - const edgeParsedUri: EdgeParsedUri = { - publicAddress: address - } + edgeParsedUri.publicAddress = address edgeParsedUri.nativeAmount = // @ts-expect-error content != null && content.amount !== '0' ? content.amount : undefined - edgeParsedUri.currencyCode = 'XTZ' + edgeParsedUri.currencyCode = currencyCode return edgeParsedUri } diff --git a/src/tron/TronTools.ts b/src/tron/TronTools.ts index 09a1024fb..690e9da24 100644 --- a/src/tron/TronTools.ts +++ b/src/tron/TronTools.ts @@ -75,7 +75,7 @@ export class TronTools implements EdgeCurrencyTools { if (/^(0x)?[0-9a-fA-F]{64}$/.test(userInput)) { // It looks like a private key, so validate the hex: const tronKeyBuffer = Buffer.from(userInput.replace(/^0x/, ''), 'hex') - if (EthereumUtil.isValidPrivate(tronKeyBuffer) === true) { + if (EthereumUtil.isValidPrivate(tronKeyBuffer)) { throw new Error('Invalid private key') } const tronKey = tronKeyBuffer.toString('hex') @@ -133,14 +133,14 @@ export class TronTools implements EdgeCurrencyTools { const networks = { [this.currencyInfo.pluginId]: true, 'usdt-trc20': true } const { smartPayPublicAddress, smartPayUserId } = this.initOptions - const { parsedUri, edgeParsedUri } = parseUriCommon( - this.currencyInfo, + const { parsedUri, edgeParsedUri } = await parseUriCommon({ + currencyInfo: this.currencyInfo, uri, networks, - this.builtinTokens, - currencyCode ?? this.currencyInfo.currencyCode, + builtinTokens: this.builtinTokens, + currencyCode: currencyCode ?? this.currencyInfo.currencyCode, customTokens - ) + }) if (parsedUri.protocol === 'usdt-trc20') { edgeParsedUri.currencyCode = 'USDT' } diff --git a/src/zcash/ZcashTools.ts b/src/zcash/ZcashTools.ts index 2bd0972c0..33e17ecff 100644 --- a/src/zcash/ZcashTools.ts +++ b/src/zcash/ZcashTools.ts @@ -162,14 +162,14 @@ export class ZcashTools implements EdgeCurrencyTools { const { edgeParsedUri, edgeParsedUri: { publicAddress } - } = parseUriCommon( - this.currencyInfo, + } = await parseUriCommon({ + currencyInfo: this.currencyInfo, uri, networks, - this.builtinTokens, - currencyCode ?? this.currencyInfo.currencyCode, + builtinTokens: this.builtinTokens, + currencyCode: currencyCode ?? this.currencyInfo.currencyCode, customTokens - ) + }) if (publicAddress == null || !(await this.isValidAddress(publicAddress))) { throw new Error('InvalidPublicAddressError') diff --git a/yarn.lock b/yarn.lock index b354a05af..7fb43854d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3987,10 +3987,10 @@ ed25519@0.0.4: bindings "^1.2.1" nan "^2.0.9" -edge-core-js@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/edge-core-js/-/edge-core-js-2.5.0.tgz#9dc013c4f59a7a3fb1c88880eb600c4ef3e44e4f" - integrity sha512-sY0lJDIECanLx/muNGRXz3BUcfd3c76gCFA2BZu/4coE2O5o5GK4QnNB64uKPw6XBNrLfDhP1IcrclHDDgcOUQ== +edge-core-js@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/edge-core-js/-/edge-core-js-2.9.0.tgz#99a73c9b7903637f3551ef8cfb771e821193145c" + integrity sha512-hRxiJSe0NZtiokb4zmDr4fFnAspGN6i8dsVqRfOGeOzyJwm/1yo0K1lx70A1pkXHmNIrsirrp80wPcmLVSvl+Q== dependencies: aes-js "^3.1.0" base-x "^4.0.0"