Skip to content

Commit

Permalink
ADD: support for deeplinks (closes BlueWallet#892)
Browse files Browse the repository at this point in the history
  • Loading branch information
Overtorment committed Apr 30, 2020
1 parent cccbfb2 commit 3479fbd
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 10 deletions.
10 changes: 8 additions & 2 deletions class/deeplink-schema-match.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ class DeeplinkSchemaMatch {
* Examines the content of the event parameter.
* If the content is recognizable, create a dictionary with the respective
* navigation dictionary required by react-navigation
* @param {Object} event
* @param {void} completionHandler
*
* @param event {{url: string}} URL deeplink as passed to app, e.g. `bitcoin:bc1qh6tf004ty7z7un2v5ntu4mkf630545gvhs45u7?amount=666&label=Yo`
* @param completionHandler {function} Returns {routeName: string, params: object}
*/
static navigationRouteFor(event, completionHandler) {
if (event.url === null) {
Expand All @@ -35,6 +36,11 @@ class DeeplinkSchemaMatch {
if (typeof event.url !== 'string') {
return;
}

if (event.url.toLowerCase().startsWith('bluewallet:bitcoin:') || event.url.toLowerCase().startsWith('bluewallet:lightning:')) {
event.url = event.url.substring(11);
}

if (DeeplinkSchemaMatch.isPossiblyPSBTFile(event.url)) {
RNFS.readFile(event.url)
.then(file => {
Expand Down
100 changes: 92 additions & 8 deletions tests/unit/deeplink-schema-match.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,22 @@ describe('unit - DeepLinkSchemaMatch', function() {
assert.ok(DeeplinkSchemaMatch.hasSchema('bitcoin:BC1QH6TF004TY7Z7UN2V5NTU4MKF630545GVHS45U7?amount=666&label=Yo'));
assert.ok(DeeplinkSchemaMatch.hasSchema('BITCOIN:BC1Q3RL0MKYK0ZRTXFMQN9WPCD3GNAZ00YV9YP0HXE'));
assert.ok(DeeplinkSchemaMatch.hasSchema('BITCOIN:BC1Q3RL0MKYK0ZRTXFMQN9WPCD3GNAZ00YV9YP0HXE?amount=666&label=Yo'));
assert.ok(
DeeplinkSchemaMatch.hasSchema(
'lightning:lnbc10u1pwjqwkkpp5vlc3tttdzhpk9fwzkkue0sf2pumtza7qyw9vucxyyeh0yaqq66yqdq5f38z6mmwd3ujqar9wd6qcqzpgxq97zvuqrzjqvgptfurj3528snx6e3dtwepafxw5fpzdymw9pj20jj09sunnqmwqz9hx5qqtmgqqqqqqqlgqqqqqqgqjq5duu3fs9xq9vn89qk3ezwpygecu4p3n69wm3tnl28rpgn2gmk5hjaznemw0gy32wrslpn3g24khcgnpua9q04fttm2y8pnhmhhc2gncplz0zde',
),
);

assert.ok(DeeplinkSchemaMatch.hasSchema('bluewallet:bitcoin:12eQ9m4sgAwTSQoNXkRABKhCXCsjm2jdVG'));
assert.ok(DeeplinkSchemaMatch.hasSchema('bluewallet:bitcoin:bc1qh6tf004ty7z7un2v5ntu4mkf630545gvhs45u7?amount=666&label=Yo'));
assert.ok(DeeplinkSchemaMatch.hasSchema('bluewallet:bitcoin:BC1QH6TF004TY7Z7UN2V5NTU4MKF630545GVHS45U7?amount=666&label=Yo'));
assert.ok(DeeplinkSchemaMatch.hasSchema('bluewallet:BITCOIN:BC1Q3RL0MKYK0ZRTXFMQN9WPCD3GNAZ00YV9YP0HXE'));
assert.ok(DeeplinkSchemaMatch.hasSchema('bluewallet:BITCOIN:BC1Q3RL0MKYK0ZRTXFMQN9WPCD3GNAZ00YV9YP0HXE?amount=666&label=Yo'));
assert.ok(
DeeplinkSchemaMatch.hasSchema(
'bluewallet:lightning:lnbc10u1pwjqwkkpp5vlc3tttdzhpk9fwzkkue0sf2pumtza7qyw9vucxyyeh0yaqq66yqdq5f38z6mmwd3ujqar9wd6qcqzpgxq97zvuqrzjqvgptfurj3528snx6e3dtwepafxw5fpzdymw9pj20jj09sunnqmwqz9hx5qqtmgqqqqqqqlgqqqqqqgqjq5duu3fs9xq9vn89qk3ezwpygecu4p3n69wm3tnl28rpgn2gmk5hjaznemw0gy32wrslpn3g24khcgnpua9q04fttm2y8pnhmhhc2gncplz0zde',
),
);
});

it('isBitcoin Address', () => {
Expand Down Expand Up @@ -55,16 +71,84 @@ describe('unit - DeepLinkSchemaMatch', function() {
assert.ok(!DeeplinkSchemaMatch.isSafelloRedirect({ url: 'bluewallet:' }));
});

it('navigationForRoute', () => {
const event = { uri: '12eQ9m4sgAwTSQoNXkRABKhCXCsjm2jdVG' };
DeeplinkSchemaMatch.navigationRouteFor(event, navValue => {
assert.strictEqual(navValue, {
routeName: 'SendDetails',
params: {
uri: event.url,
it('navigationForRoute', async () => {
const events = [
{
argument: { url: '12eQ9m4sgAwTSQoNXkRABKhCXCsjm2jdVG' },
expected: {
routeName: 'SendDetails',
params: {
uri: '12eQ9m4sgAwTSQoNXkRABKhCXCsjm2jdVG',
},
},
},
{
argument: { url: 'bitcoin:12eQ9m4sgAwTSQoNXkRABKhCXCsjm2jdVG' },
expected: {
routeName: 'SendDetails',
params: {
uri: 'bitcoin:12eQ9m4sgAwTSQoNXkRABKhCXCsjm2jdVG',
},
},
},
{
argument: { url: 'BITCOIN:BC1Q3RL0MKYK0ZRTXFMQN9WPCD3GNAZ00YV9YP0HXE?amount=666&label=Yo' },
expected: {
routeName: 'SendDetails',
params: {
uri: 'BITCOIN:BC1Q3RL0MKYK0ZRTXFMQN9WPCD3GNAZ00YV9YP0HXE?amount=666&label=Yo',
},
},
},
{
argument: { url: 'bluewallet:BITCOIN:BC1Q3RL0MKYK0ZRTXFMQN9WPCD3GNAZ00YV9YP0HXE?amount=666&label=Yo' },
expected: {
routeName: 'SendDetails',
params: {
uri: 'BITCOIN:BC1Q3RL0MKYK0ZRTXFMQN9WPCD3GNAZ00YV9YP0HXE?amount=666&label=Yo',
},
},
},
{
argument: {
url:
'lightning:lnbc10u1pwjqwkkpp5vlc3tttdzhpk9fwzkkue0sf2pumtza7qyw9vucxyyeh0yaqq66yqdq5f38z6mmwd3ujqar9wd6qcqzpgxq97zvuqrzjqvgptfurj3528snx6e3dtwepafxw5fpzdymw9pj20jj09sunnqmwqz9hx5qqtmgqqqqqqqlgqqqqqqgqjq5duu3fs9xq9vn89qk3ezwpygecu4p3n69wm3tnl28rpgn2gmk5hjaznemw0gy32wrslpn3g24khcgnpua9q04fttm2y8pnhmhhc2gncplz0zde',
},
expected: {
routeName: 'ScanLndInvoice',
params: {
uri:
'lightning:lnbc10u1pwjqwkkpp5vlc3tttdzhpk9fwzkkue0sf2pumtza7qyw9vucxyyeh0yaqq66yqdq5f38z6mmwd3ujqar9wd6qcqzpgxq97zvuqrzjqvgptfurj3528snx6e3dtwepafxw5fpzdymw9pj20jj09sunnqmwqz9hx5qqtmgqqqqqqqlgqqqqqqgqjq5duu3fs9xq9vn89qk3ezwpygecu4p3n69wm3tnl28rpgn2gmk5hjaznemw0gy32wrslpn3g24khcgnpua9q04fttm2y8pnhmhhc2gncplz0zde',
},
},
},
{
argument: {
url:
'bluewallet:lightning:lnbc10u1pwjqwkkpp5vlc3tttdzhpk9fwzkkue0sf2pumtza7qyw9vucxyyeh0yaqq66yqdq5f38z6mmwd3ujqar9wd6qcqzpgxq97zvuqrzjqvgptfurj3528snx6e3dtwepafxw5fpzdymw9pj20jj09sunnqmwqz9hx5qqtmgqqqqqqqlgqqqqqqgqjq5duu3fs9xq9vn89qk3ezwpygecu4p3n69wm3tnl28rpgn2gmk5hjaznemw0gy32wrslpn3g24khcgnpua9q04fttm2y8pnhmhhc2gncplz0zde',
},
expected: {
routeName: 'ScanLndInvoice',
params: {
uri:
'lightning:lnbc10u1pwjqwkkpp5vlc3tttdzhpk9fwzkkue0sf2pumtza7qyw9vucxyyeh0yaqq66yqdq5f38z6mmwd3ujqar9wd6qcqzpgxq97zvuqrzjqvgptfurj3528snx6e3dtwepafxw5fpzdymw9pj20jj09sunnqmwqz9hx5qqtmgqqqqqqqlgqqqqqqgqjq5duu3fs9xq9vn89qk3ezwpygecu4p3n69wm3tnl28rpgn2gmk5hjaznemw0gy32wrslpn3g24khcgnpua9q04fttm2y8pnhmhhc2gncplz0zde',
},
},
},
];

const asyncNavigationRouteFor = async function(event) {
return new Promise(function(resolve) {
DeeplinkSchemaMatch.navigationRouteFor(event, navValue => {
resolve(navValue);
});
});
});
};

for (let event of events) {
let navValue = await asyncNavigationRouteFor(event.argument);
assert.deepStrictEqual(navValue, event.expected);
}
});

it('decodes bip21', () => {
Expand Down

0 comments on commit 3479fbd

Please sign in to comment.