thirdweb 5.49.0 → 5.50.0-nightly-6432e8dc6bdd0ed985fe0d76e47b36601bfa8be3-20240831000359
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/exports/extensions/ens.js +6 -1
- package/dist/cjs/exports/extensions/ens.js.map +1 -1
- package/dist/cjs/extensions/ens/__generated__/L2Resolver/read/name.js +115 -0
- package/dist/cjs/extensions/ens/__generated__/L2Resolver/read/name.js.map +1 -0
- package/dist/cjs/extensions/ens/constants.js +3 -1
- package/dist/cjs/extensions/ens/constants.js.map +1 -1
- package/dist/cjs/extensions/ens/resolve-address.js +13 -1
- package/dist/cjs/extensions/ens/resolve-address.js.map +1 -1
- package/dist/cjs/extensions/ens/resolve-l2-name.js +80 -0
- package/dist/cjs/extensions/ens/resolve-l2-name.js.map +1 -0
- package/dist/cjs/extensions/ens/resolve-name.js +1 -1
- package/dist/cjs/extensions/ens/resolve-name.js.map +1 -1
- package/dist/cjs/react/web/ui/prebuilt/thirdweb/CreateDirectListingButton/index.js +64 -19
- package/dist/cjs/react/web/ui/prebuilt/thirdweb/CreateDirectListingButton/index.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/version.js.map +1 -1
- package/dist/esm/exports/extensions/ens.js +2 -0
- package/dist/esm/exports/extensions/ens.js.map +1 -1
- package/dist/esm/extensions/ens/__generated__/L2Resolver/read/name.js +107 -0
- package/dist/esm/extensions/ens/__generated__/L2Resolver/read/name.js.map +1 -0
- package/dist/esm/extensions/ens/constants.js +2 -0
- package/dist/esm/extensions/ens/constants.js.map +1 -1
- package/dist/esm/extensions/ens/resolve-address.js +13 -1
- package/dist/esm/extensions/ens/resolve-address.js.map +1 -1
- package/dist/esm/extensions/ens/resolve-l2-name.js +75 -0
- package/dist/esm/extensions/ens/resolve-l2-name.js.map +1 -0
- package/dist/esm/extensions/ens/resolve-name.js +1 -1
- package/dist/esm/extensions/ens/resolve-name.js.map +1 -1
- package/dist/esm/react/web/ui/prebuilt/thirdweb/CreateDirectListingButton/index.js +62 -17
- package/dist/esm/react/web/ui/prebuilt/thirdweb/CreateDirectListingButton/index.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/types/exports/extensions/ens.d.ts +2 -0
- package/dist/types/exports/extensions/ens.d.ts.map +1 -1
- package/dist/types/extensions/ens/__generated__/L2Resolver/read/name.d.ts +84 -0
- package/dist/types/extensions/ens/__generated__/L2Resolver/read/name.d.ts.map +1 -0
- package/dist/types/extensions/ens/constants.d.ts +2 -0
- package/dist/types/extensions/ens/constants.d.ts.map +1 -1
- package/dist/types/extensions/ens/resolve-address.d.ts +12 -0
- package/dist/types/extensions/ens/resolve-address.d.ts.map +1 -1
- package/dist/types/extensions/ens/resolve-l2-name.d.ts +48 -0
- package/dist/types/extensions/ens/resolve-l2-name.d.ts.map +1 -0
- package/dist/types/react/web/ui/prebuilt/thirdweb/CreateDirectListingButton/index.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/version.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/exports/extensions/ens.ts +10 -0
- package/src/extensions/ens/__generated__/L2Resolver/read/name.ts +122 -0
- package/src/extensions/ens/constants.ts +4 -0
- package/src/extensions/ens/resolve-address.test.ts +13 -0
- package/src/extensions/ens/resolve-address.ts +13 -1
- package/src/extensions/ens/resolve-l2-name.test.ts +30 -0
- package/src/extensions/ens/resolve-l2-name.ts +107 -0
- package/src/extensions/ens/resolve-name.ts +1 -1
- package/src/react/web/ui/prebuilt/thirdweb/CreateDirectListingButton/index.tsx +75 -18
- package/src/version.ts +1 -1
@@ -32,6 +32,18 @@ export type ResolveAddressOptions = {
|
|
32
32
|
* name: "vitalik.eth",
|
33
33
|
* });
|
34
34
|
* ```
|
35
|
+
*
|
36
|
+
* Resolve an address to a Basename.
|
37
|
+
* ```ts
|
38
|
+
* import { resolveAddress, BASENAME_RESOLVER_ADDRESS } from "thirdweb/extensions/ens";
|
39
|
+
* import { base } from "thirdweb/chains";
|
40
|
+
* const address = await resolveAddress({
|
41
|
+
* client,
|
42
|
+
* name: "myk.base.eth",
|
43
|
+
* resolverAddress: BASENAME_RESOLVER_ADDRESS,
|
44
|
+
* resolverChain: base,
|
45
|
+
* });
|
46
|
+
* ```
|
35
47
|
* @extension ENS
|
36
48
|
* @returns A promise that resolves to the Ethereum address.
|
37
49
|
*/
|
@@ -58,7 +70,7 @@ export async function resolveAddress(options: ResolveAddressOptions) {
|
|
58
70
|
return resolvedAddress;
|
59
71
|
},
|
60
72
|
{
|
61
|
-
cacheKey: `ens:addr:${name}`,
|
73
|
+
cacheKey: `ens:addr:${resolverChain?.id || 1}:${name}`,
|
62
74
|
// 1min cache
|
63
75
|
cacheTime: 60 * 1000,
|
64
76
|
},
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
2
|
+
import { TEST_CLIENT } from "../../../test/src/test-clients.js";
|
3
|
+
import { base } from "../../chains/chain-definitions/base.js";
|
4
|
+
import { BASENAME_RESOLVER_ADDRESS } from "./constants.js";
|
5
|
+
import { resolveL2Name } from "./resolve-l2-name.js";
|
6
|
+
|
7
|
+
// skip this test suite if there is no secret key available to test with
|
8
|
+
// TODO: remove reliance on secret key during unit tests entirely
|
9
|
+
describe.runIf(process.env.TW_SECRET_KEY)("ENS:resolve-l2-name", () => {
|
10
|
+
it("should resolve Basename", async () => {
|
11
|
+
const ens = await resolveL2Name({
|
12
|
+
client: TEST_CLIENT,
|
13
|
+
// myk.base.eth
|
14
|
+
address: "0x653Ff253b0c7C1cc52f484e891b71f9f1F010Bfb",
|
15
|
+
resolverChain: base,
|
16
|
+
resolverAddress: BASENAME_RESOLVER_ADDRESS,
|
17
|
+
});
|
18
|
+
expect(ens).toBe("myk.base.eth");
|
19
|
+
});
|
20
|
+
|
21
|
+
it("should return null if no Basename exists for the address", async () => {
|
22
|
+
const ens = await resolveL2Name({
|
23
|
+
client: TEST_CLIENT,
|
24
|
+
address: "0xc6248746A9CA5935ae722E2061347A5897548c03",
|
25
|
+
resolverChain: base,
|
26
|
+
resolverAddress: BASENAME_RESOLVER_ADDRESS,
|
27
|
+
});
|
28
|
+
expect(ens).toBeNull();
|
29
|
+
});
|
30
|
+
});
|
@@ -0,0 +1,107 @@
|
|
1
|
+
import type { Address } from "abitype";
|
2
|
+
import { type Hex, encodePacked, keccak256, namehash } from "viem";
|
3
|
+
import type { Chain } from "../../chains/types.js";
|
4
|
+
import type { ThirdwebClient } from "../../client/client.js";
|
5
|
+
import { getContract } from "../../contract/contract.js";
|
6
|
+
import { withCache } from "../../utils/promise/withCache.js";
|
7
|
+
import { name } from "./__generated__/L2Resolver/read/name.js";
|
8
|
+
|
9
|
+
/**
|
10
|
+
* @extension ENS
|
11
|
+
*/
|
12
|
+
export type ResolveL2NameOptions = {
|
13
|
+
client: ThirdwebClient;
|
14
|
+
address: Address;
|
15
|
+
resolverAddress: string;
|
16
|
+
resolverChain: Chain;
|
17
|
+
};
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Convert an address to a reverse node for ENS resolution
|
21
|
+
*
|
22
|
+
* @internal
|
23
|
+
*/
|
24
|
+
export const convertReverseNodeToBytes = (
|
25
|
+
address: Address,
|
26
|
+
chainId: number,
|
27
|
+
) => {
|
28
|
+
const addressFormatted = address.toLocaleLowerCase() as Address;
|
29
|
+
const addressNode = keccak256(addressFormatted.substring(2) as Hex);
|
30
|
+
const cointype = (0x80000000 | chainId) >>> 0;
|
31
|
+
|
32
|
+
const chainCoinType = cointype.toString(16).toLocaleUpperCase();
|
33
|
+
const reverseNode = namehash(`${chainCoinType.toLocaleUpperCase()}.reverse`);
|
34
|
+
|
35
|
+
const addressReverseNode = keccak256(
|
36
|
+
encodePacked(["bytes32", "bytes32"], [reverseNode, addressNode]),
|
37
|
+
);
|
38
|
+
return addressReverseNode;
|
39
|
+
};
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Resolves the L2 name for a specified address.
|
43
|
+
* @param options - The options for resolving an L2 ENS address.
|
44
|
+
* @example
|
45
|
+
* ```ts
|
46
|
+
* import { resolveL2Name } from "thirdweb/extensions/ens";
|
47
|
+
* const name = await resolveL2Name({
|
48
|
+
* client,
|
49
|
+
* address: "0x1234...",
|
50
|
+
* resolverAddress: "0x...",
|
51
|
+
* resolverChain: base,
|
52
|
+
* });
|
53
|
+
* ```
|
54
|
+
*
|
55
|
+
* Resolve a Basename.
|
56
|
+
* ```ts
|
57
|
+
* import { resolveL2Name, BASENAME_RESOLVER_ADDRESS } from "thirdweb/extensions/ens";
|
58
|
+
* import { base } from "thirdweb/chains";
|
59
|
+
* const name = await resolveL2Name({
|
60
|
+
* client,
|
61
|
+
* address: "0x1234...",
|
62
|
+
* resolverAddress: BASENAME_RESOLVER_ADDRESS,
|
63
|
+
* resolverChain: base,
|
64
|
+
* });
|
65
|
+
* ```
|
66
|
+
* @extension ENS
|
67
|
+
* @returns A promise that resolves to the Ethereum address.
|
68
|
+
*/
|
69
|
+
export async function resolveL2Name(options: ResolveL2NameOptions) {
|
70
|
+
const { client, address, resolverAddress, resolverChain } = options;
|
71
|
+
|
72
|
+
return withCache(
|
73
|
+
async () => {
|
74
|
+
const contract = getContract({
|
75
|
+
client,
|
76
|
+
chain: resolverChain,
|
77
|
+
address: resolverAddress,
|
78
|
+
});
|
79
|
+
|
80
|
+
const reverseName = convertReverseNodeToBytes(
|
81
|
+
address,
|
82
|
+
resolverChain.id || 1,
|
83
|
+
);
|
84
|
+
|
85
|
+
const resolvedName = await name({
|
86
|
+
contract,
|
87
|
+
node: reverseName,
|
88
|
+
}).catch((e) => {
|
89
|
+
if ("data" in e && e.data === "0x7199966d") {
|
90
|
+
return null;
|
91
|
+
}
|
92
|
+
throw e;
|
93
|
+
});
|
94
|
+
|
95
|
+
if (resolvedName === "") {
|
96
|
+
return null;
|
97
|
+
}
|
98
|
+
|
99
|
+
return resolvedName;
|
100
|
+
},
|
101
|
+
{
|
102
|
+
cacheKey: `ens:name:${resolverChain}:${address}`,
|
103
|
+
// 1min cache
|
104
|
+
cacheTime: 60 * 1000,
|
105
|
+
},
|
106
|
+
);
|
107
|
+
}
|
@@ -4,7 +4,8 @@ import { useCallback } from "react";
|
|
4
4
|
import type { Chain } from "../../../../../../chains/types.js";
|
5
5
|
import type { ThirdwebClient } from "../../../../../../client/client.js";
|
6
6
|
import { getContract } from "../../../../../../contract/contract.js";
|
7
|
-
import {
|
7
|
+
import { isERC721 } from "../../../../../../extensions/erc721/read/isERC721.js";
|
8
|
+
import { isERC1155 } from "../../../../../../extensions/erc1155/read/isERC1155.js";
|
8
9
|
import {
|
9
10
|
type CreateListingParams,
|
10
11
|
createListing,
|
@@ -74,12 +75,13 @@ export function CreateDirectListingButton(
|
|
74
75
|
});
|
75
76
|
const account = useActiveAccount();
|
76
77
|
const defaultPayModalMetadata = payModal ? payModal.metadata : undefined;
|
78
|
+
const nftContract = getContract({
|
79
|
+
address: assetContractAddress,
|
80
|
+
chain,
|
81
|
+
client,
|
82
|
+
});
|
77
83
|
const { data: payMetadata } = useReadContract(getPayMetadata, {
|
78
|
-
contract:
|
79
|
-
address: assetContractAddress,
|
80
|
-
chain,
|
81
|
-
client,
|
82
|
-
}),
|
84
|
+
contract: nftContract,
|
83
85
|
tokenId,
|
84
86
|
queryOptions: {
|
85
87
|
enabled: !defaultPayModalMetadata,
|
@@ -91,19 +93,78 @@ export function CreateDirectListingButton(
|
|
91
93
|
if (!account) {
|
92
94
|
throw new Error("No account detected");
|
93
95
|
}
|
96
|
+
const [is721, is1155] = await Promise.all([
|
97
|
+
isERC721({ contract: nftContract }),
|
98
|
+
isERC1155({ contract: nftContract }),
|
99
|
+
]);
|
100
|
+
if (!is1155 && !is721) {
|
101
|
+
throw new Error("Asset must either be ERC721 or ERC1155");
|
102
|
+
}
|
103
|
+
// Check for token approval
|
104
|
+
if (is1155) {
|
105
|
+
const [{ isApprovedForAll }, { setApprovalForAll }] = await Promise.all([
|
106
|
+
import(
|
107
|
+
"../../../../../../extensions/erc1155/__generated__/IERC1155/read/isApprovedForAll.js"
|
108
|
+
),
|
109
|
+
import(
|
110
|
+
"../../../../../../extensions/erc1155/__generated__/IERC1155/write/setApprovalForAll.js"
|
111
|
+
),
|
112
|
+
]);
|
113
|
+
const isApproved = await isApprovedForAll({
|
114
|
+
contract: nftContract,
|
115
|
+
operator: marketplaceContract.address,
|
116
|
+
owner: account.address,
|
117
|
+
});
|
118
|
+
if (!isApproved) {
|
119
|
+
const transaction = setApprovalForAll({
|
120
|
+
contract: nftContract,
|
121
|
+
operator: marketplaceContract.address,
|
122
|
+
approved: true,
|
123
|
+
});
|
124
|
+
await mutateAsync(transaction);
|
125
|
+
}
|
126
|
+
} else {
|
127
|
+
const [{ isApprovedForAll }, { setApprovalForAll }, { getApproved }] =
|
128
|
+
await Promise.all([
|
129
|
+
import(
|
130
|
+
"../../../../../../extensions/erc721/__generated__/IERC721A/read/isApprovedForAll.js"
|
131
|
+
),
|
132
|
+
import(
|
133
|
+
"../../../../../../extensions/erc721/__generated__/IERC721A/write/setApprovalForAll.js"
|
134
|
+
),
|
135
|
+
import(
|
136
|
+
"../../../../../../extensions/erc721/__generated__/IERC721A/read/getApproved.js"
|
137
|
+
),
|
138
|
+
]);
|
139
|
+
const [isApproved, tokenApproved] = await Promise.all([
|
140
|
+
isApprovedForAll({
|
141
|
+
contract: nftContract,
|
142
|
+
operator: marketplaceContract.address,
|
143
|
+
owner: account.address,
|
144
|
+
}),
|
145
|
+
getApproved({ contract: nftContract, tokenId: props.tokenId }),
|
146
|
+
]);
|
147
|
+
|
148
|
+
if (
|
149
|
+
!isApproved &&
|
150
|
+
tokenApproved.toLowerCase() !==
|
151
|
+
marketplaceContract.address.toLowerCase()
|
152
|
+
) {
|
153
|
+
const transaction = setApprovalForAll({
|
154
|
+
contract: nftContract,
|
155
|
+
operator: marketplaceContract.address,
|
156
|
+
approved: true,
|
157
|
+
});
|
158
|
+
await mutateAsync(transaction);
|
159
|
+
}
|
160
|
+
}
|
94
161
|
const listingTx = createListing({
|
95
162
|
contract: marketplaceContract,
|
96
163
|
...props,
|
97
164
|
});
|
98
|
-
|
99
|
-
transaction: listingTx,
|
100
|
-
account,
|
101
|
-
});
|
102
|
-
if (approveTx) {
|
103
|
-
await mutateAsync(approveTx);
|
104
|
-
}
|
165
|
+
|
105
166
|
return listingTx;
|
106
|
-
}, [marketplaceContract, props, account, mutateAsync]);
|
167
|
+
}, [marketplaceContract, props, account, mutateAsync, nftContract]);
|
107
168
|
|
108
169
|
return (
|
109
170
|
<TransactionButton
|
@@ -128,14 +189,10 @@ async function getPayMetadata(
|
|
128
189
|
}>,
|
129
190
|
): Promise<{ name?: string; image?: string }> {
|
130
191
|
const [
|
131
|
-
{ isERC721 },
|
132
|
-
{ isERC1155 },
|
133
192
|
{ getContractMetadata },
|
134
193
|
{ getNFT: getERC721 },
|
135
194
|
{ getNFT: getERC1155 },
|
136
195
|
] = await Promise.all([
|
137
|
-
import("../../../../../../extensions/erc721/read/isERC721.js"),
|
138
|
-
import("../../../../../../extensions/erc1155/read/isERC1155.js"),
|
139
196
|
import("../../../../../../extensions/common/read/getContractMetadata.js"),
|
140
197
|
import("../../../../../../extensions/erc721/read/getNFT.js"),
|
141
198
|
import("../../../../../../extensions/erc1155/read/getNFT.js"),
|
package/src/version.ts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export const version = "5.
|
1
|
+
export const version = "5.50.0-nightly-6432e8dc6bdd0ed985fe0d76e47b36601bfa8be3-20240831000359";
|