Skip to content

Commit 4fee66e

Browse files
Add Unstoppable Domains Reverse Resolution (#1410)
* added UD resolution dependency pinned to the same version uauth uses to avoid increasing package size * renames shortenEns to domain agnostic * added uns reverse resolution * removed excess console log * Bump core version and add alpha tag, but react and vuew versions, prettier and err checking * Fix demo Co-authored-by: Adam Carpenter <[email protected]>
1 parent e9ee7d0 commit 4fee66e

File tree

16 files changed

+246
-49
lines changed

16 files changed

+246
-49
lines changed

examples/with-vuejs-v2/src/components/HelloWorld.vue

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<div class="avatar" />
88
<div class="details">
99
<div v-if="ens">{{ ens.name }}</div>
10+
<div v-if="uns">{{ uns.name }}</div>
1011
<div v-if="address">{{ address }}</div>
1112

1213
<span>Connected Wallet: {{ connectedWallet.label }}</span>
@@ -83,6 +84,14 @@ export default {
8384
return trunc(this.connectedWallet.accounts[0].ens);
8485
}
8586
},
87+
uns: function () {
88+
if (
89+
this.connectedWallet.accounts &&
90+
this.connectedWallet.accounts[0].uns?.name
91+
) {
92+
return trunc(this.connectedWallet.accounts[0].uns);
93+
}
94+
},
8695
},
8796
};
8897
</script>

packages/core/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,9 @@ type Account = {
510510
contentHash?: string
511511
getText?: (key: string) => Promise<string | undefined>
512512
}
513+
uns: {
514+
name?: string
515+
}
513516
balance: Record<TokenSymbol, string>
514517
}
515518

packages/core/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@web3-onboard/core",
3-
"version": "2.12.1",
3+
"version": "2.13.0-alpha.1",
44
"description": "Web3-Onboard makes it simple to connect Ethereum hardware and software wallets to your dapp. Features standardized spec compliant web3 providers for all supported wallets, framework agnostic modern javascript UI with code splitting, CSS customization, multi-chain and multi-account support, reactive wallet state subscriptions and real-time transaction state change notifications.",
55
"keywords": [
66
"Ethereum",
@@ -60,8 +60,9 @@
6060
"license": "MIT",
6161
"devDependencies": {
6262
"@rollup-extras/plugin-copy": "~1.2.2",
63+
"@rollup/plugin-commonjs": "^23.0.4",
6364
"@rollup/plugin-json": "^4.1.0",
64-
"@rollup/plugin-node-resolve": "^11.0.0",
65+
"@rollup/plugin-node-resolve": "^13.0.6",
6566
"@rollup/plugin-replace": "^3.0.0",
6667
"@rollup/plugin-typescript": "^8.0.0",
6768
"@tsconfig/svelte": "^2.0.0",
@@ -84,6 +85,7 @@
8485
"typescript": "^4.5.5"
8586
},
8687
"dependencies": {
88+
"@unstoppabledomains/resolution": "^8.0",
8789
"@web3-onboard/common": "^2.2.3",
8890
"bignumber.js": "^9.0.0",
8991
"bnc-sdk": "^4.6.2",

packages/core/rollup.config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import json from '@rollup/plugin-json'
55
import sveltePreprocess from 'svelte-preprocess'
66
import typescript from '@rollup/plugin-typescript'
77
import copy from '@rollup-extras/plugin-copy'
8+
import commonjs from '@rollup/plugin-commonjs'
89

910
const production = !process.env.ROLLUP_WATCH
1011

@@ -35,6 +36,9 @@ export default {
3536
sourceMap: !production,
3637
inlineSources: !production
3738
}),
39+
commonjs({
40+
include: /node_modules/
41+
}),
3842
copy({
3943
src: 'src/i18n/en.json',
4044
dest: 'i18n'

packages/core/src/provider.ts

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { fromEventPattern, Observable } from 'rxjs'
22
import { filter, takeUntil, take, share, switchMap } from 'rxjs/operators'
33
import partition from 'lodash.partition'
4-
import { providers } from 'ethers'
4+
import { providers, utils } from 'ethers'
55
import { weiToEth } from '@web3-onboard/common'
66
import { disconnectWallet$ } from './streams.js'
77
import { updateAccount, updateWallet } from './store/actions.js'
88
import { validEnsChain } from './utils.js'
99
import disconnect from './disconnect.js'
1010
import { state } from './store/index.js'
1111
import { getBNMulitChainSdk } from './services.js'
12+
import { Resolution } from '@unstoppabledomains/resolution'
1213

1314
import type {
1415
ChainId,
@@ -26,6 +27,7 @@ import type {
2627
Address,
2728
Balances,
2829
Ens,
30+
Uns,
2931
WalletPermission,
3032
WalletState
3133
} from './types.js'
@@ -146,10 +148,15 @@ export function trackWallet(
146148
account => account.address === address
147149
)
148150

149-
// update accounts without ens and balance first
151+
// update accounts without ens/uns and balance first
150152
updateWallet(label, {
151153
accounts: [
152-
existingAccount || { address: address, ens: null, balance: null },
154+
existingAccount || {
155+
address: address,
156+
ens: null,
157+
uns: null,
158+
balance: null
159+
},
153160
...restAccounts
154161
]
155162
})
@@ -176,7 +183,7 @@ export function trackWallet(
176183
}
177184
})
178185

179-
// also when accounts change, update Balance and ENS
186+
// also when accounts change, update Balance and ENS/UNS
180187
accountsChanged$
181188
.pipe(
182189
switchMap(async ([address]) => {
@@ -205,13 +212,23 @@ export function trackWallet(
205212
? getEns(address, chain)
206213
: Promise.resolve(null)
207214

208-
return Promise.all([Promise.resolve(address), balanceProm, ensProm])
215+
const unsProm =
216+
account && account.uns
217+
? Promise.resolve(account.uns)
218+
: getUns(address, chain)
219+
220+
return Promise.all([
221+
Promise.resolve(address),
222+
balanceProm,
223+
ensProm,
224+
unsProm
225+
])
209226
})
210227
)
211228
.subscribe(res => {
212229
if (!res) return
213-
const [address, balance, ens] = res
214-
updateAccount(label, address, { balance, ens })
230+
const [address, balance, ens, uns] = res
231+
updateAccount(label, address, { balance, ens, uns })
215232
})
216233

217234
const chainChanged$ = listenChainChanged({ provider, disconnected$ }).pipe(
@@ -264,6 +281,7 @@ export function trackWallet(
264281
({
265282
address,
266283
ens: null,
284+
uns: null,
267285
balance: null
268286
} as Account)
269287
)
@@ -274,7 +292,7 @@ export function trackWallet(
274292
})
275293
})
276294

277-
// when chain changes get ens and balance for each account for wallet
295+
// when chain changes get ens/uns and balance for each account for wallet
278296
chainChanged$
279297
.pipe(
280298
switchMap(async chainId => {
@@ -293,12 +311,21 @@ export function trackWallet(
293311
? getEns(address, chain)
294312
: Promise.resolve(null)
295313

296-
const [balance, ens] = await Promise.all([balanceProm, ensProm])
314+
const unsProm = validEnsChain(chainId)
315+
? getUns(address, chain)
316+
: Promise.resolve(null)
317+
318+
const [balance, ens, uns] = await Promise.all([
319+
balanceProm,
320+
ensProm,
321+
unsProm
322+
])
297323

298324
return {
299325
address,
300326
balance,
301-
ens
327+
ens,
328+
uns
302329
}
303330
})
304331
)
@@ -353,6 +380,33 @@ export async function getEns(
353380
}
354381
}
355382

383+
export async function getUns(
384+
address: Address,
385+
chain: Chain
386+
): Promise<Uns | null> {
387+
// check if address is valid ETH address before attempting to resolve
388+
// chain we don't recognize and don't have a rpcUrl for requests
389+
if (!utils.isAddress(address) || !chain) return null
390+
391+
const resolutionInstance = new Resolution()
392+
393+
try {
394+
const name = await resolutionInstance.reverse(address)
395+
let uns = null
396+
397+
if (name) {
398+
uns = {
399+
name
400+
}
401+
}
402+
403+
return uns
404+
} catch (error) {
405+
console.error(error)
406+
return null
407+
}
408+
}
409+
356410
export async function getBalance(
357411
address: string,
358412
chain: Chain

packages/core/src/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export interface WalletState {
105105
export type Account = {
106106
address: Address
107107
ens: Ens | null
108+
uns: Uns | null
108109
balance: Balances | null
109110
}
110111

@@ -117,6 +118,10 @@ export interface Ens {
117118
getText: (key: string) => Promise<string | undefined>
118119
}
119120

121+
export interface Uns {
122+
name: string
123+
}
124+
120125
export type Avatar = {
121126
url: string
122127
linkage: Array<{ type: string; content: string }>

packages/core/src/utils.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,10 @@ export function shortenAddress(add: string): string {
8181
return `${add.slice(0, 6)}...${add.slice(-4)}`
8282
}
8383

84-
export function shortenEns(ens: string): string {
85-
return ens.length > 11 ? `${ens.slice(0, 4)}...${ens.slice(-6)}` : ens
84+
export function shortenDomain(domain: string): string {
85+
return domain.length > 11
86+
? `${domain.slice(0, 4)}...${domain.slice(-6)}`
87+
: domain
8688
}
8789

8890
export async function copyWalletAddress(text: string): Promise<void> {

packages/core/src/validation.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ const ens = Joi.any().allow(
4646
null
4747
)
4848

49+
const uns = Joi.any().allow(
50+
Joi.object({
51+
name: Joi.string().required()
52+
}),
53+
null
54+
)
55+
4956
const balance = Joi.any().allow(
5057
Joi.object({
5158
eth: Joi.number()
@@ -56,6 +63,7 @@ const balance = Joi.any().allow(
5663
const account = Joi.object({
5764
address: Joi.string().required(),
5865
ens,
66+
uns,
5967
balance
6068
})
6169

packages/core/src/views/account-center/Minimized.svelte

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import {
55
getDefaultChainStyles,
66
shortenAddress,
7-
shortenEns,
7+
shortenDomain,
88
unrecognizedChainStyle
99
} from '../../utils.js'
1010
import { updateAccountCenter } from '../../store/actions.js'
@@ -25,7 +25,10 @@
2525
$: [firstAccount] = primaryWallet ? primaryWallet.accounts : []
2626
2727
$: ensName =
28-
firstAccount && firstAccount.ens && shortenEns(firstAccount.ens.name)
28+
firstAccount && firstAccount.ens && shortenDomain(firstAccount.ens.name)
29+
30+
$: unsName =
31+
firstAccount && firstAccount.uns && shortenDomain(firstAccount.uns.name)
2932
3033
$: shortenedFirstAddress = firstAccount
3134
? shortenAddress(firstAccount.address)
@@ -179,7 +182,11 @@
179182
<!-- address and balance -->
180183
<div class="flex flex-column" style="height: 40px;">
181184
<div class="address">
182-
{ensName ? shortenEns(ensName) : shortenedFirstAddress}
185+
{ensName
186+
? shortenDomain(ensName)
187+
: unsName
188+
? shortenDomain(unsName)
189+
: shortenedFirstAddress}
183190
</div>
184191
{#if firstAddressBalance}
185192
<div in:fade class="balance">

packages/core/src/views/account-center/WalletRow.svelte

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
import { fade } from 'svelte/transition'
44
import { ProviderRpcErrorCode } from '@web3-onboard/common'
55
import type { WalletState } from '../../types.js'
6-
import { shortenAddress, shortenEns, copyWalletAddress } from '../../utils.js'
6+
import {
7+
shortenAddress,
8+
shortenDomain,
9+
copyWalletAddress
10+
} from '../../utils.js'
711
import en from '../../i18n/en.json'
812
import SuccessStatusIcon from '../shared/SuccessStatusIcon.svelte'
913
import WalletAppBadge from '../shared/WalletAppBadge.svelte'
@@ -87,7 +91,7 @@
8791
);
8892
}
8993
90-
.address-ens {
94+
.address-domain {
9195
margin-left: 0.5rem;
9296
font-weight: 700;
9397
color: var(
@@ -156,7 +160,7 @@
156160
}
157161
</style>
158162

159-
{#each wallet.accounts as { address, ens, balance }, i}
163+
{#each wallet.accounts as { address, ens, uns, balance }, i}
160164
<div class="relative">
161165
<div
162166
on:click={() => setPrimaryWallet(wallet, address)}
@@ -188,9 +192,13 @@
188192
{/if}
189193
</div>
190194

191-
<!-- ADDRESS / ENS -->
192-
<span class="address-ens"
193-
>{ens ? shortenEns(ens.name) : shortenAddress(address)}</span
195+
<!-- ADDRESS / DOMAIN -->
196+
<span class="address-domain"
197+
>{ens
198+
? shortenDomain(ens.name)
199+
: uns
200+
? shortenDomain(uns.name)
201+
: shortenAddress(address)}</span
194202
>
195203
</div>
196204

@@ -249,9 +257,11 @@
249257
</li>
250258
<li
251259
on:click|stopPropagation={() => {
252-
copyWalletAddress(ens ? ens.name : address).then(() => {
253-
changeText()
254-
})
260+
copyWalletAddress(ens ? ens.name : uns ? uns.name : address).then(
261+
() => {
262+
changeText()
263+
}
264+
)
255265
}}
256266
>
257267
{en.accountCenter.copyAddress}

0 commit comments

Comments
 (0)