Skip to content

Commit f012109

Browse files
authored
Merge pull request #704 from enkryptcom/feat/space-id-support
Feat: space id support
2 parents 61d94ef + be3e905 commit f012109

15 files changed

Lines changed: 558 additions & 1414 deletions

File tree

packages/extension/src/libs/name-resolver/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ class GenericNameResolver {
1414
});
1515
}
1616

17-
async resolveName(name: string, coins: CoinType[]): Promise<string | null> {
17+
async resolveName(name: string, coins: CoinType[], providerChain?: string): Promise<string | null> {
1818
let response: string | null = null;
1919
for (const coin of coins) {
2020
response = await this.nameResolver
21-
.resolveAddress(name, coin)
21+
.resolveAddress(name, coin, providerChain)
2222
.catch(() => null);
2323
if (response) return response;
2424
}

packages/extension/src/providers/common/ui/send-transaction/send-contacts-list.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@ const isChecked = (address: string) => {
125125
props.network.displayAddress(address)
126126
);
127127
} catch (err) {
128-
console.error('Error checking if address is checked', err);
128+
console.error(
129+
'Error checking if address is checked, probably name resolver',
130+
);
129131
return false;
130132
}
131133
};

packages/extension/src/providers/ethereum/ui/send-transaction/index.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,11 @@ const inputAddressFrom = (text: string) => {
678678
const inputAddressTo = async (text: string) => {
679679
const debounceResolve = debounce(() => {
680680
nameResolver
681-
.resolveName(text, [props.network.name as CoinType, 'ETH'])
681+
.resolveName(
682+
text,
683+
[props.network.name as CoinType, 'ETH'],
684+
props.network.provider as string,
685+
)
682686
.then(resolved => {
683687
if (resolved) {
684688
addressTo.value = resolved;

packages/extension/src/providers/solana/ui/send-transaction/index.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,11 @@ const inputAddressFrom = (text: string) => {
704704
const inputAddressTo = async (text: string) => {
705705
const debounceResolve = debounce(() => {
706706
nameResolver
707-
.resolveName(text, [props.network.name as CoinType, 'ETH'])
707+
.resolveName(
708+
text,
709+
[props.network.name as CoinType, 'ETH'],
710+
props.network.provider as string,
711+
)
708712
.then(resolved => {
709713
if (resolved) {
710714
addressTo.value = resolved;

packages/extension/src/ui/action/views/swap/index.vue

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,11 @@ const setMax = () => {
404404
const inputAddress = (text: string) => {
405405
const debounceResolve = debounce(() => {
406406
nameResolver
407-
.resolveName(text, [props.network.name as CoinType, 'ETH'])
407+
.resolveName(
408+
text,
409+
[props.network.name as CoinType, 'ETH'],
410+
props.network.provider as string,
411+
)
408412
.then(resolved => {
409413
if (resolved) {
410414
inputAddress(resolved);
@@ -773,7 +777,7 @@ const isDisabled = computed(() => {
773777
return true;
774778
if (
775779
BigNumber(fromAmount.value).gt(
776-
fromBase(fromToken.value!.balance.toString(), fromToken.value.decimals),
780+
fromBase(fromToken.value!.balance!.toString(), fromToken.value!.decimals),
777781
)
778782
)
779783
return true;

packages/hw-wallets/src/trezor/ethereum/configs.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ const supportedPaths = {
2121
[NetworkNames.Arbitrum]: DEFAULT_PATHS,
2222
[NetworkNames.Gnosis]: DEFAULT_PATHS,
2323
[NetworkNames.Fantom]: DEFAULT_PATHS,
24-
[NetworkNames.Klaytn]: DEFAULT_PATHS,
24+
[NetworkNames.Kaia]: DEFAULT_PATHS,
2525
[NetworkNames.Base]: DEFAULT_PATHS,
2626
[NetworkNames.Celo]: DEFAULT_PATHS,
27-
[NetworkNames.Syscoin]: DEFAULT_PATHS,
27+
[NetworkNames.SyscoinNEVM]: DEFAULT_PATHS,
2828
[NetworkNames.Telos]: DEFAULT_PATHS,
2929
[NetworkNames.Blast]: DEFAULT_PATHS,
3030
};

packages/name-resolution/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"tsup": "^8.5.0",
3838
"typescript": "^5.8.3",
3939
"typescript-eslint": "8.33.0",
40+
"viem": "^2.29.2",
4041
"vitest": "^3.1.4"
4142
},
4243
"repository": {
@@ -47,9 +48,10 @@
4748
"author": "kvhnuke",
4849
"license": "MIT",
4950
"dependencies": {
51+
"@bonfida/spl-name-service": "3.0.10",
5052
"@ensdomains/address-encoder": "^1.1.2",
51-
"@siddomains/sidjs": "0.1.29",
5253
"@unstoppabledomains/resolution": "^9.3.3",
54+
"@web3-name-sdk/core": "0.4.1",
5355
"ethers": "^5.8.0"
5456
}
5557
}

packages/name-resolution/src/index.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,22 @@ class NameResolver {
4141
if (name !== null) return name;
4242
}
4343
return null;
44-
})
44+
}),
4545
);
4646
}
4747

4848
public async resolveAddress(
4949
name: string,
50-
coin: CoinType = "ETH"
50+
coin: CoinType = "ETH",
51+
paymentIdChain?: string,
5152
): Promise<string | null> {
5253
return this.initDone.then(() => {
53-
if (this.sid.isSupportedName(name)) return this.sid.resolveAddress(name);
5454
if (this.rns.isSupportedName(name))
5555
return this.rns.resolveAddress(name, coin);
5656
if (this.ud.isSupportedName(name))
5757
return this.ud.resolveAddress(name, coin);
58+
if (this.sid.isSupportedName(name))
59+
return this.sid.resolveAddress(name, paymentIdChain);
5860
if (this.ens.isSupportedName(name))
5961
return this.ens.resolveAddress(name, coin);
6062

packages/name-resolution/src/sid/index.ts

Lines changed: 94 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,119 @@
1-
import { ethers } from "ethers";
2-
import SID, { getSidAddress } from "@siddomains/sidjs";
1+
import { createWeb3Name } from "@web3-name-sdk/core";
32
import { BaseResolver } from "../types";
3+
import {
4+
PAYMENT_ID_CHAINS_MAP,
5+
PaymentIdChain,
6+
SIDOptions,
7+
TIMEOUT_PRESETS,
8+
} from "./types";
9+
import { createSolName } from "@web3-name-sdk/core/solName";
10+
import { createPaymentIdName } from "@web3-name-sdk/core/paymentIdName";
11+
import { isValidPaymentId } from "./utils";
412
import { getTLD } from "../utils";
5-
import { SIDOptions } from "./types";
13+
// demo: https://sdk-demo-git-main-space-id.vercel.app/
14+
15+
const evm_tlds = [
16+
"bnb",
17+
"arb",
18+
"wod",
19+
"mph",
20+
"g",
21+
"btc",
22+
"burger",
23+
"alien",
24+
"zkf",
25+
"merlin",
26+
"taiko",
27+
"tomo",
28+
"gno",
29+
"floki",
30+
"ll",
31+
"ip",
32+
"mode",
33+
"mint",
34+
"manta",
35+
"cake",
36+
"zeta",
37+
"ail",
38+
"duck",
39+
];
640

741
class SIDResolver implements BaseResolver {
842
name: string;
9-
10-
supportedTLDs = ["bnb", "arb"];
11-
43+
timeout: number;
44+
// The supported tlds for sid in evm and solana
45+
supportedTLDs = ["sol", ...evm_tlds];
1246
rpc: SIDOptions;
47+
solanaNameResolver: ReturnType<typeof createSolName>;
48+
paymentIdNameResolver: ReturnType<typeof createPaymentIdName>;
49+
web3NameResolver: ReturnType<typeof createWeb3Name>;
1350

1451
constructor(options: SIDOptions) {
1552
this.rpc = options;
53+
this.timeout = options.timeout || TIMEOUT_PRESETS.normal;
1654
this.name = "spaceid";
55+
this.solanaNameResolver = createSolName({ timeout: this.timeout });
56+
this.paymentIdNameResolver = createPaymentIdName();
57+
this.web3NameResolver = createWeb3Name();
1758
}
1859

19-
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-empty-function
2060
public async init(): Promise<void> {}
2161

22-
public async resolveReverseName(address: string): Promise<string | null> {
23-
const bnbProvider = new ethers.providers.JsonRpcProvider({
24-
url: this.rpc.node.bnb,
25-
headers: {
26-
"user-agent": "enkrypt/name-resolver",
27-
},
28-
});
29-
const sidBNB = new SID({
30-
provider: bnbProvider,
31-
sidAddress: getSidAddress("56"),
32-
});
33-
const nameBnb = await sidBNB.getName(address);
34-
if (nameBnb) return nameBnb.name;
35-
const arbProvider = new ethers.providers.JsonRpcProvider({
36-
url: this.rpc.node.arb,
37-
headers: {
38-
"user-agent": "enkrypt/name-resolver",
39-
},
40-
});
41-
const sidArb = new SID({
42-
provider: arbProvider,
43-
sidAddress: getSidAddress("42161"),
62+
// The PaymentId only supports getAddress resolution.
63+
public async handlePaymentIdGetAddress(
64+
name: string,
65+
paymentIdChain?: string,
66+
): Promise<string | null> {
67+
return await this.paymentIdNameResolver.getAddress({
68+
name,
69+
chainId:
70+
PAYMENT_ID_CHAINS_MAP[paymentIdChain?.toLowerCase()] ||
71+
PaymentIdChain.Ethereum,
4472
});
45-
const nameArb = await sidArb.getName(address);
46-
if (nameArb) return nameArb.name;
47-
return null;
4873
}
4974

50-
public async resolveAddress(name: string): Promise<string | null> {
51-
const provider = new ethers.providers.JsonRpcProvider({
52-
url: this.rpc.node[getTLD(name)],
53-
headers: {
54-
"user-agent": "enkrypt/name-resolver",
55-
},
56-
});
57-
const sid = new SID({
58-
provider,
59-
sidAddress: getSidAddress(getTLD(name) === "bnb" ? "56" : "42161"),
60-
});
61-
const address = await sid.name(name).getAddress();
62-
if (parseInt(address, 16) === 0) {
75+
public async resolveReverseName(address: string): Promise<string | null> {
76+
try {
77+
let name = await this.web3NameResolver.getDomainName({
78+
timeout: this.timeout,
79+
address,
80+
});
81+
if (!name) {
82+
name = await this.solanaNameResolver.getDomainName({
83+
address,
84+
});
85+
}
86+
return name;
87+
} catch (error) {
6388
return null;
6489
}
65-
return address;
6690
}
6791

92+
public async resolveAddress(
93+
name: string,
94+
paymentIdChain?: string,
95+
): Promise<string | null> {
96+
if (isValidPaymentId(name)) {
97+
return this.handlePaymentIdGetAddress(name, paymentIdChain);
98+
}
99+
100+
const tld = getTLD(name);
101+
switch (tld) {
102+
case "sol":
103+
const solAddress = await this.solanaNameResolver.getAddress({
104+
name,
105+
});
106+
return solAddress;
107+
default:
108+
const address = await this.web3NameResolver.getAddress(name, {
109+
timeout: this.timeout,
110+
});
111+
return parseInt(address, 16) === 0 ? null : address;
112+
}
113+
}
68114
public isSupportedName(name: string): boolean {
69-
return this.supportedTLDs.includes(getTLD(name));
115+
// Compatible with TLD and paymentId
116+
return this.supportedTLDs.includes(getTLD(name)) || isValidPaymentId(name);
70117
}
71118
}
72119

packages/name-resolution/src/sid/types.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,36 @@ export interface SIDOptions {
33
bnb: string;
44
arb: string;
55
};
6+
timeout?: number
67
}
8+
9+
export type Protocol = "EVM" | "Solana" | "PaymentID";
10+
export enum PaymentIdChain {
11+
Bitcoin = 0,
12+
Ethereum = 1,
13+
Solana = 2,
14+
Tron = 3,
15+
Aptos = 4,
16+
Sui = 5,
17+
}
18+
export const PAYMENT_ID_CHAINS_MAP = {
19+
"bitcoin": 0,
20+
"ethereum": 1,
21+
"solana": 2,
22+
"tron": 3,
23+
"aptos": 4,
24+
"sui": 5,
25+
};
26+
export type Method =
27+
| "getAddress"
28+
| "getDomainName"
29+
| "batchGetDomainNameByChainId"
30+
| "getMetadata"
31+
| "getContentHash";
32+
33+
34+
export const TIMEOUT_PRESETS = {
35+
veryShort: 100, // Intentionally short to test timeout
36+
normal: 5000, // Normal timeout (5s)
37+
long: 15000, // Long timeout (15s)
38+
};

0 commit comments

Comments
 (0)