Skip to content

Commit 3927859

Browse files
authored
feat(send): add unified onchain/lightning switch (#2324)
* feat(send): add unified onchain/lightning switch * fix(send): max amount when switching payment method * fix(send): toast message with 0 onchain * fix: type errors * fix(send): unified exceeding balances
1 parent aeb535b commit 3927859

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1806
-1634
lines changed

__tests__/scanner.ts

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,94 @@
1-
import { findlnurl } from '../src/utils/lnurl';
2-
import { TBitcoinUrl, decodeQRData } from '../src/utils/scanner';
1+
import { findLnUrl } from '../src/utils/lnurl';
2+
import { EAvailableNetwork } from '../src/utils/networks';
3+
import { parseUri } from '../src/utils/scanner/scanner';
4+
import { TBitcoinData } from '../src/utils/scanner/types';
35

46
describe('QR codes', () => {
57
it('decodes a bitcoin URI with params', async () => {
6-
const res = await decodeQRData(
8+
const res = await parseUri(
79
'bitcoin:1P5ZEDWTKTFGxQjZphgWPQUpe554WKDfHQ?amount=0.0005&label=Nakamoto&message=Donation%20for%20project%20xyz',
10+
EAvailableNetwork.bitcoin,
811
);
912
if (res.isErr()) {
1013
throw res.error;
1114
}
12-
const qrData = res.value[0] as TBitcoinUrl;
15+
const qrData = res.value as TBitcoinData;
1316
expect(qrData.network).toEqual('bitcoin');
14-
expect(qrData.qrDataType).toEqual('bitcoinAddress');
15-
expect(qrData.sats).toEqual(50000);
17+
expect(qrData.type).toEqual('onchain');
18+
expect(qrData.amount).toEqual(50000);
1619
expect(qrData.message).toEqual('Donation for project xyz');
1720
});
1821

1922
it('decodes a bitcoin legacy address URI', async () => {
20-
const res = await decodeQRData(
23+
const res = await parseUri(
2124
'bitcoin:1P5ZEDWTKTFGxQjZphgWPQUpe554WKDfHQ',
25+
EAvailableNetwork.bitcoin,
2226
);
2327
if (res.isErr()) {
2428
throw res.error;
2529
}
26-
const qrData = res.value[0] as TBitcoinUrl;
30+
const qrData = res.value as TBitcoinData;
2731
expect(qrData.network).toEqual('bitcoin');
28-
expect(qrData.qrDataType).toEqual('bitcoinAddress');
32+
expect(qrData.type).toEqual('onchain');
2933
});
3034

3135
it('decodes a bitcoin wrapped segwit address URI', async () => {
32-
const res = await decodeQRData(
36+
const res = await parseUri(
3337
'bitcoin:3DrziWGfPSYWZpmGxL4WytNeXA2mwzEwWJ',
38+
EAvailableNetwork.bitcoin,
3439
);
3540
if (res.isErr()) {
3641
throw res.error;
3742
}
38-
const qrData = res.value[0] as TBitcoinUrl;
43+
const qrData = res.value as TBitcoinData;
3944
expect(qrData.network).toEqual('bitcoin');
40-
expect(qrData.qrDataType).toEqual('bitcoinAddress');
45+
expect(qrData.type).toEqual('onchain');
4146
});
4247

4348
it('decodes a bitcoin native segwit address URI', async () => {
44-
const res = await decodeQRData(
49+
const res = await parseUri(
4550
'bitcoin:bc1qkk0vs43wzsundw37f8xslw69eddwfe24w9pyrg',
51+
EAvailableNetwork.bitcoin,
4652
);
4753
if (res.isErr()) {
4854
throw res.error;
4955
}
50-
const qrData = res.value[0] as TBitcoinUrl;
56+
const qrData = res.value as TBitcoinData;
5157
expect(qrData.network).toEqual('bitcoin');
52-
expect(qrData.qrDataType).toEqual('bitcoinAddress');
58+
expect(qrData.type).toEqual('onchain');
5359
});
5460

5561
it('decodes a plain bitcoin native segwit address', async () => {
56-
const res = await decodeQRData(
62+
const res = await parseUri(
5763
'bc1qkk0vs43wzsundw37f8xslw69eddwfe24w9pyrg',
64+
EAvailableNetwork.bitcoin,
5865
);
5966
if (res.isErr()) {
6067
throw res.error;
6168
}
62-
const qrData = res.value[0] as TBitcoinUrl;
69+
const qrData = res.value as TBitcoinData;
6370
expect(qrData.network).toEqual('bitcoin');
64-
expect(qrData.qrDataType).toEqual('bitcoinAddress');
71+
expect(qrData.type).toEqual('onchain');
6572
});
6673

6774
it('finds lnurl', async () => {
6875
const base =
6976
'lnurl1dp68gurn8ghj7mrww3uxymm59e3xjemnw4hzu7re0ghkcmn4wfkz7urp0ylh2um9wf5kg0fhxycnv9g9w58';
70-
expect(findlnurl(base)).toEqual(base);
71-
expect(findlnurl(base.toUpperCase())).toEqual(base);
72-
expect(findlnurl('https://site.com/?lightning=' + base)).toEqual(base);
77+
expect(findLnUrl(base)).toEqual(base);
78+
expect(findLnUrl(base.toUpperCase())).toEqual(base);
79+
expect(findLnUrl('https://site.com/?lightning=' + base)).toEqual(base);
7380
expect(
74-
findlnurl('https://site.com/?lightning=' + base.toUpperCase()),
81+
findLnUrl('https://site.com/?lightning=' + base.toUpperCase()),
7582
).toEqual(base);
76-
expect(findlnurl('https://site.com/?nada=nada&lightning=' + base)).toEqual(
83+
expect(findLnUrl('https://site.com/?nada=nada&lightning=' + base)).toEqual(
7784
base,
7885
);
7986
expect(
80-
findlnurl('https://site.com/?nada=nada&lightning=' + base.toUpperCase()),
87+
findLnUrl('https://site.com/?nada=nada&lightning=' + base.toUpperCase()),
8188
).toEqual(base);
82-
expect(findlnurl('bs')).toEqual(null);
83-
expect(findlnurl('https://site.com')).toEqual(null);
84-
expect(findlnurl('https://site.com/?bs=' + base)).toEqual(null);
85-
expect(findlnurl('bitcoin:site.com/?lightning=' + base)).toEqual(base);
89+
expect(findLnUrl('bs')).toEqual(null);
90+
expect(findLnUrl('https://site.com')).toEqual(null);
91+
expect(findLnUrl('https://site.com/?bs=' + base)).toEqual(null);
92+
expect(findLnUrl('bitcoin:site.com/?lightning=' + base)).toEqual(base);
8693
});
8794
});

e2e/helpers.js

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,9 @@ export const sleep = (ms) => {
4747
});
4848
};
4949

50-
export const isVisible = async (id) => {
51-
try {
52-
await expect(element(by.id(id))).toBeVisible();
53-
return true;
54-
} catch (e) {
55-
return false;
56-
}
57-
};
58-
5950
export const isButtonEnabled = async (element) => {
60-
try {
61-
await expect(element).tap();
62-
return true;
63-
} catch (e) {
64-
return false;
65-
}
51+
const attributes = await element.getAttributes();
52+
return attributes.label !== 'disabled';
6653
};
6754

6855
export async function waitForElementAttribute(
@@ -143,6 +130,25 @@ export const launchAndWait = async () => {
143130
}
144131
};
145132

133+
export const receiveOnchainFunds = async (rpc, amount = '0.001') => {
134+
await element(by.id('Receive')).tap();
135+
// Wait for animation
136+
await sleep(1000);
137+
// Get address from QR code
138+
let { label: wAddress } = await element(by.id('QRCode')).getAttributes();
139+
wAddress = wAddress.replace('bitcoin:', '');
140+
141+
// Send and mine
142+
await rpc.sendToAddress(wAddress, amount);
143+
await rpc.generateToAddress(1, await rpc.getNewAddress());
144+
145+
await waitFor(element(by.id('NewTxPrompt')))
146+
.toBeVisible()
147+
.withTimeout(10000);
148+
await element(by.id('NewTxPrompt')).swipe('down');
149+
await sleep(1000);
150+
};
151+
146152
export const waitForPeerConnection = async (lnd, nodeId, maxRetries = 20) => {
147153
let retries = 0;
148154

e2e/onchain.e2e.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ d('Onchain', () => {
9999
await element(by.id('AddressContinue')).tap();
100100

101101
// Amount / NumberPad
102-
await element(by.id('SendNumberPadMax')).tap();
102+
await element(by.id('AvailableAmount')).tap();
103103
// cat't use .multitap here, doesn't work properly
104104
// maybe some race condition in beignet library ?
105105
await element(
@@ -112,7 +112,7 @@ d('Onchain', () => {
112112
by.id('NRemove').withAncestor(by.id('SendAmountNumberPad')),
113113
).tap();
114114
await expect(element(by.text('199 999'))).toBeVisible();
115-
await element(by.id('SendNumberPadMax')).tap();
115+
await element(by.id('AvailableAmount')).tap();
116116
await element(by.id('ContinueAmount')).tap();
117117

118118
// Review & Send

0 commit comments

Comments
 (0)