Skip to content

Commit 01b04c6

Browse files
authored
Merge pull request #277 from EdgeApp/sam/ren-bridge-uri
Add support for Ren Bridge URIs
2 parents 72c1fbe + 061cadb commit 01b04c6

File tree

8 files changed

+179
-39
lines changed

8 files changed

+179
-39
lines changed

src/common/plugin/makeCurrencyTools.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ import {
55
EdgeCurrencyTools,
66
EdgeEncodeUri,
77
EdgeIo,
8-
EdgeMetadata,
98
EdgeMetaToken,
10-
EdgeParsedUri,
119
EdgeWalletInfo,
1210
JsonObject
1311
} from 'edge-core-js/types'
@@ -20,7 +18,7 @@ import {
2018
asPrivateKey,
2119
PrivateKey
2220
} from '../utxobased/keymanager/cleaners'
23-
import { EncodeUriMetadata, PluginInfo } from './types'
21+
import { EncodeUriMetadata, ExtendedParseUri, PluginInfo } from './types'
2422
import { getFormatsForNetwork } from './utils'
2523

2624
/**
@@ -59,7 +57,12 @@ export function makeCurrencyTools(
5957
return numbWalletInfo.keys.publicKey
6058
},
6159

62-
async parseUri(uri: string): Promise<EdgeParsedUri> {
60+
async parseUri(uri: string): Promise<ExtendedParseUri> {
61+
const isGateway = uri
62+
.toLocaleLowerCase()
63+
.startsWith(`${coinInfo.name}://`)
64+
if (isGateway) uri = uri.replace('//', '')
65+
6366
const uriObj = urlParse(uri, {}, true)
6467
const protocol = uriObj.protocol.replace(':', '').toLowerCase()
6568

@@ -79,7 +82,7 @@ export function makeCurrencyTools(
7982
if (pathname === '' && query.r == null) throw new Error('InvalidUriError')
8083

8184
// Create the returned object
82-
const parsedUri: EdgeParsedUri = {}
85+
const parsedUri: ExtendedParseUri = {}
8386
// Parse the pathname and add it to the result object
8487
if (pathname !== '') {
8588
const parsedPath = parsePathname({
@@ -92,11 +95,12 @@ export function makeCurrencyTools(
9295
}
9396

9497
// Assign the query params to the parsedUri object
95-
const metadata: EdgeMetadata = {}
98+
const metadata: ExtendedParseUri['metadata'] = {}
9699
if (query.label != null) metadata.name = query.label
97100
if (query.message != null) metadata.notes = query.message
98101
if (query.category != null) metadata.category = query.category
99102
if (query.r != null) parsedUri.paymentProtocolUrl = query.r
103+
if (isGateway) metadata.gateway = true
100104
Object.assign(parsedUri, { metadata })
101105

102106
// Get amount in native denomination if exists

src/common/plugin/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
EdgeCurrencyInfo,
77
EdgeCurrencyTools,
88
EdgeIo,
9+
EdgeParsedUri,
910
EdgeWalletInfo
1011
} from 'edge-core-js/types'
1112

@@ -115,10 +116,17 @@ interface Bip32 {
115116
private: number
116117
}
117118

119+
export interface ExtendedParseUri extends EdgeParsedUri {
120+
metadata?: EdgeParsedUri['metadata'] & {
121+
gateway?: boolean
122+
}
123+
}
124+
118125
export interface EncodeUriMetadata {
119126
metadata?: {
120127
name?: string
121128
notes?: string
129+
gateway?: boolean
122130
}
123131
}
124132

src/common/utxobased/engine/utils.ts

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ import {
1010
AddressTypeEnum,
1111
bip43PurposeNumberToTypeEnum,
1212
BIP43PurposeTypeEnum,
13-
getAddressTypeFromAddress,
14-
scriptPubkeyToAddress,
1513
ScriptTypeEnum,
1614
seedOrMnemonicToXPriv,
15+
toNewFormat,
1716
verifyAddress,
1817
VerifyAddressEnum,
1918
wifToPrivateKey,
@@ -208,27 +207,16 @@ export const parsePathname = (args: {
208207
coin: args.coin
209208
})
210209

211-
switch (addressFormat) {
212-
case VerifyAddressEnum.good:
213-
edgeParsedUri.publicAddress = args.pathname
214-
break
215-
case VerifyAddressEnum.legacy: {
216-
edgeParsedUri.legacyAddress = args.pathname
217-
// Get the non-legacy address (publicAddress)
218-
const addressType = getAddressTypeFromAddress(args.pathname, args.coin)
219-
edgeParsedUri.publicAddress = scriptPubkeyToAddress({
220-
scriptPubkey: addressToScriptPubkey({
221-
address: args.pathname,
222-
coin: args.coin
223-
}),
224-
addressType,
225-
coin: args.coin
226-
}).address
227-
break
228-
}
229-
case VerifyAddressEnum.bad:
230-
throw new Error('InvalidPublicAddressError')
231-
}
210+
// Throw if address format failed
211+
if (addressFormat === VerifyAddressEnum.bad)
212+
throw new Error('InvalidPublicAddressError')
213+
214+
// Format publicAddress to the latest format from the provided address
215+
edgeParsedUri.publicAddress = toNewFormat(args.pathname, args.coin)
216+
217+
// Include a legacyAddress if the provided format is a legacy format
218+
if (addressFormat === VerifyAddressEnum.legacy)
219+
edgeParsedUri.legacyAddress = args.pathname
232220
}
233221

234222
return edgeParsedUri

src/common/utxobased/keymanager/keymanager.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,18 @@ export function pubkeyToScriptPubkey(
728728
}
729729
}
730730

731+
export const toNewFormat = (address: string, coinName: string): string => {
732+
const addressType = getAddressTypeFromAddress(address, coinName)
733+
return scriptPubkeyToAddress({
734+
scriptPubkey: addressToScriptPubkey({
735+
address: address,
736+
coin: coinName
737+
}),
738+
addressType,
739+
coin: coinName
740+
}).address
741+
}
742+
731743
const xprivToPrivateKeyInternal = (
732744
prefixIndex: number,
733745
args: XPrivToPrivateKeyArgs

test/common/plugin/currencyPlugin.fixtures/common.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import {
2-
EdgeEncodeUri,
3-
EdgeParsedUri,
4-
EdgeWalletInfo
5-
} from 'edge-core-js/types'
1+
import { EdgeEncodeUri, EdgeWalletInfo } from 'edge-core-js/types'
62

7-
import { EncodeUriMetadata } from '../../../../src/common/plugin/types'
3+
import {
4+
EncodeUriMetadata,
5+
ExtendedParseUri
6+
} from '../../../../src/common/plugin/types'
87

98
export interface FixtureType {
109
pluginId: string
@@ -16,7 +15,7 @@ export interface FixtureType {
1615
'invalid key name': EdgeWalletInfo
1716
'invalid wallet type': EdgeWalletInfo
1817
parseUri: {
19-
[testName: string]: [string, EdgeParsedUri] | [string]
18+
[testName: string]: [string, ExtendedParseUri] | [string]
2019
}
2120
encodeUri: {
2221
[testName: string]:

test/common/plugin/currencyPlugin.fixtures/currencies/bitcoin.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,65 @@ export const bitcoin: FixtureType = {
5555
metadata: {}
5656
}
5757
],
58+
'Ren Bridge p2wpkhp2sh Gateway address': [
59+
'bitcoin://3Lx24A66XeL1HtegyNoku77qvNBCbEqePj',
60+
{
61+
publicAddress: '3Lx24A66XeL1HtegyNoku77qvNBCbEqePj',
62+
metadata: {
63+
gateway: true
64+
}
65+
}
66+
],
67+
'Ren Bridge p2pkh Gateway address': [
68+
'bitcoin://1F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX',
69+
{
70+
publicAddress: '1F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX',
71+
metadata: {
72+
gateway: true
73+
}
74+
}
75+
],
76+
'Ren Bridge p2wpkhp2sh Gateway address mixed caps': [
77+
'bitCoin://3Lx24A66XeL1HtegyNoku77qvNBCbEqePj',
78+
{
79+
publicAddress: '3Lx24A66XeL1HtegyNoku77qvNBCbEqePj',
80+
metadata: {
81+
gateway: true
82+
}
83+
}
84+
],
85+
'Ren Bridge p2pkh Gateway address mixed caps': [
86+
'Bitcoin://1F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX',
87+
{
88+
publicAddress: '1F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX',
89+
metadata: {
90+
gateway: true
91+
}
92+
}
93+
],
94+
'Ren Bridge p2pkh Gateway address with amount, label & message': [
95+
'bitcoin://1F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX?amount=1234.56789&label=Johnny%20Bitcoin&message=Hello%20World,%20I%20miss%20you%20!',
96+
{
97+
publicAddress: '1F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX',
98+
metadata: {
99+
name: 'Johnny Bitcoin',
100+
notes: 'Hello World, I miss you !',
101+
gateway: true
102+
},
103+
nativeAmount: '123456789000',
104+
currencyCode: 'BTC'
105+
}
106+
],
107+
'Ren Bridge bech32 Gateway address': [
108+
'bitcoin://bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3',
109+
{
110+
publicAddress:
111+
'bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3',
112+
metadata: {
113+
gateway: true
114+
}
115+
}
116+
],
58117
'uri address with amount': [
59118
'bitcoin:1F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX?amount=12345.6789',
60119
{

test/common/plugin/currencyPlugin.fixtures/currencies/bitcoincash.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,75 @@ export const bitcoincash: FixtureType = {
4343
metadata: {}
4444
}
4545
],
46+
'Ren Bridge Legacy Gateway address': [
47+
'bitcoincash://1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu',
48+
{
49+
publicAddress: 'qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a',
50+
legacyAddress: '1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu',
51+
metadata: {
52+
gateway: true
53+
}
54+
}
55+
],
56+
'Ren Bridge Legacy Gateway address mixed caps': [
57+
'bitCoinCash://1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu',
58+
{
59+
publicAddress: 'qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a',
60+
legacyAddress: '1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu',
61+
metadata: {
62+
gateway: true
63+
}
64+
}
65+
],
66+
'Ren Bridge new Gateway address': [
67+
'bitcoincash://qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a',
68+
{
69+
publicAddress: 'qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a',
70+
metadata: {
71+
gateway: true
72+
}
73+
}
74+
],
75+
'Ren Bridge mixed caps Gateway address with address prefix': [
76+
'bitcoinCash://bitcoincash:pzyt5lcqp4u4wcwpwl8f8eq0hzpdnntzuy2h3nnalf',
77+
{
78+
publicAddress: 'pzyt5lcqp4u4wcwpwl8f8eq0hzpdnntzuy2h3nnalf',
79+
metadata: {
80+
gateway: true
81+
}
82+
}
83+
],
84+
'Ren Bridge mixed caps Gateway address w/o address prefix': [
85+
'bitcoinCash://pzyt5lcqp4u4wcwpwl8f8eq0hzpdnntzuy2h3nnalf',
86+
{
87+
publicAddress: 'pzyt5lcqp4u4wcwpwl8f8eq0hzpdnntzuy2h3nnalf',
88+
metadata: {
89+
gateway: true
90+
}
91+
}
92+
],
93+
'Ren Bridge weird caps Gateway address': [
94+
'BiTcOiNcAsH://bitcoincash:pzyt5lcqp4u4wcwpwl8f8eq0hzpdnntzuy2h3nnalf',
95+
{
96+
publicAddress: 'pzyt5lcqp4u4wcwpwl8f8eq0hzpdnntzuy2h3nnalf',
97+
metadata: {
98+
gateway: true
99+
}
100+
}
101+
],
102+
'Ren Bridge new Gateway address with amount, label & message': [
103+
'bitcoincash://qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a?amount=1234.56789&label=Johnny%20Bitcoincash&message=Hello%20World,%20I%20miss%20you%20!',
104+
{
105+
publicAddress: 'qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a',
106+
metadata: {
107+
name: 'Johnny Bitcoincash',
108+
notes: 'Hello World, I miss you !',
109+
gateway: true
110+
},
111+
nativeAmount: '123456789000',
112+
currencyCode: 'BCH'
113+
}
114+
],
46115
'uri address with amount': [
47116
'bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a?amount=12345.6789',
48117
{

test/common/utxobased/addressFormat/addressFormatIndex/addressFormat.spec.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { describe, it } from 'mocha'
55

66
import { parsePathname } from '../../../../../src/common/utxobased/engine/utils'
77
import {
8+
toNewFormat,
89
verifyAddress,
910
VerifyAddressEnum
1011
} from '../../../../../src/common/utxobased/keymanager/keymanager'
@@ -24,7 +25,7 @@ for (const fixture of fixtures) {
2425
)
2526
assert.equal(
2627
parsePathname({ pathname: address, coin: network }).publicAddress,
27-
address
28+
toNewFormat(address, network)
2829
)
2930
})
3031
})
@@ -51,7 +52,7 @@ for (const fixture of fixtures) {
5152
assert.deepEqual(parsePathname({ pathname: address, coin: network }), {
5253
// Uncomment this line if/when we change to always include legacy addresses
5354
// legacyAddress: _legacy,
54-
publicAddress: address
55+
publicAddress: toNewFormat(address, network)
5556
})
5657
})
5758
})
@@ -64,7 +65,7 @@ for (const fixture of fixtures) {
6465
)
6566
assert.deepEqual(parsePathname({ pathname: legacy, coin: network }), {
6667
legacyAddress: legacy,
67-
publicAddress: address
68+
publicAddress: toNewFormat(address, network)
6869
})
6970
})
7071
})

0 commit comments

Comments
 (0)