From ac2f21f002d16732dfd850ee5aaf897694cfebf3 Mon Sep 17 00:00:00 2001 From: fm2055 <48504961+fm2055@users.noreply.github.com> Date: Wed, 3 Jul 2024 03:01:49 +0000 Subject: [PATCH] feat: added SNS name resolver --- package.json | 3 + .../extension/src/libs/name-resolver/index.ts | 3 + packages/name-resolution/src/index.ts | 10 ++- packages/name-resolution/src/sns/index.ts | 66 +++++++++++++++++++ packages/name-resolution/src/sns/types.ts | 11 ++++ packages/name-resolution/src/types.ts | 6 +- .../name-resolution/tests/resolver.test.ts | 6 ++ packages/name-resolution/tests/sns.test.ts | 26 ++++++++ yarn.lock | 12 ++++ 9 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 packages/name-resolution/src/sns/index.ts create mode 100644 packages/name-resolution/src/sns/types.ts create mode 100644 packages/name-resolution/tests/sns.test.ts diff --git a/package.json b/package.json index 93c3c2887..a9de32fe2 100644 --- a/package.json +++ b/package.json @@ -41,5 +41,8 @@ }, "resolutions": { "@ledgerhq/compressjs": "https://registry.yarnpkg.com/@favware/skip-dependency/-/skip-dependency-1.2.1.tgz" + }, + "dependencies": { + "@bonfida/sns-warp-evm": "^0.0.4" } } diff --git a/packages/extension/src/libs/name-resolver/index.ts b/packages/extension/src/libs/name-resolver/index.ts index 9afcf9498..84083538a 100644 --- a/packages/extension/src/libs/name-resolver/index.ts +++ b/packages/extension/src/libs/name-resolver/index.ts @@ -11,6 +11,9 @@ class GenericNameResolver { arb: "https://nodes.mewapi.io/rpc/arb", }, }, + sns: { + network: "mainnet", + }, }); } diff --git a/packages/name-resolution/src/index.ts b/packages/name-resolution/src/index.ts index 936ab6325..b2b34220f 100644 --- a/packages/name-resolution/src/index.ts +++ b/packages/name-resolution/src/index.ts @@ -1,4 +1,5 @@ import ENSResolver from "./ens"; +import SNSResolver from "./sns"; import { CoinType, NameResolverOptions } from "./types"; import UDResolver from "./ud"; import RNSResolver from "./rns"; @@ -7,6 +8,8 @@ import SIDResolver from "./sid"; class NameResolver { ens: ENSResolver; + sns: SNSResolver; + rns: RNSResolver; ud: UDResolver; @@ -17,11 +20,13 @@ class NameResolver { constructor(options: NameResolverOptions) { this.ens = new ENSResolver(options.ens); + this.sns = new SNSResolver(options.sns); this.rns = new RNSResolver(); this.ud = new UDResolver(); this.sid = new SIDResolver(options.sid); this.initDone = Promise.all([ this.ens.init(), + this.sns.init(), this.rns.init(), this.ud.init(), this.sid.init(), @@ -32,6 +37,7 @@ class NameResolver { return this.initDone.then(() => Promise.all([ this.ens.resolveReverseName(address), + this.sns.resolveReverseName(address), this.sid.resolveReverseName(address), this.rns.resolveReverseName(address), this.ud.resolveReverseName(address), @@ -50,6 +56,8 @@ class NameResolver { coin: CoinType = "ETH" ): Promise { return this.initDone.then(() => { + if (this.sns.isSupportedName(name)) + return this.sns.resolveAddress(name, coin); if (this.sid.isSupportedName(name)) return this.sid.resolveAddress(name); if (this.rns.isSupportedName(name)) return this.rns.resolveAddress(name, coin); @@ -62,5 +70,5 @@ class NameResolver { }); } } -export { ENSResolver, UDResolver, CoinType }; +export { ENSResolver, SNSResolver, UDResolver, CoinType }; export default NameResolver; diff --git a/packages/name-resolution/src/sns/index.ts b/packages/name-resolution/src/sns/index.ts new file mode 100644 index 000000000..f494313c8 --- /dev/null +++ b/packages/name-resolution/src/sns/index.ts @@ -0,0 +1,66 @@ +import { SupportedChains, SNS } from "@bonfida/sns-warp-evm"; +import { BaseResolver, CoinType } from "../types"; +import { getTLD } from "../utils"; +import { ChainMap, Resolvers, SNSOptions } from "./types"; + +const MAINNET_CHAIN_MAP: ChainMap = { + "BASE": SupportedChains.BASE, + "BNB": SupportedChains.BNBMainnet +} + +const TESTNET_CHAIN_MAP: ChainMap = { + "BASE": SupportedChains.BASESepolia, + "BNB": SupportedChains.BNBTestNet +} + +class SNSResolver implements BaseResolver { + options: SNSOptions; + + name: string; + + chainMap: ChainMap; + + chainResolvers: Resolvers; + + constructor(options: SNSOptions) { + this.options = options; + this.name = "sns"; + this.chainMap = options.network === "testnet" + ? TESTNET_CHAIN_MAP + : MAINNET_CHAIN_MAP; + this.chainResolvers = Object.fromEntries( + Object.entries(this.chainMap).map(([key, val]) => ( + [key, new SNS(val)] + )) + ); + } + + // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-empty-function + public async init(): Promise { } + + // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars + public async resolveReverseName(_address: string): Promise { + return null + } + + public async resolveAddress( + name: string, + coin: CoinType = "ETH" + ): Promise { + const resolver = this.chainResolvers[coin]; + if (resolver) { + return resolver.resolveName(name) + .then((address) => address ?? null) + .catch(() => null) + } + + return null + } + + // eslint-disable-next-line class-methods-use-this + public isSupportedName(name: string): boolean { + return getTLD(name) === "sol"; + } +} + +export default SNSResolver; diff --git a/packages/name-resolution/src/sns/types.ts b/packages/name-resolution/src/sns/types.ts new file mode 100644 index 000000000..842392adc --- /dev/null +++ b/packages/name-resolution/src/sns/types.ts @@ -0,0 +1,11 @@ +import { SupportedChains, SNS } from "@bonfida/sns-warp-evm"; + +type SupportedNetwork = "BASE" | "BNB"; + +export interface SNSOptions { + network: "testnet" | "mainnet"; +} + +export type ChainMap = Record; + +export type Resolvers = Record; diff --git a/packages/name-resolution/src/types.ts b/packages/name-resolution/src/types.ts index 242f5320d..456c3babb 100644 --- a/packages/name-resolution/src/types.ts +++ b/packages/name-resolution/src/types.ts @@ -1,5 +1,6 @@ import { ENSOptions } from "./ens/types"; import { SIDOptions } from "./sid/types"; +import { SNSOptions } from "./sns/types"; export type CoinType = | "BTC" @@ -137,7 +138,9 @@ export type CoinType = | "NRG" | "ARB1" | "CELO" - | "AVAXC"; + | "AVAXC" + | "BASE"; + export abstract class BaseResolver { name: string; @@ -157,4 +160,5 @@ export abstract class BaseResolver { export interface NameResolverOptions { ens: ENSOptions; sid: SIDOptions; + sns: SNSOptions; } diff --git a/packages/name-resolution/tests/resolver.test.ts b/packages/name-resolution/tests/resolver.test.ts index 971992857..45f5d6c64 100644 --- a/packages/name-resolution/tests/resolver.test.ts +++ b/packages/name-resolution/tests/resolver.test.ts @@ -14,6 +14,9 @@ describe("Name Resolver resolving", () => { arb: "https://nodes.mewapi.io/rpc/arb", }, }, + sns: { + network: "testnet", + }, }); let address = await resolver.resolveAddress("test.eth", "ETH"); expect(address).to.be.eq("0xeefB13C7D42eFCc655E528dA6d6F7bBcf9A2251d"); @@ -34,6 +37,9 @@ describe("Name Resolver resolving", () => { arb: "https://nodes.mewapi.io/rpc/arb", }, }, + sns: { + network: "testnet", + }, }); let name = await resolver.resolveReverseName( "0xe5dc07bdcdb8c98850050c7f67de7e164b1ea391" diff --git a/packages/name-resolution/tests/sns.test.ts b/packages/name-resolution/tests/sns.test.ts new file mode 100644 index 000000000..a37e75950 --- /dev/null +++ b/packages/name-resolution/tests/sns.test.ts @@ -0,0 +1,26 @@ +import { expect } from "chai"; +import SNSResolver from "../src/sns" + +describe("SNS Name resolving", () => { + // the tests container + it("it should properly resolve address", async () => { + const resolver = new SNSResolver({ network: "testnet" }); + await resolver.init(); + const address = await resolver.resolveAddress("mock3.sol", "BNB"); + expect(address).to.be.eq("0x1D719d2dB763f905b1924F46a5185e001Dd93786"); + }).timeout(10000); + + it("it should return null if not found", async () => { + const resolver = new SNSResolver({ network: "testnet" }); + await resolver.init(); + const name = await resolver.resolveReverseName( + "0xe5dc07bdcdb8c98850050c7f67de7e164b1ea392" + ); + expect(name).to.be.eq(null); + const address = await resolver.resolveAddress( + "sdfsfsdfsdfsdf.sol", + "BASE" + ); + expect(address).to.be.eq(null); + }).timeout(10000); +}); diff --git a/yarn.lock b/yarn.lock index 2574f2fba..492a39fde 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1754,6 +1754,17 @@ __metadata: languageName: node linkType: hard +"@bonfida/sns-warp-evm@npm:^0.0.4": + version: 0.0.4 + resolution: "@bonfida/sns-warp-evm@npm:0.0.4" + peerDependencies: + "@ethersproject/address": ^5.7.0 + "@ethersproject/hash": ^5.7.0 + "@ethersproject/providers": ^5.7.2 + checksum: ad7e8c8a157f3c79668d8704eecb96708384f54f07088aaabcfb4798984d5d93082ddc80bb5b020e114d6bf9769781205aad53a1a9aa3c652558a6985b24a36f + languageName: node + linkType: hard + "@cardano-foundation/ledgerjs-hw-app-cardano@npm:^6.0.1": version: 6.0.1 resolution: "@cardano-foundation/ledgerjs-hw-app-cardano@npm:6.0.1" @@ -14910,6 +14921,7 @@ __metadata: version: 0.0.0-use.local resolution: "enkrypt@workspace:." dependencies: + "@bonfida/sns-warp-evm": ^0.0.4 "@commitlint/cli": ^19.3.0 "@commitlint/config-conventional": ^19.2.2 "@swc/core": ^1.6.3