Skip to content

Commit 8d4e20f

Browse files
committed
Add new parseLink and encodePayLink methods
1 parent 1c93393 commit 8d4e20f

7 files changed

Lines changed: 373 additions & 29 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Unreleased
44

5+
- added: `EdgeCurrencyConfig.encodePayLink`
6+
- added: `EdgeCurrencyConfig.parseLink`
7+
- deprecated: `EdgeCurrencyWallet.encodeUri`. Use `EdgeCurrencyConfig.encodePayLink`
8+
- deprecated: `EdgeCurrencyWallet.parseUri`. Use `EdgeCurrencyConfig.parseLink`
59
- fixed: Avoid deprecated Gradle syntax.
610

711
## 2.34.0 (2025-08-25)

src/core/account/plugin-api.ts

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,20 @@ import {
55
EdgeCurrencyInfo,
66
EdgeGetTokenDetailsFilter,
77
EdgeOtherMethods,
8+
EdgeParsedLink,
9+
EdgePayLink,
810
EdgeSwapConfig,
911
EdgeSwapInfo,
1012
EdgeToken,
13+
EdgeTokenId,
1114
EdgeTokenMap
1215
} from '../../types/types'
16+
import { parsedUriToLink } from '../currency/uri-tools'
1317
import { uniqueStrings } from '../currency/wallet/enabled-tokens'
1418
import { getCurrencyTools } from '../plugins/plugins-selectors'
1519
import { ApiInput } from '../root-pixie'
1620
import { changePluginUserSettings, changeSwapSettings } from './account-files'
17-
import { getTokenId } from './custom-tokens'
21+
import { getTokenId, makeMetaTokens } from './custom-tokens'
1822

1923
const emptyTokens: EdgeTokenMap = {}
2024
const emptyTokenIds: string[] = []
@@ -186,6 +190,54 @@ export class CurrencyConfig
186190
)
187191
}
188192

193+
async parseLink(
194+
link: string,
195+
opts: { tokenId?: EdgeTokenId } = {}
196+
): Promise<EdgeParsedLink> {
197+
const { tokenId } = opts
198+
const { allTokens } = this
199+
const tools = await getCurrencyTools(this._ai, this._pluginId)
200+
201+
if (tools.parseLink != null) {
202+
return await tools.parseLink(link, { tokenId, allTokens })
203+
}
204+
205+
// Fallback version:
206+
if (tools.parseUri != null) {
207+
const out = await tools.parseUri(
208+
link,
209+
this.downgradeTokenId(tokenId),
210+
makeMetaTokens(this.customTokens)
211+
)
212+
return parsedUriToLink(out, this.currencyInfo, allTokens)
213+
}
214+
215+
return {}
216+
}
217+
218+
async encodePayLink(link: EdgePayLink): Promise<string> {
219+
const { tokenId } = link
220+
const { allTokens } = this
221+
const tools = await getCurrencyTools(this._ai, this._pluginId)
222+
223+
if (tools.encodePayLink != null) {
224+
return await tools.encodePayLink(link, { allTokens })
225+
}
226+
227+
// Fallback version:
228+
if (tools.encodeUri != null) {
229+
return await tools.encodeUri(
230+
{
231+
...link,
232+
currencyCode: this.downgradeTokenId(tokenId)
233+
},
234+
makeMetaTokens(this.customTokens)
235+
)
236+
}
237+
238+
return ''
239+
}
240+
189241
async importKey(
190242
userInput: string,
191243
opts: { keyOptions?: object } = {}
@@ -198,6 +250,13 @@ export class CurrencyConfig
198250
const keys = await tools.importPrivateKey(userInput, opts.keyOptions)
199251
return { ...keys, imported: true }
200252
}
253+
254+
private downgradeTokenId(tokenId?: EdgeTokenId): string | undefined {
255+
if (tokenId === undefined) return
256+
return tokenId == null
257+
? this.currencyInfo.currencyCode
258+
: this.allTokens[tokenId]?.currencyCode
259+
}
201260
}
202261

203262
export class SwapConfig extends Bridgeable<EdgeSwapConfig> {

src/core/currency/uri-tools.ts

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
import {
2+
EdgeCurrencyInfo,
3+
EdgeParsedLink,
4+
EdgeParsedUri,
5+
EdgeTokenMap
6+
} from '../../types/types'
7+
import { makeMetaToken } from '../account/custom-tokens'
8+
9+
export function parsedUriToLink(
10+
uri: EdgeParsedUri,
11+
currencyInfo: EdgeCurrencyInfo,
12+
allTokens: EdgeTokenMap
13+
): EdgeParsedLink {
14+
const {
15+
// Edge has never supported BitID:
16+
// bitIDCallbackUri,
17+
// bitIDDomain,
18+
// bitidKycProvider, // Experimental
19+
// bitidKycRequest, // Experimental
20+
// bitidPaymentAddress, // Experimental
21+
// bitIDURI,
22+
23+
// The GUI handles address requests:
24+
// returnUri,
25+
26+
currencyCode,
27+
expireDate,
28+
legacyAddress,
29+
metadata,
30+
minNativeAmount,
31+
nativeAmount,
32+
paymentProtocolUrl,
33+
privateKeys,
34+
publicAddress,
35+
segwitAddress,
36+
token,
37+
uniqueIdentifier,
38+
walletConnect
39+
} = uri
40+
let { tokenId } = uri
41+
42+
if (tokenId === undefined && currencyCode != null) {
43+
tokenId =
44+
currencyCode === currencyInfo.currencyCode
45+
? null
46+
: Object.keys(allTokens).find(
47+
tokenId => allTokens[tokenId].currencyCode === currencyCode
48+
)
49+
}
50+
51+
const out: EdgeParsedLink = {}
52+
53+
// Payment addresses:
54+
if (publicAddress != null) {
55+
out.pay = {
56+
publicAddress: legacyAddress ?? publicAddress ?? segwitAddress,
57+
addressType:
58+
legacyAddress != null
59+
? 'legacyAddress'
60+
: publicAddress != null
61+
? 'publicAddress'
62+
: 'segwitAddress',
63+
label: metadata?.name,
64+
message: metadata?.notes,
65+
memo: uniqueIdentifier,
66+
memoType: 'text',
67+
nativeAmount: nativeAmount,
68+
minNativeAmount: minNativeAmount,
69+
tokenId: tokenId,
70+
expires: expireDate,
71+
isGateway: (metadata as any)?.gateway // Undocumented feature
72+
}
73+
}
74+
75+
if (paymentProtocolUrl != null) {
76+
out.paymentProtocol = { paymentProtocolUrl }
77+
}
78+
79+
// Private keys:
80+
if (privateKeys != null && privateKeys.length > 0) {
81+
out.privateKey = { privateKey: privateKeys[0] }
82+
}
83+
84+
// Custom tokens:
85+
if (token != null) {
86+
const { contractAddress, currencyCode, currencyName, denominations } = token
87+
out.token = {
88+
currencyCode,
89+
denominations,
90+
displayName: currencyName,
91+
networkLocation: {
92+
contractAddress,
93+
type: (token as any).type // Undocumented EVM token type
94+
}
95+
}
96+
}
97+
98+
if (walletConnect != null) {
99+
out.walletConnect = walletConnect
100+
}
101+
102+
return out
103+
}
104+
105+
export function linkToParsedUri(link: EdgeParsedLink): EdgeParsedUri {
106+
const out: EdgeParsedUri = {}
107+
108+
// Payment addresses:
109+
if (link.pay != null) {
110+
const {
111+
publicAddress,
112+
addressType,
113+
label,
114+
message,
115+
memo,
116+
nativeAmount,
117+
minNativeAmount,
118+
tokenId,
119+
expires,
120+
isGateway
121+
} = link.pay
122+
out.publicAddress = publicAddress
123+
if (addressType === 'legacyAddress') out.legacyAddress = publicAddress
124+
if (addressType === 'segwitAddress') out.segwitAddress = publicAddress
125+
out.metadata = {
126+
name: label,
127+
notes: message,
128+
// @ts-expect-error Undocumented feature:
129+
gateway: isGateway
130+
}
131+
out.uniqueIdentifier = memo
132+
out.nativeAmount = nativeAmount
133+
out.minNativeAmount = minNativeAmount
134+
out.tokenId = tokenId
135+
out.expireDate = expires
136+
;(out as any).gateway = isGateway
137+
}
138+
139+
// Payment protocol:
140+
if (link.paymentProtocol != null) {
141+
const { paymentProtocolUrl } = link.paymentProtocol
142+
out.paymentProtocolUrl = paymentProtocolUrl
143+
}
144+
145+
// Private keys:
146+
if (link.privateKey != null) {
147+
const { privateKey } = link.privateKey
148+
out.privateKeys = [privateKey]
149+
}
150+
151+
// Custom tokens:
152+
if (link.token != null) {
153+
out.token = makeMetaToken(link.token)
154+
// @ts-expect-error Undocumented "ERC20" field:
155+
out.token.type = link.token.networkLocation.type
156+
}
157+
158+
if (link.walletConnect != null) {
159+
out.walletConnect = link.walletConnect
160+
}
161+
162+
return out
163+
}

src/core/currency/wallet/currency-wallet-api.ts

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import { makeMetaTokens } from '../../account/custom-tokens'
4343
import { toApiInput } from '../../root-pixie'
4444
import { makeStorageWalletApi } from '../../storage/storage-api'
4545
import { getCurrencyMultiplier } from '../currency-selectors'
46+
import { linkToParsedUri } from '../uri-tools'
4647
import { makeCurrencyWalletCallbacks } from './currency-wallet-callbacks'
4748
import {
4849
asEdgeAssetAction,
@@ -724,31 +725,68 @@ export function makeCurrencyWalletApi(
724725

725726
// URI handling:
726727
async encodeUri(options: EdgeEncodeUri): Promise<string> {
727-
return await tools.encodeUri(
728-
options,
729-
makeMetaTokens(
730-
input.props.state.accounts[accountId].customTokens[pluginId]
728+
const allTokens =
729+
input.props.state.accounts[accountId].allTokens[pluginId]
730+
731+
if (tools.encodePayLink != null) {
732+
const { tokenId = null } = upgradeCurrencyCode({
733+
allTokens,
734+
currencyInfo: plugin.currencyInfo,
735+
currencyCode: options.currencyCode
736+
})
737+
return await tools.encodePayLink(
738+
{ ...options, addressType: 'publicAddress', tokenId },
739+
{ allTokens }
731740
)
732-
)
741+
}
742+
743+
if (tools.encodeUri != null) {
744+
return await tools.encodeUri(
745+
options,
746+
makeMetaTokens(
747+
input.props.state.accounts[accountId].customTokens[pluginId]
748+
)
749+
)
750+
}
751+
752+
return ''
733753
},
754+
734755
async parseUri(uri: string, currencyCode?: string): Promise<EdgeParsedUri> {
735-
const parsedUri = await tools.parseUri(
736-
uri,
737-
currencyCode,
738-
makeMetaTokens(
739-
input.props.state.accounts[accountId].customTokens[pluginId]
740-
)
741-
)
756+
const allTokens =
757+
input.props.state.accounts[accountId].allTokens[pluginId]
742758

743-
if (parsedUri.tokenId === undefined) {
759+
if (tools.parseLink != null) {
744760
const { tokenId = null } = upgradeCurrencyCode({
745-
allTokens: input.props.state.accounts[accountId].allTokens[pluginId],
761+
allTokens,
746762
currencyInfo: plugin.currencyInfo,
747-
currencyCode: parsedUri.currencyCode ?? currencyCode
763+
currencyCode
748764
})
749-
parsedUri.tokenId = tokenId
765+
const out = await tools.parseLink(uri, { allTokens, tokenId })
766+
return linkToParsedUri(out)
767+
}
768+
769+
if (tools.parseUri != null) {
770+
const parsedUri = await tools.parseUri(
771+
uri,
772+
currencyCode,
773+
makeMetaTokens(
774+
input.props.state.accounts[accountId].customTokens[pluginId]
775+
)
776+
)
777+
778+
if (parsedUri.tokenId === undefined) {
779+
const { tokenId = null } = upgradeCurrencyCode({
780+
allTokens,
781+
currencyInfo: plugin.currencyInfo,
782+
currencyCode: parsedUri.currencyCode ?? currencyCode
783+
})
784+
parsedUri.tokenId = tokenId
785+
}
786+
return parsedUri
750787
}
751-
return parsedUri
788+
789+
return {}
752790
},
753791

754792
// Generic:

0 commit comments

Comments
 (0)