@bitpay-labs/bitcore-wallet-service 11.11.3 → 11.11.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -4
- package/src/config.ts +8 -0
- package/src/externalservices/coingecko.ts +6 -1
- package/src/externalservices/transak.ts +394 -70
- package/src/lib/blockchainexplorer.ts +4 -0
- package/src/lib/blockchainexplorers/v8.ts +1 -0
- package/src/lib/blockchainmonitor.ts +1 -0
- package/src/lib/chain/arc/index.ts +95 -0
- package/src/lib/chain/eth/index.ts +41 -23
- package/src/lib/chain/index.ts +2 -0
- package/src/lib/common/constants.ts +12 -1
- package/src/lib/common/defaults.ts +31 -0
- package/src/lib/emailservice.ts +3 -1
- package/src/lib/errors/errordefinitions.ts +4 -0
- package/src/lib/model/preferences.ts +4 -0
- package/src/lib/model/wallet.ts +1 -0
- package/src/lib/pushnotificationsservice.ts +2 -0
- package/src/lib/routes/services.ts +1 -1
- package/src/lib/routes/walletdata.ts +2 -0
- package/src/lib/server.ts +20 -2
- package/test/blockchainexplorer.test.ts +7 -0
- package/test/expressapp.test.ts +31 -0
- package/test/integration/externalservices/coinGecko.test.ts +42 -2
- package/test/integration/externalservices/transak.test.ts +545 -135
- package/test/integration/fiatrateservice.test.ts +13 -0
- package/test/integration/helpers.ts +1 -0
- package/test/integration/server.test.ts +139 -3
- package/ts_build/package.json +1 -1
- package/ts_build/src/config.d.ts.map +1 -1
- package/ts_build/src/config.js +8 -0
- package/ts_build/src/config.js.map +1 -1
- package/ts_build/src/externalservices/coingecko.d.ts.map +1 -1
- package/ts_build/src/externalservices/coingecko.js +6 -1
- package/ts_build/src/externalservices/coingecko.js.map +1 -1
- package/ts_build/src/externalservices/transak.d.ts +28 -2
- package/ts_build/src/externalservices/transak.d.ts.map +1 -1
- package/ts_build/src/externalservices/transak.js +274 -57
- package/ts_build/src/externalservices/transak.js.map +1 -1
- package/ts_build/src/lib/blockchainexplorer.d.ts.map +1 -1
- package/ts_build/src/lib/blockchainexplorer.js +4 -0
- package/ts_build/src/lib/blockchainexplorer.js.map +1 -1
- package/ts_build/src/lib/blockchainexplorers/v8.d.ts.map +1 -1
- package/ts_build/src/lib/blockchainexplorers/v8.js +1 -0
- package/ts_build/src/lib/blockchainexplorers/v8.js.map +1 -1
- package/ts_build/src/lib/blockchainmonitor.d.ts.map +1 -1
- package/ts_build/src/lib/blockchainmonitor.js +1 -0
- package/ts_build/src/lib/blockchainmonitor.js.map +1 -1
- package/ts_build/src/lib/chain/arc/index.d.ts +20 -0
- package/ts_build/src/lib/chain/arc/index.d.ts.map +1 -0
- package/ts_build/src/lib/chain/arc/index.js +95 -0
- package/ts_build/src/lib/chain/arc/index.js.map +1 -0
- package/ts_build/src/lib/chain/eth/index.d.ts +1 -0
- package/ts_build/src/lib/chain/eth/index.d.ts.map +1 -1
- package/ts_build/src/lib/chain/eth/index.js +38 -19
- package/ts_build/src/lib/chain/eth/index.js.map +1 -1
- package/ts_build/src/lib/chain/index.d.ts.map +1 -1
- package/ts_build/src/lib/chain/index.js +2 -0
- package/ts_build/src/lib/chain/index.js.map +1 -1
- package/ts_build/src/lib/common/constants.d.ts +12 -0
- package/ts_build/src/lib/common/constants.d.ts.map +1 -1
- package/ts_build/src/lib/common/constants.js +12 -1
- package/ts_build/src/lib/common/constants.js.map +1 -1
- package/ts_build/src/lib/common/defaults.d.ts +24 -0
- package/ts_build/src/lib/common/defaults.d.ts.map +1 -1
- package/ts_build/src/lib/common/defaults.js +30 -0
- package/ts_build/src/lib/common/defaults.js.map +1 -1
- package/ts_build/src/lib/common/index.d.ts +36 -0
- package/ts_build/src/lib/common/index.d.ts.map +1 -1
- package/ts_build/src/lib/emailservice.d.ts.map +1 -1
- package/ts_build/src/lib/emailservice.js +2 -0
- package/ts_build/src/lib/emailservice.js.map +1 -1
- package/ts_build/src/lib/errors/errordefinitions.d.ts +2 -0
- package/ts_build/src/lib/errors/errordefinitions.d.ts.map +1 -1
- package/ts_build/src/lib/errors/errordefinitions.js +2 -0
- package/ts_build/src/lib/errors/errordefinitions.js.map +1 -1
- package/ts_build/src/lib/model/preferences.d.ts +2 -0
- package/ts_build/src/lib/model/preferences.d.ts.map +1 -1
- package/ts_build/src/lib/model/preferences.js +3 -0
- package/ts_build/src/lib/model/preferences.js.map +1 -1
- package/ts_build/src/lib/model/wallet.d.ts.map +1 -1
- package/ts_build/src/lib/model/wallet.js +1 -0
- package/ts_build/src/lib/model/wallet.js.map +1 -1
- package/ts_build/src/lib/pushnotificationsservice.d.ts.map +1 -1
- package/ts_build/src/lib/pushnotificationsservice.js +2 -0
- package/ts_build/src/lib/pushnotificationsservice.js.map +1 -1
- package/ts_build/src/lib/routes/services.js +1 -1
- package/ts_build/src/lib/routes/services.js.map +1 -1
- package/ts_build/src/lib/routes/walletdata.d.ts.map +1 -1
- package/ts_build/src/lib/routes/walletdata.js +2 -0
- package/ts_build/src/lib/routes/walletdata.js.map +1 -1
- package/ts_build/src/lib/server.d.ts.map +1 -1
- package/ts_build/src/lib/server.js +17 -2
- package/ts_build/src/lib/server.js.map +1 -1
- package/ts_build/test/blockchainexplorer.test.js +6 -0
- package/ts_build/test/blockchainexplorer.test.js.map +1 -1
- package/ts_build/test/expressapp.test.js +30 -0
- package/ts_build/test/expressapp.test.js.map +1 -1
- package/ts_build/test/integration/externalservices/coinGecko.test.js +38 -2
- package/ts_build/test/integration/externalservices/coinGecko.test.js.map +1 -1
- package/ts_build/test/integration/externalservices/transak.test.d.ts.map +1 -1
- package/ts_build/test/integration/externalservices/transak.test.js +498 -128
- package/ts_build/test/integration/externalservices/transak.test.js.map +1 -1
- package/ts_build/test/integration/fiatrateservice.test.js +11 -0
- package/ts_build/test/integration/fiatrateservice.test.js.map +1 -1
- package/ts_build/test/integration/helpers.d.ts.map +1 -1
- package/ts_build/test/integration/helpers.js +1 -0
- package/ts_build/test/integration/helpers.js.map +1 -1
- package/ts_build/test/integration/server.test.js +135 -3
- package/ts_build/test/integration/server.test.js.map +1 -1
|
@@ -57,6 +57,7 @@ const TestData = __importStar(require("../testdata"));
|
|
|
57
57
|
const helpers_1 = __importDefault(require("./helpers"));
|
|
58
58
|
const clienterror_1 = require("../../src/lib/errors/clienterror");
|
|
59
59
|
const expressapp_1 = require("../../src/lib/expressapp");
|
|
60
|
+
const abi_erc20_1 = require("../../src/lib/chain/eth/abi-erc20");
|
|
60
61
|
const should = chai.should();
|
|
61
62
|
config_1.default.moralis = config_1.default.moralis ?? {
|
|
62
63
|
apiKey: 'apiKey',
|
|
@@ -2499,6 +2500,28 @@ describe('Wallet service', function () {
|
|
|
2499
2500
|
beforeEach(async function () {
|
|
2500
2501
|
({ server, wallet } = await helpers_1.default.createAndJoinWallet(1, 1, { coin: 'eth' }));
|
|
2501
2502
|
});
|
|
2503
|
+
it('should save and merge Arc token preferences without linking native USDC', async function () {
|
|
2504
|
+
({ server } = await helpers_1.default.createAndJoinWallet(1, 1, { coin: 'arc', network: 'livenet' }));
|
|
2505
|
+
await util_1.default.promisify(server.savePreferences).call(server, { arcTokenAddresses: [TOKENS[0]], language: 'es' });
|
|
2506
|
+
await util_1.default.promisify(server.savePreferences).call(server, {
|
|
2507
|
+
arcTokenAddresses: [TOKENS[1], CWC.ethers.getAddress(TOKENS[0])],
|
|
2508
|
+
});
|
|
2509
|
+
let preferences = await util_1.default.promisify(server.getPreferences).call(server, {});
|
|
2510
|
+
preferences.arcTokenAddresses.should.deep.equal(TOKENS);
|
|
2511
|
+
preferences.language.should.equal('es');
|
|
2512
|
+
try {
|
|
2513
|
+
await util_1.default.promisify(server.savePreferences).call(server, {
|
|
2514
|
+
arcTokenAddresses: [TOKENS[0], CWC.Constants.ARC.USDC_CONTRACT_ADDRESS], language: 'en',
|
|
2515
|
+
});
|
|
2516
|
+
should.fail('Expected native USDC token preference rejection');
|
|
2517
|
+
}
|
|
2518
|
+
catch (err) {
|
|
2519
|
+
err.message.toString().should.contain('arcTokenAddresses');
|
|
2520
|
+
}
|
|
2521
|
+
preferences = await util_1.default.promisify(server.getPreferences).call(server, {});
|
|
2522
|
+
preferences.arcTokenAddresses.should.deep.equal(TOKENS);
|
|
2523
|
+
preferences.language.should.equal('es');
|
|
2524
|
+
});
|
|
2502
2525
|
it('should save & retrieve preferences', function (done) {
|
|
2503
2526
|
server.savePreferences({
|
|
2504
2527
|
email: 'dummy@dummy.com',
|
|
@@ -2685,7 +2708,8 @@ describe('Wallet service', function () {
|
|
|
2685
2708
|
unit: 'xxxxx',
|
|
2686
2709
|
},
|
|
2687
2710
|
expected: 'unit'
|
|
2688
|
-
},]
|
|
2711
|
+
}, ...['not-an-array', ['invalid']]
|
|
2712
|
+
.map(arcTokenAddresses => ({ preferences: { arcTokenAddresses }, expected: 'arcTokenAddresses' }))];
|
|
2689
2713
|
for (const item of invalid) {
|
|
2690
2714
|
try {
|
|
2691
2715
|
await util_1.default.promisify(server.savePreferences).call(server, item.preferences);
|
|
@@ -5737,6 +5761,111 @@ describe('Wallet service', function () {
|
|
|
5737
5761
|
});
|
|
5738
5762
|
});
|
|
5739
5763
|
});
|
|
5764
|
+
for (const [network, chainId] of [['livenet', 5042n], ['testnet', 5042002n]]) {
|
|
5765
|
+
describe(`#createTX ARC ${network}`, () => {
|
|
5766
|
+
let server;
|
|
5767
|
+
let from;
|
|
5768
|
+
const destination = '0x37d7B3bBD88EFdE6a93cF74D2F5b0385D3E3B08A';
|
|
5769
|
+
const usdc = new CWC.ethers.Interface(abi_erc20_1.ERC20Abi);
|
|
5770
|
+
const contractOpts = (data) => makeOpts({
|
|
5771
|
+
outputs: [{ toAddress: CWC.Constants.ARC.USDC_CONTRACT_ADDRESS, amount: 0, gasLimit: 100000, data }]
|
|
5772
|
+
});
|
|
5773
|
+
const makeOpts = (overrides = {}) => ({
|
|
5774
|
+
outputs: [{ toAddress: destination, amount: 1e18, gasLimit: 21000 }],
|
|
5775
|
+
nonce: 0, feeLevel: 'normal', ...overrides
|
|
5776
|
+
});
|
|
5777
|
+
beforeEach(async () => {
|
|
5778
|
+
({ server } = await helpers_1.default.createAndJoinWallet(1, 1, { coin: 'arc', network }));
|
|
5779
|
+
from = (await util_1.default.promisify(server.createAddress).call(server, {})).address;
|
|
5780
|
+
blockchainExplorer.getBalance = sinon_1.default.stub().callsArgWith(1, null, { balance: 2e18, confirmed: 2e18, unconfirmed: 0 });
|
|
5781
|
+
helpers_1.default.stubFeeLevels({ 1: 25000000000, 2: 25000000000, 3: 25000000000, 4: 25000000000 }, true, 'arc');
|
|
5782
|
+
});
|
|
5783
|
+
for (const [txType, sendMax] of [[0, false], [2, false], [2, true]]) {
|
|
5784
|
+
it(`should publish, sign and submit a type ${txType} native USDC ${sendMax ? 'send-max ' : ''}proposal`, async () => {
|
|
5785
|
+
const maxGasFee = sendMax ? 31000000000 : 30000000000;
|
|
5786
|
+
sinon_1.default.stub(server, 'estimateFee').resolves(maxGasFee).onFirstCall().resolves(30000000000);
|
|
5787
|
+
sinon_1.default.stub(server, 'estimatePriorityFee').resolves(0);
|
|
5788
|
+
const fee = (txType === 2 ? maxGasFee : 25000000000) * 21000;
|
|
5789
|
+
const amount = sendMax ? 2e18 - fee : 1e18;
|
|
5790
|
+
const txp = await util_1.default.promisify(server.createTx).call(server, makeOpts({ txType, sendMax,
|
|
5791
|
+
outputs: [{ toAddress: destination, amount: sendMax ? null : amount, gasLimit: 21000 }] }));
|
|
5792
|
+
txp.fee.should.equal(fee);
|
|
5793
|
+
txp.amount.should.equal(amount);
|
|
5794
|
+
await util_1.default.promisify(server.publishTx).call(server, helpers_1.default.getProposalSignatureOpts(txp, TestData.copayers[0].privKey_1H_0));
|
|
5795
|
+
await util_1.default.promisify(server.signTx).call(server, { txProposalId: txp.id, signatures: helpers_1.default.clientSign(txp, TestData.copayers[0].xPrivKey_44H_0H_0H) });
|
|
5796
|
+
const accepted = await util_1.default.promisify(server.getTx).call(server, { txProposalId: txp.id });
|
|
5797
|
+
accepted.status.should.equal('accepted');
|
|
5798
|
+
const [raw] = accepted.getRawTx();
|
|
5799
|
+
const signed = CWC.ethers.Transaction.from(raw);
|
|
5800
|
+
signed.chainId.should.equal(chainId);
|
|
5801
|
+
signed.value.should.equal(BigInt(amount));
|
|
5802
|
+
BigInt(txp.fee).should.equal((signed.maxFeePerGas ?? signed.gasPrice) * signed.gasLimit);
|
|
5803
|
+
signed.isSigned().should.equal(true);
|
|
5804
|
+
helpers_1.default.stubBroadcast(accepted.txid);
|
|
5805
|
+
await util_1.default.promisify(server.broadcastTx).call(server, { txProposalId: txp.id });
|
|
5806
|
+
blockchainExplorer.broadcast.firstCall.args[0].should.deep.equal([raw]);
|
|
5807
|
+
(await util_1.default.promisify(server.getTx).call(server, { txProposalId: txp.id })).status.should.equal('broadcasted');
|
|
5808
|
+
});
|
|
5809
|
+
}
|
|
5810
|
+
it('should reserve wallet-owned USDC contract debits and release them when removed', async () => {
|
|
5811
|
+
for (const [method, args, debit, legacyData] of [
|
|
5812
|
+
['transfer', [destination, 1000000n], 1e18],
|
|
5813
|
+
['transferFrom', [from, destination, 1000000n], 1e18],
|
|
5814
|
+
['transferFrom', [destination, from, 1000000n], 0],
|
|
5815
|
+
['approve', [destination, 1000000n], 0],
|
|
5816
|
+
['approve', [destination, 1000000n], 1e18, usdc.encodeFunctionData('transfer', [destination, 1000000n])]
|
|
5817
|
+
]) {
|
|
5818
|
+
const data = usdc.encodeFunctionData(method, args);
|
|
5819
|
+
const txp = await util_1.default.promisify(server.createTx).call(server, { ...contractOpts(data), data: legacyData });
|
|
5820
|
+
txp.amount.should.equal(0);
|
|
5821
|
+
txp.outputs[0].amount.should.equal(0);
|
|
5822
|
+
txp.outputs[0].data.should.equal(data);
|
|
5823
|
+
CWC.ethers.Transaction.from(txp.getRawTx()[0]).data.should.equal(legacyData || data);
|
|
5824
|
+
await util_1.default.promisify(server.publishTx).call(server, helpers_1.default.getProposalSignatureOpts(txp, TestData.copayers[0].privKey_1H_0));
|
|
5825
|
+
const balance = await util_1.default.promisify(server.getBalance).call(server, {});
|
|
5826
|
+
balance.lockedAmount.should.equal(debit + txp.fee);
|
|
5827
|
+
balance.availableAmount.should.equal(2e18 - debit - txp.fee);
|
|
5828
|
+
if (debit) {
|
|
5829
|
+
try {
|
|
5830
|
+
await util_1.default.promisify(server.createTx).call(server, makeOpts({ nonce: 1,
|
|
5831
|
+
outputs: [{ toAddress: destination, amount: 1.5e18, gasLimit: 21000 }] }));
|
|
5832
|
+
should.fail('Expected pending USDC funds to be unavailable');
|
|
5833
|
+
}
|
|
5834
|
+
catch (err) {
|
|
5835
|
+
err.code.should.equal('LOCKED_FUNDS');
|
|
5836
|
+
}
|
|
5837
|
+
}
|
|
5838
|
+
await util_1.default.promisify(server.removePendingTx).call(server, { txProposalId: txp.id });
|
|
5839
|
+
(await util_1.default.promisify(server.getBalance).call(server, {})).lockedAmount.should.equal(0);
|
|
5840
|
+
}
|
|
5841
|
+
});
|
|
5842
|
+
it('should reject underpriced proposals, duplicate USDC token views and zero-address transfers', async () => {
|
|
5843
|
+
try {
|
|
5844
|
+
await util_1.default.promisify(server.getBalance).call(server, { tokenAddress: CWC.Constants.ARC.USDC_CONTRACT_ADDRESS });
|
|
5845
|
+
throw new Error('Expected duplicate token balance rejection');
|
|
5846
|
+
}
|
|
5847
|
+
catch (err) {
|
|
5848
|
+
err.message.should.contain('omit tokenAddress');
|
|
5849
|
+
}
|
|
5850
|
+
for (const [opts, message] of [
|
|
5851
|
+
[makeOpts({ feeLevel: undefined, feePerKb: 10000000000 }), 'at least 20 gwei'],
|
|
5852
|
+
[makeOpts({ tokenAddress: CWC.Constants.ARC.USDC_CONTRACT_ADDRESS }), 'omit tokenAddress'],
|
|
5853
|
+
[contractOpts(usdc.encodeFunctionData('transfer', [destination, 3000000n])), 'Insufficient funds'],
|
|
5854
|
+
[contractOpts(usdc.encodeFunctionData('transfer', [destination, 2000000n])), 'Insufficient funds for fee'],
|
|
5855
|
+
[contractOpts(usdc.getFunction('transfer').selector), 'Invalid Arc USDC contract call data'],
|
|
5856
|
+
[makeOpts({ outputs: [{ toAddress: '0x0000000000000000000000000000000000000000', amount: 1e18 }] }), 'zero address']
|
|
5857
|
+
]) {
|
|
5858
|
+
try {
|
|
5859
|
+
await util_1.default.promisify(server.createTx).call(server, opts);
|
|
5860
|
+
throw new Error('Expected proposal rejection');
|
|
5861
|
+
}
|
|
5862
|
+
catch (err) {
|
|
5863
|
+
err.message.should.contain(message);
|
|
5864
|
+
}
|
|
5865
|
+
}
|
|
5866
|
+
});
|
|
5867
|
+
});
|
|
5868
|
+
}
|
|
5740
5869
|
describe('#createTX ETH Only tests', () => {
|
|
5741
5870
|
let server;
|
|
5742
5871
|
let wallet;
|
|
@@ -5919,8 +6048,8 @@ describe('Wallet service', function () {
|
|
|
5919
6048
|
sinon_1.default.stub(server, 'estimatePriorityFee').resolves(1000000000);
|
|
5920
6049
|
const txp = await util_1.default.promisify(server.createTx).call(server, makeOpts({ txType: 2 }));
|
|
5921
6050
|
txp.feeLevel.should.equal('normal');
|
|
5922
|
-
txp.gasPrice.should.equal(
|
|
5923
|
-
txp.fee.should.equal(
|
|
6051
|
+
txp.gasPrice.should.equal(4500000000);
|
|
6052
|
+
txp.fee.should.equal(450000000000000);
|
|
5924
6053
|
txp.maxGasFee.should.equal(4500000000);
|
|
5925
6054
|
txp.priorityGasFee.should.equal(1000000000);
|
|
5926
6055
|
const [raw] = txp.getRawTx();
|
|
@@ -5973,6 +6102,9 @@ describe('Wallet service', function () {
|
|
|
5973
6102
|
await helpers_1.default.stubUtxos(server, wallet, [0.0002]);
|
|
5974
6103
|
const defaultTxp = await util_1.default.promisify(server.createTx).call(server, makeOpts({ tokenAddress }));
|
|
5975
6104
|
defaultTxp.fee.should.equal(100000000000000);
|
|
6105
|
+
sinon_1.default.stub(server, 'estimateFee').resolves(3000000000);
|
|
6106
|
+
sinon_1.default.stub(server, 'estimatePriorityFee').resolves(1000000000);
|
|
6107
|
+
await assert_1.default.rejects(util_1.default.promisify(server.createTx).call(server, makeOpts({ txType: 2, tokenAddress })), { code: tokenAddress ? 'INSUFFICIENT_ETH_FEE' : 'INSUFFICIENT_FUNDS_FOR_FEE' });
|
|
5976
6108
|
await assert_1.default.rejects(util_1.default.promisify(server.createTx).call(server, makeOpts({
|
|
5977
6109
|
txType: 2, maxGasFee: 3000000000, priorityGasFee: 1000000000, tokenAddress
|
|
5978
6110
|
})), { code: tokenAddress ? 'INSUFFICIENT_ETH_FEE' : 'INSUFFICIENT_FUNDS_FOR_FEE' });
|