Skip to content

Commit 4cf6d95

Browse files
committed
get deployed entrypoint
1 parent f524857 commit 4cf6d95

File tree

2 files changed

+140
-4
lines changed

2 files changed

+140
-4
lines changed

packages/thirdweb/src/tokens/constants.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,26 @@ export const DEFAULT_POOL_INITIAL_TICK = 230200;
44
export const DEFAULT_DEVELOPER_REWARD_BPS = 0;
55
export const DEFAULT_DEVELOPER_ADDRESS =
66
"0x1Af20C6B23373350aD464700B5965CE4B0D2aD94";
7+
8+
export const CONTRACT_FACTORY_DEPLOY_URL =
9+
"ipfs://QmZ77LnDCDyzd8rqat2YDkdbKUbdNobNuoBLy1q8YfCSKq";
10+
export const ENTRYPOINT_DEPLOY_URL =
11+
"ipfs://QmSAhuGEMtuGtBAWLB2jLacppqMPkiRtoMsy1R9Wm4PWWM";
12+
13+
export const OWNER_ADDRESS = "0x1A472863cF21D5Aa27F417dF9140400324C48f22";
14+
export const MANAGER_ADDRESS = "";
15+
16+
export const CONTRACT_DEPLOY = {
17+
CREATE: 0,
18+
CREATE2: 1,
19+
CREATE3: 2,
20+
} as const;
21+
22+
export const PROXY_DEPLOY = {
23+
CLONE: 0, // Deterministic minimal proxy
24+
CLONE_IMMUTABLE_ARGS: 1, // Deterministic proxy with immutable args
25+
ERC1967: 2, // ERC1967 upgradeable proxy
26+
ERC1967_IMMUTABLE_ARGS: 3, // ERC1967 proxy with immutable args
27+
ERC1967_BEACON: 4, // ERC1967 beacon proxy
28+
ERC1967_BEACON_IMMUTABLE_ARGS: 5, // ERC1967 beacon proxy with immutable args
29+
} as const;
Lines changed: 117 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,121 @@
1+
import type { AbiConstructor } from "abitype";
2+
import { getContract } from "src/contract/contract.js";
3+
import { getDeployedInfraContractFromMetadata } from "src/contract/deployment/utils/infra.js";
4+
import { computeDeployAddress } from "src/extensions/tokens/__generated__/ContractFactory/read/computeDeployAddress.js";
5+
import { computeProxyAddress } from "src/extensions/tokens/__generated__/ContractFactory/read/computeProxyAddress.js";
6+
import { encodeAbiParameters } from "src/utils/abi/encodeAbiParameters.js";
7+
import { normalizeFunctionParams } from "src/utils/abi/normalizeFunctionParams.js";
8+
import {
9+
fetchBytecodeFromCompilerMetadata,
10+
fetchDeployMetadata,
11+
} from "src/utils/any-evm/deploy-metadata.js";
12+
import { isContractDeployed } from "src/utils/bytecode/is-contract-deployed.js";
13+
import { padHex, toHex } from "src/utils/encoding/hex.js";
14+
import { withCache } from "src/utils/promise/withCache.js";
115
import type { ClientAndChain } from "../utils/types.js";
16+
import {
17+
CONTRACT_DEPLOY,
18+
CONTRACT_FACTORY_DEPLOY_URL,
19+
ENTRYPOINT_DEPLOY_URL,
20+
MANAGER_ADDRESS,
21+
OWNER_ADDRESS,
22+
PROXY_DEPLOY,
23+
} from "./constants.js";
224

325
export async function getDeployedEntrypointERC20(options: ClientAndChain) {
4-
// TODO (1): get the create2 factory address
5-
// TODO (2): get the bootstrap contract factory address from the create2 factory
6-
// TODO (3): get the entrypoint contract addresses using contract factory OR predict it using the contract factory address
7-
throw new Error("Asset factory deployment is not deployed yet.");
26+
const cacheKey = `${options.chain.id}-${ENTRYPOINT_DEPLOY_URL}`;
27+
28+
return withCache(
29+
async () => {
30+
// 1. Get deployed contract factory
31+
const contractFactory = await getDeployedContractFactory(options);
32+
33+
if (!contractFactory) {
34+
throw new Error(
35+
`Contract factory not found on chain: ${options.chain.id}`,
36+
);
37+
}
38+
39+
// 2. Fetch metadata and encode args for entrypoint implementation
40+
const contractMetadata = await fetchDeployMetadata({
41+
client: options.client,
42+
uri: ENTRYPOINT_DEPLOY_URL,
43+
});
44+
const bytecode = await fetchBytecodeFromCompilerMetadata({
45+
chain: options.chain,
46+
client: options.client,
47+
compilerMetadata: contractMetadata,
48+
});
49+
const constructorAbi = contractMetadata.abi.find(
50+
(abi) => abi.type === "constructor",
51+
) as AbiConstructor | undefined;
52+
const encodedArgs = encodeAbiParameters(
53+
constructorAbi?.inputs ?? [],
54+
normalizeFunctionParams(constructorAbi, {}),
55+
);
56+
57+
// 3. Compute entrypoint implementation address
58+
const entrypointImplAddress = await computeDeployAddress({
59+
contract: contractFactory,
60+
deployType: CONTRACT_DEPLOY.CREATE2,
61+
bytecode,
62+
constructorArgs: encodedArgs,
63+
salt: padHex(toHex("ERC20_ENTRYPOINT:1"), { size: 32 }),
64+
});
65+
66+
// 4. Compute entrypoint proxy address
67+
const entrypointProxyAddress = await computeProxyAddress({
68+
contract: contractFactory,
69+
implementation: entrypointImplAddress,
70+
data: "0x",
71+
salt: padHex(toHex("ERC20_ENTRYPOINT_PROXY:1"), { size: 32 }),
72+
deployType: PROXY_DEPLOY.ERC1967,
73+
});
74+
const entrypointProxy = getContract({
75+
...options,
76+
address: entrypointProxyAddress,
77+
});
78+
79+
const isDeployed = await isContractDeployed(entrypointProxy);
80+
81+
if (!isDeployed) {
82+
throw new Error(
83+
`Entrypoint is not deployed yet on chain: ${options.chain.id}`,
84+
);
85+
}
86+
87+
return entrypointProxy;
88+
},
89+
{
90+
cacheKey,
91+
cacheTime: 24 * 60 * 60 * 1000, // 1 day
92+
},
93+
);
94+
}
95+
96+
async function getDeployedContractFactory(options: ClientAndChain) {
97+
const cacheKey = `${options.chain.id}-${CONTRACT_FACTORY_DEPLOY_URL}`;
98+
return withCache(
99+
async () => {
100+
const contractMetadata = await fetchDeployMetadata({
101+
client: options.client,
102+
uri: CONTRACT_FACTORY_DEPLOY_URL,
103+
});
104+
105+
return getDeployedInfraContractFromMetadata({
106+
chain: options.chain,
107+
client: options.client,
108+
constructorParams: {
109+
owner: OWNER_ADDRESS,
110+
manager: MANAGER_ADDRESS,
111+
},
112+
contractMetadata,
113+
salt: "THIRDWEB_CONTRACT_FACTORY:1",
114+
});
115+
},
116+
{
117+
cacheKey,
118+
cacheTime: 24 * 60 * 60 * 1000, // 1 day
119+
},
120+
);
8121
}

0 commit comments

Comments
 (0)