Skip to content

Commit b7c0e4a

Browse files
refactor: optimize zksync chain detection and add Creator Testnet test
1 parent 78cbc41 commit b7c0e4a

File tree

9 files changed

+122
-70
lines changed

9 files changed

+122
-70
lines changed

.changeset/green-books-drop.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
Auto resolve zksync bytecode

packages/thirdweb/src/contract/actions/compiler-metadata.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,10 @@ export type CompilerMetadata = {
3030
export function formatCompilerMetadata(
3131
// biome-ignore lint/suspicious/noExplicitAny: TODO: fix later
3232
metadata: any,
33-
compilerType?: "solc" | "zksolc",
3433
): CompilerMetadata {
3534
let meta = metadata;
36-
if (compilerType === "zksolc") {
37-
meta = metadata.source_metadata || meta;
35+
if ("source_metadata" in metadata) {
36+
meta = metadata.source_metadata;
3837
}
3938
const compilationTarget = meta.settings.compilationTarget;
4039
const targets = Object.keys(compilationTarget);

packages/thirdweb/src/contract/deployment/publisher.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ export async function fetchPublishedContractMetadata(options: {
2424
contractId: string;
2525
publisher?: string;
2626
version?: string;
27-
compilerType?: "solc" | "zksolc";
2827
}): Promise<FetchDeployMetadataResult> {
2928
const cacheKey = `${options.contractId}-${options.publisher}-${options.version}`;
3029
return withCache(
@@ -34,7 +33,6 @@ export async function fetchPublishedContractMetadata(options: {
3433
publisherAddress: options.publisher || THIRDWEB_DEPLOYER,
3534
contractId: options.contractId,
3635
version: options.version,
37-
compilerType: options.compilerType,
3836
});
3937
if (!publishedContract.publishMetadataUri) {
4038
throw new Error(
@@ -44,7 +42,6 @@ export async function fetchPublishedContractMetadata(options: {
4442
const data = await fetchDeployMetadata({
4543
client: options.client,
4644
uri: publishedContract.publishMetadataUri,
47-
compilerType: options.compilerType,
4845
});
4946
return data;
5047
},
@@ -214,7 +211,6 @@ type FetchPublishedContractOptions = {
214211
contractId: string;
215212
version?: string;
216213
client: ThirdwebClient;
217-
compilerType?: "solc" | "zksolc";
218214
};
219215

220216
/**

packages/thirdweb/src/contract/deployment/utils/bootstrap.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { sendAndConfirmTransaction } from "../../../transaction/actions/send-and-confirm-transaction.js";
2-
import type { FetchDeployMetadataResult } from "../../../utils/any-evm/deploy-metadata.js";
2+
import {
3+
type FetchDeployMetadataResult,
4+
fetchBytecodeFromCompilerMetadata,
5+
} from "../../../utils/any-evm/deploy-metadata.js";
36
import { isZkSyncChain } from "../../../utils/any-evm/zksync/isZkSyncChain.js";
47
import type { ClientAndChainAndAccount } from "../../../utils/types.js";
58
import { type ThirdwebContract, getContract } from "../../contract.js";
@@ -27,7 +30,6 @@ export async function getOrDeployInfraForPublishedContract(
2730
constructorParams?: Record<string, unknown>;
2831
publisher?: string;
2932
version?: string;
30-
compilerType?: "solc" | "zksolc";
3133
},
3234
): Promise<{
3335
cloneFactoryContract: ThirdwebContract;
@@ -41,7 +43,6 @@ export async function getOrDeployInfraForPublishedContract(
4143
constructorParams,
4244
publisher,
4345
version,
44-
compilerType,
4546
} = args;
4647

4748
if (await isZkSyncChain(chain)) {
@@ -55,14 +56,17 @@ export async function getOrDeployInfraForPublishedContract(
5556
contractId,
5657
publisher,
5758
version,
58-
compilerType,
5959
});
6060
const implementationContract = await zkDeployContractDeterministic({
6161
chain,
6262
client,
6363
account,
6464
abi: compilerMetadata.abi,
65-
bytecode: compilerMetadata.bytecode,
65+
bytecode: await fetchBytecodeFromCompilerMetadata({
66+
compilerMetadata,
67+
client,
68+
chain,
69+
}),
6670
params: constructorParams,
6771
});
6872
return {

packages/thirdweb/src/extensions/prebuilts/deploy-published.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ import { resolveMethod } from "../../transaction/resolve-method.js";
1313
import { encodeAbiParameters } from "../../utils/abi/encodeAbiParameters.js";
1414
import { normalizeFunctionParams } from "../../utils/abi/normalizeFunctionParams.js";
1515
import { getAddress } from "../../utils/address.js";
16-
import type { CompilerMetadata } from "../../utils/any-evm/deploy-metadata.js";
16+
import {
17+
type CompilerMetadata,
18+
fetchBytecodeFromCompilerMetadata,
19+
} from "../../utils/any-evm/deploy-metadata.js";
1720
import type { FetchDeployMetadataResult } from "../../utils/any-evm/deploy-metadata.js";
1821
import { isZkSyncChain } from "../../utils/any-evm/zksync/isZkSyncChain.js";
1922
import type { Hex } from "../../utils/encoding/hex.js";
@@ -33,7 +36,6 @@ export type DeployPublishedContractOptions = {
3336
version?: string;
3437
implementationConstructorParams?: Record<string, unknown>;
3538
salt?: string;
36-
compilerType?: "solc" | "zksolc";
3739
};
3840

3941
/**
@@ -93,14 +95,12 @@ export async function deployPublishedContract(
9395
version,
9496
implementationConstructorParams,
9597
salt,
96-
compilerType,
9798
} = options;
9899
const deployMetadata = await fetchPublishedContractMetadata({
99100
client,
100101
contractId,
101102
publisher,
102103
version,
103-
compilerType,
104104
});
105105

106106
return deployContractfromDeployMetadata({
@@ -111,7 +111,6 @@ export async function deployPublishedContract(
111111
initializeParams: contractParams,
112112
implementationConstructorParams,
113113
salt,
114-
compilerType,
115114
});
116115
}
117116

@@ -130,7 +129,6 @@ export type DeployContractfromDeployMetadataOptions = {
130129
initializeParams?: Record<string, unknown>;
131130
}[];
132131
salt?: string;
133-
compilerType?: "solc" | "zksolc";
134132
};
135133

136134
/**
@@ -148,7 +146,6 @@ export async function deployContractfromDeployMetadata(
148146
implementationConstructorParams,
149147
modules,
150148
salt,
151-
compilerType,
152149
} = options;
153150
switch (deployMetadata?.deployType) {
154151
case "standard": {
@@ -182,7 +179,6 @@ export async function deployContractfromDeployMetadata(
182179
client,
183180
})),
184181
publisher: deployMetadata.publisher,
185-
compilerType,
186182
});
187183

188184
const initializeTransaction = await getInitializeTransaction({
@@ -272,7 +268,11 @@ async function directDeploy(options: {
272268
account,
273269
client,
274270
chain,
275-
bytecode: compilerMetadata.bytecode,
271+
bytecode: await fetchBytecodeFromCompilerMetadata({
272+
compilerMetadata,
273+
client,
274+
chain,
275+
}),
276276
abi: compilerMetadata.abi,
277277
params: contractParams,
278278
salt,
@@ -286,7 +286,11 @@ async function directDeploy(options: {
286286
account,
287287
client,
288288
chain,
289-
bytecode: compilerMetadata.bytecode,
289+
bytecode: await fetchBytecodeFromCompilerMetadata({
290+
compilerMetadata,
291+
client,
292+
chain,
293+
}),
290294
abi: compilerMetadata.abi,
291295
constructorParams: contractParams,
292296
salt,

packages/thirdweb/src/utils/any-evm/compute-published-contract-deploy-info.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import { encodeAbiParameters } from "../abi/encodeAbiParameters.js";
77
import { normalizeFunctionParams } from "../abi/normalizeFunctionParams.js";
88
import { ensureBytecodePrefix } from "../bytecode/prefix.js";
99
import type { Hex } from "../encoding/hex.js";
10-
import type { FetchDeployMetadataResult } from "./deploy-metadata.js";
10+
import {
11+
type FetchDeployMetadataResult,
12+
fetchBytecodeFromCompilerMetadata,
13+
} from "./deploy-metadata.js";
1114
import { getInitBytecodeWithSalt } from "./get-init-bytecode-with-salt.js";
1215

1316
/**
@@ -52,7 +55,11 @@ export async function computeDeploymentInfoFromMetadata(args: {
5255
client: args.client,
5356
chain: args.chain,
5457
abi: args.contractMetadata.abi,
55-
bytecode: args.contractMetadata.bytecode,
58+
bytecode: await fetchBytecodeFromCompilerMetadata({
59+
compilerMetadata: args.contractMetadata,
60+
client: args.client,
61+
chain: args.chain,
62+
}),
5663
constructorParams: args.constructorParams,
5764
salt: args.salt,
5865
});

packages/thirdweb/src/utils/any-evm/deploy-metadata.ts

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import type { Abi } from "abitype";
2+
import type { Chain } from "../../chains/types.js";
23
import type { ThirdwebClient } from "../../client/client.js";
34
import { formatCompilerMetadata } from "../../contract/actions/compiler-metadata.js";
45
import { download } from "../../storage/download.js";
56
import type { Hex } from "../encoding/hex.js";
7+
import { withCache } from "../promise/withCache.js";
68
import type { Prettify } from "../type-utils.js";
9+
import { isZkSyncChain } from "./zksync/isZkSyncChain.js";
710

811
type FetchDeployMetadataOptions = {
912
uri: string;
1013
client: ThirdwebClient;
11-
compilerType?: "solc" | "zksolc";
1214
};
1315

1416
export type FetchDeployMetadataResult = Partial<ExtendedMetadata> &
@@ -23,41 +25,21 @@ export type FetchDeployMetadataResult = Partial<ExtendedMetadata> &
2325
export async function fetchDeployMetadata(
2426
options: FetchDeployMetadataOptions,
2527
): Promise<FetchDeployMetadataResult> {
26-
const isZksolc = options.compilerType === "zksolc";
2728
const rawMeta: RawCompilerMetadata = await download({
2829
uri: options.uri,
2930
client: options.client,
3031
}).then((r) => r.json());
3132

32-
if (
33-
isZksolc &&
34-
(!rawMeta.compilers?.zksolc || rawMeta.compilers?.zksolc.length === 0)
35-
) {
36-
throw new Error(`No zksolc metadata found for contract: ${rawMeta.name}`);
37-
}
38-
39-
const metadataUri = isZksolc
40-
? rawMeta.compilers.zksolc[0].metadataUri
41-
: rawMeta.metadataUri;
42-
const bytecodeUri = isZksolc
43-
? rawMeta.compilers.zksolc[0].bytecodeUri
44-
: rawMeta.bytecodeUri;
45-
const [deployBytecode, parsedMeta] = await Promise.all([
46-
download({ uri: bytecodeUri, client: options.client }).then(
47-
(res) => res.text() as Promise<Hex>,
48-
),
49-
fetchAndParseCompilerMetadata({
50-
client: options.client,
51-
uri: metadataUri,
52-
compilerType: options.compilerType,
53-
}),
54-
]);
33+
const metadataUri = rawMeta.metadataUri;
34+
const parsedMeta = await fetchAndParseCompilerMetadata({
35+
client: options.client,
36+
uri: metadataUri,
37+
});
5538

5639
return {
5740
...rawMeta,
5841
...parsedMeta,
5942
version: rawMeta.version,
60-
bytecode: deployBytecode,
6143
name: rawMeta.name,
6244
};
6345
}
@@ -84,10 +66,42 @@ async function fetchAndParseCompilerMetadata(
8466
}
8567
return {
8668
...metadata,
87-
...formatCompilerMetadata(metadata, options.compilerType),
69+
...formatCompilerMetadata(metadata),
8870
};
8971
}
9072

73+
export async function fetchBytecodeFromCompilerMetadata(options: {
74+
compilerMetadata: FetchDeployMetadataResult;
75+
client: ThirdwebClient;
76+
chain: Chain;
77+
}) {
78+
const { compilerMetadata, client, chain } = options;
79+
return withCache(
80+
async () => {
81+
const isZksolc = await isZkSyncChain(chain);
82+
const bytecodeUri = isZksolc
83+
? compilerMetadata.compilers?.zksolc[0]?.bytecodeUri
84+
: compilerMetadata.bytecodeUri;
85+
86+
if (!bytecodeUri) {
87+
throw new Error(
88+
`No bytecode URI found in compiler metadata for ${compilerMetadata.name} on chain ${chain.name}`,
89+
);
90+
}
91+
const deployBytecode = await download({
92+
uri: bytecodeUri,
93+
client,
94+
}).then((res) => res.text() as Promise<Hex>);
95+
96+
return deployBytecode;
97+
},
98+
{
99+
cacheKey: `bytecode:${compilerMetadata.name}:${chain.id}`,
100+
cacheTime: 24 * 60 * 60 * 1000,
101+
},
102+
);
103+
}
104+
91105
// types
92106

93107
type RawCompilerMetadata = {
@@ -96,8 +110,8 @@ type RawCompilerMetadata = {
96110
bytecodeUri: string;
97111
// biome-ignore lint/suspicious/noExplicitAny: TODO: fix later
98112
analytics?: any;
99-
// biome-ignore lint/suspicious/noExplicitAny: TODO: fix later
100-
[key: string]: any;
113+
version?: string;
114+
[key: string]: unknown;
101115
};
102116

103117
type ParsedCompilerMetadata = {
@@ -146,10 +160,7 @@ type ParsedCompilerMetadata = {
146160
};
147161

148162
export type CompilerMetadata = Prettify<
149-
RawCompilerMetadata &
150-
ParsedCompilerMetadata & {
151-
bytecode: Hex;
152-
}
163+
RawCompilerMetadata & ParsedCompilerMetadata
153164
>;
154165

155166
export type ExtendedMetadata = {

packages/thirdweb/src/utils/any-evm/zksync/isZkSyncChain.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,21 @@ export async function isZkSyncChain(chain: Chain) {
66
return false;
77
}
88

9-
const stack = await getChainStack(chain.id).catch(() => {
10-
// fall back to checking against these zksync chain-ids
11-
if (
12-
chain.id === 324 ||
13-
chain.id === 300 ||
14-
chain.id === 302 ||
15-
chain.id === 11124 ||
16-
chain.id === 282 || // cronos zkevm testnet
17-
chain.id === 388 // cronos zkevm mainnet
18-
) {
19-
return "zksync-stack";
20-
}
9+
// check known zksync chain-ids first
10+
if (
11+
chain.id === 324 ||
12+
chain.id === 300 ||
13+
chain.id === 302 ||
14+
chain.id === 11124 ||
15+
chain.id === 282 || // cronos zkevm testnet
16+
chain.id === 388 // cronos zkevm mainnet
17+
) {
18+
return true;
19+
}
2120

21+
// fallback to checking the stack on rpc
22+
const stack = await getChainStack(chain.id).catch(() => {
23+
// dont throw if network check fails
2224
return "";
2325
});
2426

0 commit comments

Comments
 (0)