From 7dc23d14e38d44bf36b5870fb0131827643ce9ee Mon Sep 17 00:00:00 2001 From: Kenny Joseph Date: Mon, 29 Apr 2024 15:05:31 -0400 Subject: [PATCH 1/3] add token rm util --- packages/bitcore-client/bin/wallet | 3 +- packages/bitcore-client/bin/wallet-token | 6 ++-- packages/bitcore-client/bin/wallet-token-rm | 33 +++++++++++++++++++++ packages/bitcore-client/src/wallet.ts | 16 ++++++++++ 4 files changed, 54 insertions(+), 4 deletions(-) create mode 100755 packages/bitcore-client/bin/wallet-token-rm diff --git a/packages/bitcore-client/bin/wallet b/packages/bitcore-client/bin/wallet index 1e7b69c33ec..88c948160e1 100755 --- a/packages/bitcore-client/bin/wallet +++ b/packages/bitcore-client/bin/wallet @@ -19,7 +19,8 @@ program .command('paypro', 'pay using payment protocol').alias('p') .command('send', 'simple send from wallet to an address').alias('s') .command('sign', 'sign a transaction') - .command('token', 'add an ERC20 token to an eth wallet') + .command('token', 'add an ERC20 token to an EVM wallet') + .command('token-rm', 'remove an ERC20 token from an EVM wallet') .command('flags', 'check or set wallet flags (XRP only)') .command('storage', 'storage util for wallets') .command('sign-message', 'sign a message with an address') diff --git a/packages/bitcore-client/bin/wallet-token b/packages/bitcore-client/bin/wallet-token index 01561da203f..fb6ad2eb450 100755 --- a/packages/bitcore-client/bin/wallet-token +++ b/packages/bitcore-client/bin/wallet-token @@ -8,7 +8,7 @@ program .version(require('../package.json').version) .requiredOption('--name ', 'REQUIRED - Wallet name') .requiredOption('--contractAddress ', 'REQUIRED - Token contract address') - .option('--tokenName ', 'optional - Custom name for token') + .option('--tokenName ', 'optional - Custom name for token (default - contract\'s ticker)') .option('--storageType ', 'optional - Name of the database to use (Mongo | Level | TextFile)') .option('--path ', 'optional - Custom wallet storage path') .parse(process.argv); @@ -19,8 +19,8 @@ const main = async () => { const { name, path, contractAddress, storageType, tokenName } = program.opts(); try { wallet = await Wallet.loadWallet({ name, path, storageType }); - if (!['MATIC', 'ETH'].includes(wallet.chain)) { - throw new Error('Cannot add token to non-ETH wallet.'); + if (!wallet.isEvmChain()) { + throw new Error('Cannot add token to non-EVM wallet.'); } const token = await wallet.getToken(contractAddress); const tokenObj = { diff --git a/packages/bitcore-client/bin/wallet-token-rm b/packages/bitcore-client/bin/wallet-token-rm new file mode 100755 index 00000000000..e1d9fcee2ed --- /dev/null +++ b/packages/bitcore-client/bin/wallet-token-rm @@ -0,0 +1,33 @@ +#!/usr/bin/env node + +const program = require('commander'); +const promptly = require('promptly'); +const { Wallet } = require('../ts_build/src/wallet'); + +program + .version(require('../package.json').version) + .requiredOption('--name ', 'REQUIRED - Wallet name') + .requiredOption('--tokenName ', 'REQUIRED - Name of token to remove') + .option('--storageType ', 'optional - Name of the database to use (Mongo | Level | TextFile)') + .option('--path ', 'optional - Custom wallet storage path') + .parse(process.argv); + +let wallet; + +const main = async () => { + const { name, path, tokenName, storageType } = program.opts(); + try { + wallet = await Wallet.loadWallet({ name, path, storageType }); + if (!wallet.isEvmChain()) { + throw new Error('Cannot remove token from non-EVM wallet.'); + } + await wallet.rmToken({ tokenName }); + console.log(`Successfully removed ${tokenName}`); + } catch (e) { + console.error(e); + } +}; + +main() + .catch(console.error) + .finally(() => wallet?.storage?.close()); diff --git a/packages/bitcore-client/src/wallet.ts b/packages/bitcore-client/src/wallet.ts index 3fed08c7550..43094059ba8 100644 --- a/packages/bitcore-client/src/wallet.ts +++ b/packages/bitcore-client/src/wallet.ts @@ -274,6 +274,14 @@ export class Wallet { return ['BTC', 'BCH', 'DOGE', 'LTC'].includes(this.chain?.toUpperCase() || 'BTC'); } + /** + * Is this wallet EVM compatible? + * @returns {Boolean} + */ + isEvmChain() { + return ['ETH', 'MATIC'].includes(this.chain?.toUpperCase()); + } + lock() { this.unlocked = undefined; return this; @@ -404,6 +412,14 @@ export class Wallet { await this.saveWallet(); } + async rmToken({ tokenName }) { + if (!this.tokens) { + return; + } + this.tokens = this.tokens.filter(tok => tok.name !== tokenName || (!tok.name && tok.symbol !== tokenName)); + await this.saveWallet(); + } + async newTx(params: { utxos?: any[]; recipients: { address: string; amount: number }[]; From f8fc7a0d4355a77cf01a6405cd143b07f752d796 Mon Sep 17 00:00:00 2001 From: Kenny Joseph Date: Thu, 3 Oct 2024 20:32:00 -0400 Subject: [PATCH 2/3] fix filter and add tests --- packages/bitcore-client/src/wallet.ts | 5 +- .../bitcore-client/test/unit/wallet.test.ts | 74 +++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/packages/bitcore-client/src/wallet.ts b/packages/bitcore-client/src/wallet.ts index e345543ce17..365c6d359ff 100644 --- a/packages/bitcore-client/src/wallet.ts +++ b/packages/bitcore-client/src/wallet.ts @@ -454,7 +454,10 @@ export class Wallet { if (!this.tokens) { return; } - this.tokens = this.tokens.filter(tok => tok.name !== tokenName || (!tok.name && tok.symbol !== tokenName)); + this.tokens = this.tokens.filter(tok => + (tok.name && tok.name !== tokenName) || + /* legacy object */ (!tok.name && tok.symbol !== tokenName) + ); await this.saveWallet(); } diff --git a/packages/bitcore-client/test/unit/wallet.test.ts b/packages/bitcore-client/test/unit/wallet.test.ts index dad197ee1c5..02477ac0a35 100644 --- a/packages/bitcore-client/test/unit/wallet.test.ts +++ b/packages/bitcore-client/test/unit/wallet.test.ts @@ -473,5 +473,79 @@ describe('Wallet', function() { } }); }); + + describe.only('rmToken', function() { + walletName = 'BitcoreClientTestRmToken'; + const usdcLegacyObj = { + symbol: 'USDC', + address: '0x123', + decimals: '6', + }; + + const usdcObj = { + symbol: 'USDC', + address: '0xabc', + decimals: '6', + name: 'USDCn' + }; + + const daiObj = { + symbol: 'DAI', + address: '0x1a2b3c', + decimals: '6', + name: 'DAIn' + }; + + beforeEach(async function() { + wallet = await Wallet.create({ + chain: 'ETH', + network: 'mainnet', + name: walletName, + phrase: 'snap impact summer because must pipe weasel gorilla actor acid web whip', + password: 'abc123', + lite: false, + storageType, + baseUrl + }); + + wallet.tokens = [ + usdcLegacyObj, + usdcObj, + daiObj + ]; + }); + + it('should remove a legacy token object', function() { + wallet.rmToken({ tokenName: 'USDC' }); + wallet.tokens.length.should.equal(2); + wallet.tokens.filter(t => t.symbol === 'USDC').length.should.equal(1); + wallet.tokens.filter(t => t.symbol === 'USDC')[0].should.deep.equal(usdcObj); + }); + + it('should remove a token object', function() { + wallet.rmToken({ tokenName: 'USDCn' }); + wallet.tokens.length.should.equal(2); + wallet.tokens.filter(t => t.symbol === 'USDC').length.should.equal(1); + wallet.tokens.filter(t => t.symbol === 'USDC')[0].should.deep.equal(usdcLegacyObj); + }); + + it('should remove the correct token object regardless of order', function() { + wallet.tokens = [ + usdcObj, + daiObj, + usdcLegacyObj // this should be ordered after usdcObj + ]; + + wallet.rmToken({ tokenName: 'USDC' }); + wallet.tokens.length.should.equal(2); + wallet.tokens.filter(t => t.symbol === 'USDC').length.should.equal(1); + wallet.tokens.filter(t => t.symbol === 'USDC')[0].should.deep.equal(usdcObj); + }); + + it('should not remove any unmatched token object', function() { + wallet.rmToken({ tokenName: 'BOGUS' }); + wallet.tokens.length.should.equal(3); + }); + }); }); From 79449e71ef432e4cbbfd2be1079d827c5b906a26 Mon Sep 17 00:00:00 2001 From: Kenny Joseph Date: Thu, 3 Oct 2024 20:33:50 -0400 Subject: [PATCH 3/3] rm .only --- packages/bitcore-client/test/unit/wallet.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bitcore-client/test/unit/wallet.test.ts b/packages/bitcore-client/test/unit/wallet.test.ts index 02477ac0a35..d038f3e2526 100644 --- a/packages/bitcore-client/test/unit/wallet.test.ts +++ b/packages/bitcore-client/test/unit/wallet.test.ts @@ -474,7 +474,7 @@ describe('Wallet', function() { }); }); - describe.only('rmToken', function() { + describe('rmToken', function() { walletName = 'BitcoreClientTestRmToken'; const usdcLegacyObj = { symbol: 'USDC', @@ -535,7 +535,7 @@ describe('Wallet', function() { daiObj, usdcLegacyObj // this should be ordered after usdcObj ]; - + wallet.rmToken({ tokenName: 'USDC' }); wallet.tokens.length.should.equal(2); wallet.tokens.filter(t => t.symbol === 'USDC').length.should.equal(1);