Skip to content

Commit 14d0854

Browse files
author
Justin Kook
committed
ERC20 Changes squashed based on ETH branch
1 parent bcc514d commit 14d0854

File tree

12 files changed

+138
-28
lines changed

12 files changed

+138
-28
lines changed

packages/bitcore-wallet-client/src/lib/api.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,10 @@ export class API extends EventEmitter {
739739
$.checkArgument(coin || _.includes(Constants.COINS, coin));
740740
$.checkArgument(network || _.includes(['livenet', 'testnet'], network));
741741

742+
if (Constants.ERC20.includes(coin)) {
743+
coin = 'eth'
744+
}
745+
742746
this.request.get(
743747
'/v2/feelevels/?coin=' +
744748
(coin || 'btc') +
@@ -1111,6 +1115,7 @@ export class API extends EventEmitter {
11111115
// *
11121116
// * @param {Boolean} opts.twoStep[=false] - Optional: use 2-step balance computation for improved performance
11131117
// * @param {Boolean} opts.includeExtendedInfo (optional: query extended status)
1118+
// * @param {String} opts.tokenAddress (optional: ERC20 Token Contract Address)
11141119
// * @returns {Callback} cb - Returns error or an object with status information
11151120
// */
11161121
getStatus(opts, cb) {
@@ -1129,6 +1134,10 @@ export class API extends EventEmitter {
11291134
qs.push('twoStep=' + (opts.twoStep ? '1' : '0'));
11301135
qs.push('serverMessageArray=1');
11311136

1137+
if (opts.tokenAddress) {
1138+
qs.push('tokenAddress=' + opts.tokenAddress);
1139+
}
1140+
11321141
this.request.get('/v3/wallets/?' + qs.join('&'), (err, result) => {
11331142
if (err) return cb(err);
11341143
if (result.wallet.status == 'pending') {
@@ -1783,6 +1792,7 @@ export class API extends EventEmitter {
17831792
// * @param {Object} opts
17841793
// * @param {Number} opts.skip (defaults to 0)
17851794
// * @param {Number} opts.limit
1795+
// * @param {String} opts.tokenAddress
17861796
// * @param {Boolean} opts.includeExtendedInfo
17871797
// * @param {Callback} cb
17881798
// * @return {Callback} cb - Return error or array of transactions
@@ -1794,6 +1804,7 @@ export class API extends EventEmitter {
17941804
if (opts) {
17951805
if (opts.skip) args.push('skip=' + opts.skip);
17961806
if (opts.limit) args.push('limit=' + opts.limit);
1807+
if (opts.tokenAddress) args.push('tokenAddress=' + opts.tokenAddress);
17971808
if (opts.includeExtendedInfo) args.push('includeExtendedInfo=1');
17981809
}
17991810
var qs = '';

packages/bitcore-wallet-client/src/lib/common/constants.ts

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,39 @@ export const Constants = {
5252
minDecimals: 2,
5353
}
5454
},
55+
usdc: {
56+
toSatoshis: 1e6,
57+
full: {
58+
maxDecimals: 8,
59+
minDecimals: 8,
60+
},
61+
short: {
62+
maxDecimals: 6,
63+
minDecimals: 2,
64+
}
65+
},
66+
pax: {
67+
toSatoshis: 1e18,
68+
full: {
69+
maxDecimals: 8,
70+
minDecimals: 8,
71+
},
72+
short: {
73+
maxDecimals: 6,
74+
minDecimals: 2,
75+
}
76+
},
77+
gusd: {
78+
toSatoshis: 1e2,
79+
full: {
80+
maxDecimals: 8,
81+
minDecimals: 8,
82+
},
83+
short: {
84+
maxDecimals: 6,
85+
minDecimals: 2,
86+
}
87+
},
5588
bit: {
5689
toSatoshis: 100,
5790
full: {
@@ -64,6 +97,7 @@ export const Constants = {
6497
}
6598
},
6699
},
67-
COINS: ['btc', 'bch', 'eth'],
100+
COINS: ['btc', 'bch', 'eth', 'usdc', 'pax', 'gusd'],
101+
ERC20: ['usdc', 'pax', 'gusd'],
68102
UTXO_COINS: ['btc', 'bch']
69103
};

packages/bitcore-wallet-client/src/lib/common/utils.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -316,15 +316,17 @@ export class Utils {
316316

317317
return t;
318318
} else {
319-
const { outputs, amount, from, nonce, gasPrice, data, gasLimit } = txp;
319+
const { outputs, amount, from, nonce, data, gasPrice, gasLimit, tokenAddress } = txp;
320+
const chain = tokenAddress ? 'ERC20' : coin.toUpperCase();
320321
const rawTx = Transactions.create({
321-
chain: coin.toUpperCase(),
322-
recipients: [{ address: outputs[0].toAddress, amount }],
322+
chain,
323+
recipients: [{ address: outputs[0].toAddress, amount: amount }],
323324
from,
324325
nonce,
325-
fee: gasPrice,
326326
data,
327-
gasLimit
327+
fee: gasPrice,
328+
gasLimit,
329+
tokenAddress
328330
});
329331
return { uncheckedSerialize: () => rawTx };
330332
}

packages/bitcore-wallet-service/src/lib/blockchainexplorer.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { V8 } from './blockchainexplorers/v8';
44
const $ = require('preconditions').singleton();
55
const Common = require('./common');
66
const Defaults = Common.Defaults;
7+
const Constants = Common.Constants;
78
let log = require('npmlog');
89
log.debug = log.verbose;
910

@@ -28,9 +29,13 @@ export function BlockChainExplorer(opts) {
2829
$.checkArgument(opts);
2930

3031
const provider = opts.provider || 'v8';
31-
const coin = opts.coin || Defaults.COIN;
32+
let coin = opts.coin || Defaults.COIN;
3233
const network = opts.network || 'livenet';
3334

35+
if (Constants.ERC20[opts.coin.toUpperCase()]) {
36+
coin = 'eth'
37+
}
38+
3439
$.checkState(PROVIDERS[provider], 'Provider ' + provider + ' not supported');
3540
$.checkState(
3641
_.includes(_.keys(PROVIDERS[provider]), coin),

packages/bitcore-wallet-service/src/lib/blockchainexplorers/v8.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,12 @@ export class V8 {
5353
$.checkArgument(opts.url);
5454

5555
this.apiPrefix = _.isUndefined(opts.apiPrefix) ? '/api' : opts.apiPrefix;
56-
this.coin = opts.coin || Defaults.COIN;
56+
57+
if (Constants.ERC20[opts.coin.toUpperCase()]) {
58+
this.coin = 'eth'
59+
} else {
60+
this.coin = opts.coin || Defaults.COIN;
61+
}
5762
this.network = opts.network || 'livenet';
5863
this.v8network = v8network(this.network);
5964

@@ -139,8 +144,9 @@ export class V8 {
139144

140145
async getBalance(wallet, cb) {
141146
const client = this._getAuthClient(wallet);
147+
const { tokenAddress } = wallet;
142148
client
143-
.getBalance({ pubKey: wallet.beAuthPublicKey2, payload: {} })
149+
.getBalance({ pubKey: wallet.beAuthPublicKey2, payload: {}, tokenAddress })
144150
.then(ret => {
145151
return cb(null, ret);
146152
})
@@ -295,7 +301,8 @@ export class V8 {
295301
includeMempool: true,
296302
pubKey: wallet.beAuthPublicKey2,
297303
payload: {},
298-
startBlock: undefined
304+
startBlock: undefined,
305+
tokenAddress: wallet.tokenAddress,
299306
};
300307

301308
if (_.isNumber(startBlock)) opts.startBlock = startBlock;
@@ -383,7 +390,7 @@ export class V8 {
383390
return cb(err);
384391
});
385392
}
386-
393+
387394
estimateFee(nbBlocks, cb) {
388395
nbBlocks = nbBlocks || [1, 2, 6, 24];
389396
const result = {};

packages/bitcore-wallet-service/src/lib/blockchainexplorers/v8/client.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ export class Client {
4343
}
4444

4545
async getBalance(params) {
46-
const { payload, pubKey } = params;
47-
const url = `${this.baseUrl}/wallet/${pubKey}/balance`;
46+
const { payload, pubKey, tokenAddress } = params;
47+
const query = tokenAddress ? `?tokenAddress=${tokenAddress}` : '';
48+
const url = `${this.baseUrl}/wallet/${pubKey}/balance${query}`;
4849
console.log('[client.js.37:url:]', url); // TODO
4950
const signature = this.sign({ method: 'GET', url, payload });
5051
return request.get(url, {
@@ -108,7 +109,8 @@ export class Client {
108109
startDate,
109110
endBlock,
110111
endDate,
111-
includeMempool
112+
includeMempool,
113+
tokenAddress
112114
} = params;
113115
let url = `${this.baseUrl}/wallet/${pubKey}/transactions?`;
114116
if (startBlock) {
@@ -117,6 +119,9 @@ export class Client {
117119
if (endBlock) {
118120
url += `endBlock=${endBlock}&`;
119121
}
122+
if (tokenAddress) {
123+
url += `tokenAddress=${tokenAddress}&`;
124+
}
120125
if (includeMempool) {
121126
url += 'includeMempool=true';
122127
}

packages/bitcore-wallet-service/src/lib/common/constants.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,16 @@ module.exports = {
44
COINS: {
55
BTC: 'btc',
66
BCH: 'bch',
7-
ETH: 'eth'
7+
ETH: 'eth',
8+
USDC: 'usdc',
9+
PAX: 'pax',
10+
GUSD: 'gusd'
11+
},
12+
13+
ERC20: {
14+
USDC: 'usdc',
15+
PAX: 'pax',
16+
GUSD: 'gusd'
817
},
918

1019
UTXO_COINS: {

packages/bitcore-wallet-service/src/lib/expressapp.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ export class ExpressApp {
343343

344344
router.get('/v3/wallets/', (req, res) => {
345345
getServerWithAuth(req, res, (server) => {
346-
const opts = { includeExtendedInfo: false, twoStep: false, includeServerMessages: false };
346+
const opts = { includeExtendedInfo: false, twoStep: false, includeServerMessages: false, tokenAddress: req.query.tokenAddress };
347347
if (req.query.includeExtendedInfo == '1')
348348
opts.includeExtendedInfo = true;
349349
if (req.query.twoStep == '1') opts.twoStep = true;
@@ -727,9 +727,11 @@ export class ExpressApp {
727727
skip?: number;
728728
limit?: number;
729729
includeExtendedInfo?: boolean;
730+
tokenAddress?: string;
730731
} = {};
731732
if (req.query.skip) opts.skip = +req.query.skip;
732733
if (req.query.limit) opts.limit = +req.query.limit;
734+
if (req.query.tokenAddress) opts.tokenAddress = req.query.tokenAddress;
733735
if (req.query.includeExtendedInfo == '1')
734736
opts.includeExtendedInfo = true;
735737

packages/bitcore-wallet-service/src/lib/model/txproposal.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ export class TxProposal {
116116
gasLimit?: number;
117117
gasPrice?: number;
118118
data?: string;
119+
tokenAddress?: string;
119120

120121
static create(opts) {
121122
opts = opts || {};
@@ -177,6 +178,7 @@ export class TxProposal {
177178
x.from = opts.from;
178179
x.nonce = opts.nonce;
179180
x.data = opts.data;
181+
x.tokenAddress = opts.tokenAddress;
180182

181183
return x;
182184
}
@@ -229,6 +231,7 @@ export class TxProposal {
229231
x.from = obj.from;
230232
x.nonce = obj.nonce;
231233
x.data = obj.data;
234+
x.tokenAddress = obj.tokenAddress;
232235

233236
if (x.status == 'broadcasted') {
234237
x.raw = obj.raw;
@@ -266,13 +269,15 @@ export class TxProposal {
266269
);
267270

268271
if (!Constants.UTXO_COINS[this.coin.toUpperCase()]) {
272+
const chain = this.tokenAddress ? 'ERC20' : this.coin.toUpperCase();
269273
const rawTx = Transactions.create({
270-
chain: this.coin.toUpperCase(),
271-
recipients: [{ address: this.outputs[0].toAddress, amount: this.amount}],
274+
chain,
275+
recipients: [{ address: this.outputs[0].toAddress, amount: this.amount }],
272276
from: this.from,
273277
nonce: this.nonce,
274-
fee: this.gasPrice,
275278
data: this.data,
279+
fee: this.gasPrice,
280+
tokenAddress: this.tokenAddress,
276281
gasLimit: this.gasLimit
277282
});
278283
return { uncheckedSerialize: () => rawTx };

packages/bitcore-wallet-service/src/lib/server.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,7 @@ export class WalletService {
663663
* @param {Object} opts
664664
* @param {Object} opts.includeExtendedInfo - Include PKR info & address managers for wallet & copayers
665665
* @param {Object} opts.includeServerMessages - Include server messages array
666+
* @param {Object} opts.tokenAddress - (Optional) Token contract address to pass in getBalance
666667
* @returns {Object} status
667668
*/
668669
getStatus(opts, cb) {
@@ -1708,9 +1709,9 @@ export class WalletService {
17081709
_convertBitcoreBalance(bitcoreBalance, locked) {
17091710
const { unconfirmed, confirmed, balance } = bitcoreBalance;
17101711
const convertedBalance = {
1711-
totalAmount: balance,
1712-
totalConfirmedAmount: confirmed,
1713-
lockedAmount: locked,
1712+
totalAmount: Number(balance),
1713+
totalConfirmedAmount: Number(confirmed),
1714+
lockedAmount: Number(locked),
17141715
lockedConfirmedAmount: confirmed - locked,
17151716
availableAmount: balance - unconfirmed,
17161717
availableConfirmedAmount: confirmed - unconfirmed,
@@ -1728,7 +1729,7 @@ export class WalletService {
17281729

17291730
getBalance(opts, cb) {
17301731
opts = opts || {};
1731-
1732+
17321733
if (opts.coin) {
17331734
return cb(new ClientError('coin is not longer supported in getBalance'));
17341735
}
@@ -1757,6 +1758,11 @@ export class WalletService {
17571758
if (err) return cb(err);
17581759

17591760
if (!Constants.UTXO_COINS[wallet.coin.toUpperCase()]) {
1761+
1762+
if (opts.tokenAddress) {
1763+
wallet.tokenAddress = opts.tokenAddress;
1764+
}
1765+
17601766
bc.getBalance(wallet, (err, balance) => {
17611767
if (err) {
17621768
return cb(err);
@@ -2030,7 +2036,7 @@ export class WalletService {
20302036
)
20312037
);
20322038
};
2033-
2039+
20342040
const getFeeLevel = (feeSamples, level, n, fallback) => {
20352041
let result;
20362042

@@ -2876,16 +2882,17 @@ export class WalletService {
28762882
? opts.fee
28772883
: null,
28782884
noShuffleOutputs: opts.noShuffleOutputs,
2879-
data: opts.data,
28802885
gasPrice,
2881-
gasLimit
2886+
gasLimit,
2887+
data: opts.data,
2888+
tokenAddress: opts.tokenAddress
28822889
};
28832890
txp = TxProposal.create(txOpts);
28842891
next();
28852892
},
28862893
(next) => {
28872894
if (!Constants.UTXO_COINS[wallet.coin.toUpperCase()]) {
2888-
this.getBalance({ wallet }, (err, balance) => {
2895+
this.getBalance({ wallet, tokenAddress: opts.tokenAddress }, (err, balance) => {
28892896
const { totalAmount, availableAmount } = balance;
28902897
if (totalAmount < txp.getTotalAmount()) {
28912898
return cb(Errors.INSUFFICIENT_FUNDS);
@@ -4192,6 +4199,10 @@ export class WalletService {
41924199
bcHeight
41934200
); // TODO
41944201

4202+
if (opts.tokenAddress) {
4203+
wallet.tokenAddress = opts.tokenAddress;
4204+
}
4205+
41954206
bc.getTransactions(wallet, startBlock, (err, txs) => {
41964207
if (err) return cb(err);
41974208
const dustThreshold = Constants.UTXO_COINS[wallet.coin.toUpperCase()]
@@ -4339,6 +4350,7 @@ export class WalletService {
43394350
* @param {Object} opts
43404351
* @param {Number} opts.skip (defaults to 0)
43414352
* @param {Number} opts.limit
4353+
* @param {String} opts.tokenAddress ERC20 Token Contract Address
43424354
* @param {Number} opts.includeExtendedInfo[=false] - Include all inputs/outputs for every tx.
43434355
* @returns {TxProposal[]} Transaction proposals, first newer
43444356
*/

0 commit comments

Comments
 (0)