-
Notifications
You must be signed in to change notification settings - Fork 399
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[TS SDK] Feature: L2 ENS name resolution (#4334)
## Problem solved Short description of the bug fixed or feature added <!-- start pr-codex --> --- ## PR-Codex overview This PR adds L2 ENS name resolution functionality to the Thirdweb package. ### Detailed summary - Added L2 ENS name resolution - Updated cache key in resolve-name.ts - Added new constants in constants.ts - Exported new functions and constants in ens.ts - Updated resolve-address.ts and resolve-l2-name.ts for Basename resolution - Added resolve-l2-name test cases - Added resolve-l2-name functionality and related files > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
- Loading branch information
1 parent
c52e1be
commit 6432e8d
Showing
10 changed files
with
308 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"thirdweb": minor | ||
--- | ||
|
||
Adds L2 ENS name resolution |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[ | ||
"function name(bytes32 node) view returns (string memory)" | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
122 changes: 122 additions & 0 deletions
122
packages/thirdweb/src/extensions/ens/__generated__/L2Resolver/read/name.ts
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,6 @@ | ||
export const UNIVERSAL_RESOLVER_ADDRESS = | ||
"0xce01f8eee7E479C928F8919abD53E553a36CeF67"; | ||
export const BASENAME_RESOLVER_ADDRESS = | ||
"0xC6d566A56A1aFf6508b41f6c90ff131615583BCD"; | ||
export const BASE_SEPOLIA_BASENAME_RESOLVER_ADDRESS = | ||
"0x6533C94869D28fAA8dF77cc63f9e2b2D6Cf77eBA"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
packages/thirdweb/src/extensions/ens/resolve-l2-name.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { describe, expect, it } from "vitest"; | ||
import { TEST_CLIENT } from "../../../test/src/test-clients.js"; | ||
import { base } from "../../chains/chain-definitions/base.js"; | ||
import { BASENAME_RESOLVER_ADDRESS } from "./constants.js"; | ||
import { resolveL2Name } from "./resolve-l2-name.js"; | ||
|
||
// skip this test suite if there is no secret key available to test with | ||
// TODO: remove reliance on secret key during unit tests entirely | ||
describe.runIf(process.env.TW_SECRET_KEY)("ENS:resolve-l2-name", () => { | ||
it("should resolve Basename", async () => { | ||
const ens = await resolveL2Name({ | ||
client: TEST_CLIENT, | ||
// myk.base.eth | ||
address: "0x653Ff253b0c7C1cc52f484e891b71f9f1F010Bfb", | ||
resolverChain: base, | ||
resolverAddress: BASENAME_RESOLVER_ADDRESS, | ||
}); | ||
expect(ens).toBe("myk.base.eth"); | ||
}); | ||
|
||
it("should return null if no Basename exists for the address", async () => { | ||
const ens = await resolveL2Name({ | ||
client: TEST_CLIENT, | ||
address: "0xc6248746A9CA5935ae722E2061347A5897548c03", | ||
resolverChain: base, | ||
resolverAddress: BASENAME_RESOLVER_ADDRESS, | ||
}); | ||
expect(ens).toBeNull(); | ||
}); | ||
}); |
107 changes: 107 additions & 0 deletions
107
packages/thirdweb/src/extensions/ens/resolve-l2-name.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import type { Address } from "abitype"; | ||
import { type Hex, encodePacked, keccak256, namehash } from "viem"; | ||
import type { Chain } from "../../chains/types.js"; | ||
import type { ThirdwebClient } from "../../client/client.js"; | ||
import { getContract } from "../../contract/contract.js"; | ||
import { withCache } from "../../utils/promise/withCache.js"; | ||
import { name } from "./__generated__/L2Resolver/read/name.js"; | ||
|
||
/** | ||
* @extension ENS | ||
*/ | ||
export type ResolveL2NameOptions = { | ||
client: ThirdwebClient; | ||
address: Address; | ||
resolverAddress: string; | ||
resolverChain: Chain; | ||
}; | ||
|
||
/** | ||
* Convert an address to a reverse node for ENS resolution | ||
* | ||
* @internal | ||
*/ | ||
export const convertReverseNodeToBytes = ( | ||
address: Address, | ||
chainId: number, | ||
) => { | ||
const addressFormatted = address.toLocaleLowerCase() as Address; | ||
const addressNode = keccak256(addressFormatted.substring(2) as Hex); | ||
const cointype = (0x80000000 | chainId) >>> 0; | ||
|
||
const chainCoinType = cointype.toString(16).toLocaleUpperCase(); | ||
const reverseNode = namehash(`${chainCoinType.toLocaleUpperCase()}.reverse`); | ||
|
||
const addressReverseNode = keccak256( | ||
encodePacked(["bytes32", "bytes32"], [reverseNode, addressNode]), | ||
); | ||
return addressReverseNode; | ||
}; | ||
|
||
/** | ||
* Resolves the L2 name for a specified address. | ||
* @param options - The options for resolving an L2 ENS address. | ||
* @example | ||
* ```ts | ||
* import { resolveL2Name } from "thirdweb/extensions/ens"; | ||
* const name = await resolveL2Name({ | ||
* client, | ||
* address: "0x1234...", | ||
* resolverAddress: "0x...", | ||
* resolverChain: base, | ||
* }); | ||
* ``` | ||
* | ||
* Resolve a Basename. | ||
* ```ts | ||
* import { resolveL2Name, BASENAME_RESOLVER_ADDRESS } from "thirdweb/extensions/ens"; | ||
* import { base } from "thirdweb/chains"; | ||
* const name = await resolveL2Name({ | ||
* client, | ||
* address: "0x1234...", | ||
* resolverAddress: BASENAME_RESOLVER_ADDRESS, | ||
* resolverChain: base, | ||
* }); | ||
* ``` | ||
* @extension ENS | ||
* @returns A promise that resolves to the Ethereum address. | ||
*/ | ||
export async function resolveL2Name(options: ResolveL2NameOptions) { | ||
const { client, address, resolverAddress, resolverChain } = options; | ||
|
||
return withCache( | ||
async () => { | ||
const contract = getContract({ | ||
client, | ||
chain: resolverChain, | ||
address: resolverAddress, | ||
}); | ||
|
||
const reverseName = convertReverseNodeToBytes( | ||
address, | ||
resolverChain.id || 1, | ||
); | ||
|
||
const resolvedName = await name({ | ||
contract, | ||
node: reverseName, | ||
}).catch((e) => { | ||
if ("data" in e && e.data === "0x7199966d") { | ||
return null; | ||
} | ||
throw e; | ||
}); | ||
|
||
if (resolvedName === "") { | ||
return null; | ||
} | ||
|
||
return resolvedName; | ||
}, | ||
{ | ||
cacheKey: `ens:name:${resolverChain}:${address}`, | ||
// 1min cache | ||
cacheTime: 60 * 1000, | ||
}, | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters