cake_wallet/lib/core/address_validator.dart
Matthew Fosse 62e0c2a592
litecoin mweb support (#1455)
* Fix stub creation

* Generate MWEB addresses

* Fix mweb address derivation

* Use camel-case

* Show utxos in tx list

* A few fixes

* Add spent processing

* Update balance

* Balance fixes

* Update address records

* Get rid of debounce hack

* Get sending up to the confirmation box

* Fee estimation

* Stop the daemon if plugin is unloaded

* Normal fee for non-mweb txns

* Fix fee estimation for send all

* Don't hash mweb addresses

* More fee fixes

* Broadcast mweb

* Remove test files

* One more

* Confirm sent txns

* Couple of fixes

* Resign inputs after mweb create

* Some more fixes

* Update balance after sending

* Correctly update address records

* Update confs

* [skip ci] updates

* [skip ci] add dep overrides

* working

* small fix

* merge fixes [skip ci]

* merge fixes [skip ci]

* [skip ci] minor fixes

* silent payment fixes [skip ci]

* updates [skip ci]

* save [skip ci]

* use mwebutxos box

* [skip ci] lots of fixes, still testing

* add rescan from height feature and test workflow build

* install go

* use sudo

* correct package name

* move building mweb higher for faster testing

* install fixes

* install later version of go

* go fixes

* testing

* testing

* testing

* testing

* testing

* should workgit add .github/workflows/pr_test_build.yml

* ???

* ??? pt.2

* should work, for real this time

* fix tx history not persisting + update build_mwebd script

* updates

* fix some rescan and address gen issues

* save [skip ci]

* fix unconfirmed balance not updating when receiving

* unspent coins / coin control fixes

* coin control fixes

* address balance and txCount fixes, try/catch electrum call

* fix txCount for addresses

* save [skip ci]

* potential fixes

* minor fix

* minor fix - 2

* sync status fixes, potential fix for background state issue

* workflow and script updates

* updates

* expirimental optimization

* [skip ci] minor enhancements

* workflow and script fixes

* workflow minor cleanup [skip ci]

* minor code cleanup & friendlier error message on failed tx's

* balance when sending fix

* experimental

* more experiments

* save

* updates

* coin control edge cases

* remove neutrino.db if no litecoin wallets left after deleting

* update translations

* updates

* minor fix

* [skip ci] update translations + minor fixes

* state fixes

* configure fix

* ui updates

* translation fixes

* [skip ci] addressbook updates

* fix popup

* fix popup2

* fix litecoin address book

* fix ios mwebd build script

* fix for building monero.com

* minor fix

* uncomment fix for state issues

* potential mweb sync fix (ios)

* remove print [skip ci]

* electrum stream potential fix

* fix ios build issues [skip ci]

* connection reliability updates, update kotlin code to match swift code, minor electrum error handling

* dep fixes

* minor fix

* more merge fixes

* bitcoin_flutter removal fixes

* [skip ci] fix always scan setting, swift updates

* updates

* fixes

* small fix

* small fix

* fix

* dart:convert != package:convert

* change address fixes

* update bitcoin_base to fix mweb address program checking

* fix ios xcode project [skip ci]

* updates

* more fixes

* more fixes

* ensure we don't initialize mweb until we really have to

* fix regression

* improve mweb reliability

* [skip ci] wip adress generation

* wip

* wip

* [skip ci] wip

* updates [skip ci]

* ios fixes

* fix workflows + ios fix

* test old mweb version

* update go version and mwebd hash

* review updates pt.1

* Update cw_bitcoin/lib/litecoin_wallet.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* remove non-litecoin address types regex [skip ci]

* more minor fixes

* remove duplicate [skip ci]

* Update lib/store/settings_store.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

* script updates, swap params on createLitecoinWalletService

* topup fix

* [skip ci] wip

* [skip ci] testing

* [skip ci] file didn't get saved

* more address generation reliability fixes

* [skip ci] minor

* minor code cleanup

* hopefully prevents send issue

* [skip ci] wip address changes

* [skip ci] save

* save mweb addresses, auto-restart sync process if it gets stuck [skip ci]

* address generation issues mostly resolved

* more performance fixes

* [skip ci]

* this should maybe be refactored, pt.1

* separate mweb balances, pt.2

* [skip ci] save

* add translations [skip ci]

* fix sending with mweb amounts

* works for simple mweb-mweb case, further testing needed

* found an edge case

* [skip ci] make failed broadcast error message less serious

* minor

* capture all grpc errors and much better error handling overall

* [skip ci] minor

* prevent transactions with < 6 confirmations from being used + hide mweb balances if mweb is off

* fix

* merge fixes pt.1 [skip ci]

* fix mweb tags

* fix

* [skip ci] fix tag spacing

* fix transaction history not showing up

* fix mweb crash on non-fully deleted mweb cache, sync status ETA, other connection fixes

* [skip ci] minor code cleanup

* [skip ci] minor code cleanup

* additional cleanup

* silent payments eta fixes and updates

* revert sync eta changes into separate pr

* [skip ci] minor

* [skip ci] minor

* revert sync status title

* review fixes, additional cleanup

* [skip ci] minor

* [skip ci] minor

* [skip ci] minor

* trigger build

* review fixes, pt.2

* check if still processing utxos before updating sync status [skip ci]

* [skip ci] minor

* balance fix

* minor

* minor

* [skip ci] minor

* [skip ci] fix test net btc

* don't use mwebd for non-mweb tx's

* [skip ci] minor cleanup

* don't show all 1000+ mweb addresses on receive page

* minor cleanup + additional logging

---------

Co-authored-by: Hector Chu <hectorchu@gmail.com>
Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
Co-authored-by: Czarek Nakamoto <cyjan@mrcyjanek.net>
2024-09-28 05:22:25 +03:00

332 lines
11 KiB
Dart

import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/core/validator.dart';
import 'package:cake_wallet/solana/solana.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/erc20_token.dart';
const BEFORE_REGEX = '(^|\\s)';
const AFTER_REGEX = '(\$|\\s)';
class AddressValidator extends TextValidator {
AddressValidator({required CryptoCurrency type})
: super(
errorMessage: S.current.error_text_address,
useAdditionalValidation: type == CryptoCurrency.btc || type == CryptoCurrency.ltc
? (String txt) => BitcoinAddressUtils.validateAddress(
address: txt,
network: type == CryptoCurrency.btc
? BitcoinNetwork.mainnet
: LitecoinNetwork.mainnet,
)
: null,
pattern: getPattern(type),
length: getLength(type));
static String getPattern(CryptoCurrency type) {
var pattern = "";
if (type is Erc20Token) {
pattern = '0x[0-9a-zA-Z]+';
}
switch (type) {
case CryptoCurrency.xmr:
pattern = '4[0-9a-zA-Z]{94}|8[0-9a-zA-Z]{94}|[0-9a-zA-Z]{106}';
case CryptoCurrency.ada:
pattern = '[0-9a-zA-Z]{59}|[0-9a-zA-Z]{92}|[0-9a-zA-Z]{104}'
'|[0-9a-zA-Z]{105}|addr1[0-9a-zA-Z]{98}';
case CryptoCurrency.btc:
pattern =
'${P2pkhAddress.regex.pattern}|${P2shAddress.regex.pattern}|${P2wpkhAddress.regex.pattern}|${P2trAddress.regex.pattern}|${P2wshAddress.regex.pattern}|${SilentPaymentAddress.regex.pattern}';
case CryptoCurrency.ltc:
pattern = '^${P2wpkhAddress.regex.pattern}\$|^${MwebAddress.regex.pattern}\$';
case CryptoCurrency.nano:
pattern = '[0-9a-zA-Z_]+';
case CryptoCurrency.banano:
pattern = '[0-9a-zA-Z_]+';
case CryptoCurrency.usdc:
case CryptoCurrency.usdcpoly:
case CryptoCurrency.usdtPoly:
case CryptoCurrency.usdcEPoly:
case CryptoCurrency.ape:
case CryptoCurrency.avaxc:
case CryptoCurrency.eth:
case CryptoCurrency.mana:
case CryptoCurrency.matic:
case CryptoCurrency.maticpoly:
case CryptoCurrency.mkr:
case CryptoCurrency.oxt:
case CryptoCurrency.paxg:
case CryptoCurrency.uni:
case CryptoCurrency.aave:
case CryptoCurrency.bat:
case CryptoCurrency.comp:
case CryptoCurrency.cro:
case CryptoCurrency.ens:
case CryptoCurrency.ftm:
case CryptoCurrency.frax:
case CryptoCurrency.gusd:
case CryptoCurrency.gtc:
case CryptoCurrency.grt:
case CryptoCurrency.ldo:
case CryptoCurrency.nexo:
case CryptoCurrency.pepe:
case CryptoCurrency.storj:
case CryptoCurrency.tusd:
case CryptoCurrency.wbtc:
case CryptoCurrency.weth:
case CryptoCurrency.zrx:
case CryptoCurrency.dydx:
case CryptoCurrency.steth:
case CryptoCurrency.shib:
pattern = '0x[0-9a-zA-Z]+';
case CryptoCurrency.xrp:
pattern = '[0-9a-zA-Z]{34}|X[0-9a-zA-Z]{46}';
case CryptoCurrency.xhv:
pattern = 'hvx|hvi|hvs[0-9a-zA-Z]+';
case CryptoCurrency.xag:
case CryptoCurrency.xau:
case CryptoCurrency.xaud:
case CryptoCurrency.xbtc:
case CryptoCurrency.xcad:
case CryptoCurrency.xchf:
case CryptoCurrency.xcny:
case CryptoCurrency.xeur:
case CryptoCurrency.xgbp:
case CryptoCurrency.xjpy:
case CryptoCurrency.xnok:
case CryptoCurrency.xnzd:
case CryptoCurrency.xusd:
case CryptoCurrency.usdt:
case CryptoCurrency.usdterc20:
case CryptoCurrency.xlm:
case CryptoCurrency.trx:
case CryptoCurrency.dai:
case CryptoCurrency.dash:
case CryptoCurrency.eos:
case CryptoCurrency.wow:
pattern = '[0-9a-zA-Z]+';
case CryptoCurrency.bch:
pattern =
'(?!bitcoincash:)[0-9a-zA-Z]*|(?!bitcoincash:)q|p[0-9a-zA-Z]{41}|(?!bitcoincash:)q|p[0-9a-zA-Z]{42}|bitcoincash:q|p[0-9a-zA-Z]{41}|bitcoincash:q|p[0-9a-zA-Z]{42}';
case CryptoCurrency.bnb:
pattern = '[0-9a-zA-Z]+';
case CryptoCurrency.hbar:
pattern = '[0-9a-zA-Z.]+';
case CryptoCurrency.zaddr:
pattern = 'zs[0-9a-zA-Z]{75}';
case CryptoCurrency.zec:
pattern = 't1[0-9a-zA-Z]{33}|t3[0-9a-zA-Z]{33}';
case CryptoCurrency.dcr:
pattern = 'D[ksecS]([0-9a-zA-Z])+';
case CryptoCurrency.rvn:
pattern = '[Rr]([1-9a-km-zA-HJ-NP-Z]){33}';
case CryptoCurrency.near:
pattern = '[0-9a-f]{64}';
case CryptoCurrency.rune:
pattern = 'thor1[0-9a-z]{38}';
case CryptoCurrency.scrt:
pattern = 'secret1[0-9a-z]{38}';
case CryptoCurrency.stx:
pattern = 'S[MP][0-9a-zA-Z]+';
case CryptoCurrency.kmd:
pattern = 'R[0-9a-zA-Z]{33}';
case CryptoCurrency.pivx:
pattern = 'D([1-9a-km-zA-HJ-NP-Z]){33}';
case CryptoCurrency.btcln:
pattern = '(lnbc|LNBC)([0-9]{1,}[a-zA-Z0-9]+)';
default:
pattern = '[0-9a-zA-Z]+';
}
return '$BEFORE_REGEX($pattern)$AFTER_REGEX';
}
static List<int>? getLength(CryptoCurrency type) {
if (type is Erc20Token) {
return [42];
}
if (solana != null) {
final length = solana!.getValidationLength(type);
if (length != null) return length;
}
switch (type) {
case CryptoCurrency.xmr:
case CryptoCurrency.wow:
return null;
case CryptoCurrency.ada:
return null;
case CryptoCurrency.btc:
return null;
case CryptoCurrency.ltc:
return null;
case CryptoCurrency.dash:
return [34];
case CryptoCurrency.eos:
return [42];
case CryptoCurrency.eth:
case CryptoCurrency.usdcpoly:
case CryptoCurrency.usdtPoly:
case CryptoCurrency.usdcEPoly:
case CryptoCurrency.mana:
case CryptoCurrency.matic:
case CryptoCurrency.maticpoly:
case CryptoCurrency.mkr:
case CryptoCurrency.oxt:
case CryptoCurrency.paxg:
case CryptoCurrency.uni:
case CryptoCurrency.dai:
case CryptoCurrency.ape:
case CryptoCurrency.usdc:
case CryptoCurrency.usdterc20:
case CryptoCurrency.aave:
case CryptoCurrency.bat:
case CryptoCurrency.comp:
case CryptoCurrency.cro:
case CryptoCurrency.ens:
case CryptoCurrency.ftm:
case CryptoCurrency.frax:
case CryptoCurrency.gusd:
case CryptoCurrency.gtc:
case CryptoCurrency.grt:
case CryptoCurrency.ldo:
case CryptoCurrency.nexo:
case CryptoCurrency.pepe:
case CryptoCurrency.storj:
case CryptoCurrency.tusd:
case CryptoCurrency.wbtc:
case CryptoCurrency.weth:
case CryptoCurrency.zrx:
case CryptoCurrency.dydx:
case CryptoCurrency.steth:
case CryptoCurrency.shib:
case CryptoCurrency.avaxc:
return [42];
case CryptoCurrency.bch:
return [42, 43, 44, 54, 55];
case CryptoCurrency.bnb:
return [42];
case CryptoCurrency.nano:
return [64, 65];
case CryptoCurrency.banano:
return [64, 65];
case CryptoCurrency.sc:
return [76];
case CryptoCurrency.sol:
case CryptoCurrency.usdtSol:
case CryptoCurrency.usdcsol:
return [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44];
case CryptoCurrency.trx:
return [34];
case CryptoCurrency.usdt:
return [34];
case CryptoCurrency.usdttrc20:
return [34];
case CryptoCurrency.xlm:
return [56];
case CryptoCurrency.xrp:
return null;
case CryptoCurrency.xhv:
case CryptoCurrency.xag:
case CryptoCurrency.xau:
case CryptoCurrency.xaud:
case CryptoCurrency.xbtc:
case CryptoCurrency.xcad:
case CryptoCurrency.xchf:
case CryptoCurrency.xcny:
case CryptoCurrency.xeur:
case CryptoCurrency.xgbp:
case CryptoCurrency.xjpy:
case CryptoCurrency.xnok:
case CryptoCurrency.xnzd:
case CryptoCurrency.xusd:
return [98, 99, 106];
case CryptoCurrency.btt:
case CryptoCurrency.bttc:
case CryptoCurrency.doge:
case CryptoCurrency.firo:
return [34];
case CryptoCurrency.hbar:
return [4, 5, 6, 7, 8, 9, 10, 11];
case CryptoCurrency.xvg:
return [34];
case CryptoCurrency.zen:
return [35];
case CryptoCurrency.zaddr:
return null;
case CryptoCurrency.zec:
return null;
case CryptoCurrency.kmd:
case CryptoCurrency.pivx:
case CryptoCurrency.rvn:
return [34];
case CryptoCurrency.dcr:
return [35];
case CryptoCurrency.stx:
return [40, 41, 42];
case CryptoCurrency.rune:
return [43];
case CryptoCurrency.scrt:
return [45];
case CryptoCurrency.near:
return [64];
case CryptoCurrency.btcln:
case CryptoCurrency.kaspa:
default:
return null;
}
}
static String? getAddressFromStringPattern(CryptoCurrency type) {
String? pattern = null;
switch (type) {
case CryptoCurrency.xmr:
case CryptoCurrency.wow:
pattern = '(4[0-9a-zA-Z]{94})'
'|(8[0-9a-zA-Z]{94})'
'|([0-9a-zA-Z]{106})';
case CryptoCurrency.btc:
pattern =
'${P2pkhAddress.regex.pattern}|${P2shAddress.regex.pattern}|${P2wpkhAddress.regex.pattern}|${P2trAddress.regex.pattern}|${P2wshAddress.regex.pattern}|${SilentPaymentAddress.regex.pattern}';
case CryptoCurrency.ltc:
pattern = '([^0-9a-zA-Z]|^)^L[a-zA-Z0-9]{26,33}([^0-9a-zA-Z]|\$)'
'|([^0-9a-zA-Z]|^)[LM][a-km-zA-HJ-NP-Z1-9]{26,33}([^0-9a-zA-Z]|\$)'
'|([^0-9a-zA-Z]|^)ltc[a-zA-Z0-9]{26,45}([^0-9a-zA-Z]|\$)'
'|([^0-9a-zA-Z]|^)((ltc|t)mweb1q[ac-hj-np-z02-9]{90,120})([^0-9a-zA-Z]|\$)';
case CryptoCurrency.eth:
case CryptoCurrency.maticpoly:
pattern = '0x[0-9a-zA-Z]+';
case CryptoCurrency.nano:
pattern = 'nano_[0-9a-zA-Z]{60}';
case CryptoCurrency.banano:
pattern = 'ban_[0-9a-zA-Z]{60}';
case CryptoCurrency.bch:
pattern = '(bitcoincash:)?q[0-9a-zA-Z]{41,42}';
case CryptoCurrency.sol:
pattern = '[1-9A-HJ-NP-Za-km-z]+';
case CryptoCurrency.trx:
pattern = '(T|t)[1-9A-HJ-NP-Za-km-z]{33}';
default:
if (type.tag == CryptoCurrency.eth.title) {
pattern = '0x[0-9a-zA-Z]{42}';
}
if (type.tag == CryptoCurrency.maticpoly.tag) {
pattern = '0x[0-9a-zA-Z]{42}';
}
if (type.tag == CryptoCurrency.sol.title) {
pattern = '[1-9A-HJ-NP-Za-km-z]{43,44}';
}
if (type.tag == CryptoCurrency.trx.title) {
pattern = '(T|t)[1-9A-HJ-NP-Za-km-z]{33}';
}
}
if (pattern != null) {
return "$BEFORE_REGEX($pattern)$AFTER_REGEX";
}
return null;
}
}