Skip to content

Commit 71fd5ed

Browse files
committed
Add RNS multichchain resolution in Transfer page
1 parent fa94606 commit 71fd5ed

6 files changed

Lines changed: 128 additions & 2 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
"lodash": "^4.17.21",
8484
"loglevel": "^1.8.1",
8585
"multi-token-standard-abi": "1.0.4",
86+
"node-fetch": "^2.0.0",
8687
"pify": "^5.0.0",
8788
"pump": "^3.0.0",
8889
"readable-stream": "^3.6.0",

src/components/WalletTransfer/AddContact/AddContact.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ import {
5454
GOOGLE_LABEL,
5555
REDDIT,
5656
REDDIT_LABEL,
57+
RNS,
58+
RNS_LABEL,
5759
TWITTER,
5860
TWITTER_LABEL,
5961
UNSTOPPABLE_DOMAINS,
@@ -68,6 +70,7 @@ const VERIFIER_LABELS = {
6870
[TWITTER]: TWITTER_LABEL,
6971
[GITHUB]: GITHUB_LABEL,
7072
[ENS]: ENS_LABEL,
73+
[RNS]: RNS_LABEL,
7174
[BIT]: BIT_LABEL,
7275
[UNSTOPPABLE_DOMAINS]: UNSTOPPABLE_DOMAINS_LABEL,
7376
}

src/containers/WalletTransfer/WalletTransfer.vue

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@
141141
:items="getToAddressComboboxItems"
142142
:placeholder="verifierPlaceholder"
143143
required
144-
:rules="[contactRule, rules.contactRequired, ensRule, unstoppableDomainsRule, bitRule, torusRule]"
144+
:rules="[contactRule, rules.contactRequired, ensRule, rnsRule, unstoppableDomainsRule, bitRule, torusRule]"
145145
outlined
146146
item-text="name"
147147
item-value="value"
@@ -544,6 +544,7 @@ import {
544544
MESSAGE_MODAL_TYPE_SUCCESS,
545545
OLD_ERC721_LIST,
546546
REDDIT,
547+
RNS,
547548
TRANSACTION_SPEED,
548549
TWITTER,
549550
UNSTOPPABLE_DOMAINS,
@@ -594,6 +595,7 @@ export default {
594595
toAddress: '',
595596
formValid: false,
596597
ensError: '',
598+
rnsError: '',
597599
bitError: '',
598600
torusError: '',
599601
unstoppableDomainsError: '',
@@ -848,7 +850,7 @@ export default {
848850
this.$vuetify.goTo(0)
849851
},
850852
methods: {
851-
...mapActions(['getTorusLookupAddress', 'getEnsOrUnstoppableAddress']),
853+
...mapActions(['getTorusLookupAddress', 'getEnsOrUnstoppableAddress', 'getRnsAddress']),
852854
startQrScanning() {
853855
this.camera = 'auto'
854856
this.showQrScanner = true
@@ -862,6 +864,8 @@ export default {
862864
this.selectedVerifier = GOOGLE
863865
} else if (/.eth$/.test(toAddress) || /.xyz$/.test(toAddress) || /.kred$/i.test(toAddress)) {
864866
this.selectedVerifier = ENS
867+
} else if (/.rsk$/.test(toAddress)) {
868+
this.selectedVerifier = RNS
865869
} else if (/.crypto$/.test(toAddress)) {
866870
this.selectedVerifier = UNSTOPPABLE_DOMAINS
867871
} else if (new RegExp(`${this.bitTail}$`).test(toAddress)) {
@@ -971,6 +975,9 @@ export default {
971975
ensRule() {
972976
return this.selectedVerifier === ENS && this.ensError ? this.ensError : true
973977
},
978+
rnsRule() {
979+
return this.selectedVerifier === RNS && this.rnsError ? this.rnsError : true
980+
},
974981
bitRule() {
975982
return this.selectedVerifier === BIT && this.bitError ? this.bitError : true
976983
},
@@ -1085,6 +1092,7 @@ export default {
10851092
}
10861093
}
10871094
this.ensError = ''
1095+
this.rnsError = ''
10881096
this.unstoppableDomainsError = ''
10891097
this.torusError = ''
10901098
@@ -1233,6 +1241,17 @@ export default {
12331241
this.ensError = 'walletSettings.invalidEns'
12341242
this.$refs.form.validate()
12351243
}
1244+
} else if (this.selectedVerifier === RNS) {
1245+
try {
1246+
const res = await this.getRnsAddress({ domain: this.toAddress, coinType: this.networkType.ticker })
1247+
log.info(res)
1248+
toAddress = res.toLowerCase()
1249+
this.rnsError = ''
1250+
} catch (error) {
1251+
log.error(error)
1252+
this.rnsError = 'walletSettings.invalidRns'
1253+
}
1254+
this.$refs.form.validate()
12361255
} else if (this.selectedVerifier === UNSTOPPABLE_DOMAINS) {
12371256
try {
12381257
const res = await this.getUnstoppableDomains(this.toAddress)

src/controllers/PreferencesController.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { hashPersonalMessage } from '@ethereumjs/util'
22
import { ObservableStore } from '@metamask/obs-store'
33
import { SafeEventEmitter } from '@toruslabs/openlogin-jrpc'
44
import deepmerge from 'deepmerge'
5+
import { ethers } from 'ethers'
56
import { cloneDeep } from 'lodash'
67
import log from 'loglevel'
78
import Web3 from 'web3'
@@ -16,7 +17,9 @@ import {
1617
ACTIVITY_ACTION_TOPUP,
1718
ERROR_TIME,
1819
ETHERSCAN_SUPPORTED_NETWORKS,
20+
RSK_MAINNET,
1921
SUCCESS_TIME,
22+
SUPPORTED_NETWORK_TYPES,
2023
THEME_LIGHT_BLUE_NAME,
2124
} from '../utils/enums'
2225
import { notifyUser } from '../utils/notifications'
@@ -68,6 +71,8 @@ class PreferencesController extends SafeEventEmitter {
6871
this.web3 = new Web3(provider)
6972
this.api = new ApiHelpers(options.storeDispatch)
7073
this.signMessage = signMessage
74+
this.rskProvider = null
75+
this.rnsRegistryContract = null
7176

7277
this.interval = options.interval || DEFAULT_INTERVAL
7378
this.store = new ObservableStore({ selectedAddress: '' }) // Account specific object
@@ -826,6 +831,95 @@ class PreferencesController extends SafeEventEmitter {
826831
return this.api.get(url.href, this.headers(), { useAPIKey: true })
827832
}
828833

834+
// This approach considers resolution for tokens
835+
getRnsChainIdFromPluginId = (pluginId) => {
836+
switch (pluginId) {
837+
case 'RBTC':
838+
return 137
839+
case 'ETH':
840+
return 60
841+
case 'ETHC':
842+
return 61
843+
case 'BTC':
844+
return 0
845+
case 'LTC':
846+
return 2
847+
case 'dash':
848+
return 5
849+
case 'XRP':
850+
return 144
851+
case 'BCH':
852+
return 145
853+
case 'BNB':
854+
return 714
855+
case 'XLM':
856+
return 148
857+
case 'MATIC':
858+
return 966
859+
case 'AVAX':
860+
return 9000
861+
case 'GXC':
862+
return 2303
863+
case 'OKT':
864+
return 996
865+
case 'DAI':
866+
return 700
867+
default:
868+
return -1
869+
}
870+
}
871+
872+
async getRnsAddress({ domain, coinType }) {
873+
try {
874+
const pluginId = this.getRnsChainIdFromPluginId(coinType)
875+
if (pluginId === -1) {
876+
return null
877+
}
878+
if (!this.rskProvider) {
879+
const rskRpcServerUrl = SUPPORTED_NETWORK_TYPES[RSK_MAINNET].rpcUrl
880+
this.rskProvider = new ethers.providers.JsonRpcProvider(rskRpcServerUrl)
881+
}
882+
if (!this.rnsRegistryContract) {
883+
// REF: https://developers.rsk.co/rif/rns/architecture/registry/
884+
const RNS_REGISTRY_ADDRESS = '0xcb868aeabd31e2b66f74e9a55cf064abb31a4ad5' // hardcoded RNS registry address
885+
this.rnsRegistryContract = new ethers.Contract(
886+
RNS_REGISTRY_ADDRESS,
887+
['function resolver(bytes32 node) public view returns (address)'],
888+
this.rskProvider
889+
)
890+
}
891+
const nameHash = ethers.utils.namehash(domain)
892+
const resolverAddress = await this.rnsRegistryContract.resolver(nameHash)
893+
if (resolverAddress === ethers.constants.AddressZero) {
894+
return null
895+
}
896+
// Check if current selected currency is on RSK chain 137 if not check for multichain address
897+
let address = null
898+
if (pluginId === 137) {
899+
const addrResolverContract = new ethers.Contract(
900+
resolverAddress,
901+
['function addr(bytes32 node) public view returns (address)'],
902+
this.rskProvider
903+
)
904+
address = await addrResolverContract.addr(nameHash)
905+
} else {
906+
const multichainAddrResolverContract = new ethers.Contract(
907+
resolverAddress,
908+
['function addr(bytes32 node, uint coinType) external view returns(bytes memory)'],
909+
this.rskProvider
910+
)
911+
address = await multichainAddrResolverContract.addr(nameHash, pluginId)
912+
}
913+
if (address === undefined || address === null) {
914+
return null
915+
}
916+
return address.toLowerCase()
917+
} catch (error) {
918+
log.error(error)
919+
return null
920+
}
921+
}
922+
829923
async getTorusLookupAddress({ verifier, verifierId, walletVerifier, network }) {
830924
const url = new URL(`${config.api}/lookup/torus`)
831925
url.searchParams.append('verifier', verifier)

src/store/preferencesActions.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ export default {
5353
getEnsOrUnstoppableAddress(_, payload) {
5454
return prefsController.getEnsOrUnstoppableAddress(payload)
5555
},
56+
getRnsAddress(_, payload) {
57+
return prefsController.getRnsAddress(payload)
58+
},
5659
getTorusLookupAddress(_, payload) {
5760
return prefsController.getTorusLookupAddress(payload)
5861
},

src/utils/enums.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ export const EMAIL_PASSWORDLESS_LOGIN_PROVIDER = 'email_passwordless'
560560
export const LINKED_VERIFIER_SUBIDENTIFIER = process.env.VUE_APP_LINKED_VERIFIER_SUBIDENTIFIER
561561

562562
export const ENS = 'ENS'
563+
export const RNS = 'RNS'
563564
export const UNSTOPPABLE_DOMAINS = 'Unstoppable_Domains'
564565
export const ETH_LABEL = 'walletSettings.ethAddress'
565566
export const GOOGLE_LABEL = 'walletSettings.googleId'
@@ -568,6 +569,7 @@ export const REDDIT_LABEL = 'walletSettings.redditId'
568569
export const DISCORD_LABEL = 'walletSettings.discordId'
569570
export const TWITCH_LABEL = 'walletSettings.twitchId'
570571
export const ENS_LABEL = 'walletSettings.ensId'
572+
export const RNS_LABEL = 'walletSettings.rnsId'
571573
export const UNSTOPPABLE_DOMAINS_LABEL = 'walletSettings.unstoppableDomainsId'
572574
export const TWITTER_LABEL = 'walletSettings.twitterId'
573575
export const GITHUB_LABEL = 'walletSettings.githubId'
@@ -621,6 +623,10 @@ export const ALLOWED_VERIFIERS = [
621623
name: ENS_LABEL,
622624
value: ENS,
623625
},
626+
{
627+
name: RNS_LABEL,
628+
value: RNS,
629+
},
624630
{
625631
name: TWITTER_LABEL,
626632
value: TWITTER,

0 commit comments

Comments
 (0)