Skip to content

Commit ef3ca89

Browse files
committed
Compute addresses with ref contracts
1 parent 2fccfc0 commit ef3ca89

File tree

2 files changed

+173
-1
lines changed

2 files changed

+173
-1
lines changed
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import type { Chain } from "../../chains/types.js";
2+
import type { ThirdwebClient } from "../../client/client.js";
3+
import { encodeAbiParameters } from "../../utils/abi/encodeAbiParameters.js";
4+
import { computePublishedContractAddress } from "../../utils/any-evm/compute-published-contract-address.js";
5+
import type { ImplementationConstructorParam } from "./process-ref-deployments.js";
6+
7+
type ComputeRefDeploymentsOptions = {
8+
client: ThirdwebClient;
9+
chain: Chain;
10+
paramValue: string | ImplementationConstructorParam;
11+
};
12+
13+
export async function computeRefDeployments(
14+
options: ComputeRefDeploymentsOptions,
15+
): Promise<string | string[]> {
16+
const { client, chain, paramValue } = options;
17+
18+
if (typeof paramValue === "object") {
19+
if (
20+
"defaultValue" in paramValue &&
21+
paramValue.defaultValue &&
22+
paramValue.defaultValue.length > 0
23+
) {
24+
return paramValue.defaultValue;
25+
}
26+
27+
if ("dynamicValue" in paramValue && paramValue.dynamicValue) {
28+
const dynamicValue = paramValue.dynamicValue;
29+
const contracts = dynamicValue.refContracts;
30+
31+
if (dynamicValue.type === "address") {
32+
if (!contracts || contracts.length === 0 || !contracts[0]?.contractId) {
33+
throw new Error("Invalid or empty param value");
34+
}
35+
const salt =
36+
contracts[0]?.salt && contracts[0]?.salt.length > 0
37+
? contracts[0]?.salt
38+
: "thirdweb";
39+
40+
const addr = await computePublishedContractAddress({
41+
client,
42+
chain,
43+
contractId: contracts[0]?.contractId,
44+
publisher: contracts[0]?.publisherAddress,
45+
version: contracts[0]?.version,
46+
salt,
47+
});
48+
49+
return addr;
50+
}
51+
52+
if (dynamicValue.type === "address[]") {
53+
if (!contracts || contracts.length === 0) {
54+
throw new Error("Invalid or empty param value");
55+
}
56+
const addressArray: string[] = [];
57+
58+
for (const c of contracts) {
59+
const salt = c?.salt && c?.salt.length > 0 ? c?.salt : "thirdweb";
60+
61+
addressArray.push(
62+
await computePublishedContractAddress({
63+
client,
64+
chain,
65+
contractId: c.contractId,
66+
publisher: c.publisherAddress,
67+
version: c.version,
68+
salt,
69+
}),
70+
);
71+
}
72+
73+
return addressArray;
74+
}
75+
76+
if (dynamicValue.type === "bytes") {
77+
if (!dynamicValue.paramsToEncode) {
78+
throw new Error("Invalid or empty param value");
79+
}
80+
const paramsToEncode = dynamicValue.paramsToEncode[0];
81+
82+
if (paramsToEncode) {
83+
const types: string[] = [];
84+
const values: (string | string[])[] = [];
85+
for (const v of paramsToEncode) {
86+
types.push(v.type);
87+
88+
if (v.defaultValue) {
89+
values.push(v.defaultValue);
90+
} else if (v.dynamicValue) {
91+
values.push(
92+
await computeRefDeployments({
93+
client,
94+
chain,
95+
paramValue: v,
96+
}),
97+
);
98+
}
99+
}
100+
101+
return encodeAbiParameters(
102+
types.map((t) => {
103+
return { type: t };
104+
}),
105+
values,
106+
);
107+
}
108+
}
109+
110+
if (dynamicValue.type === "bytes[]") {
111+
if (!dynamicValue.paramsToEncode) {
112+
throw new Error("Invalid or empty param value");
113+
}
114+
const bytesArray: string[] = [];
115+
const paramArray = dynamicValue.paramsToEncode;
116+
117+
for (const a of paramArray) {
118+
const paramsToEncode = a;
119+
120+
if (paramsToEncode) {
121+
const types: string[] = [];
122+
const values: (string | string[])[] = [];
123+
for (const v of paramsToEncode) {
124+
types.push(v.type);
125+
126+
if (v.defaultValue) {
127+
values.push(v.defaultValue);
128+
} else if (v.dynamicValue) {
129+
values.push(
130+
await computeRefDeployments({
131+
client,
132+
chain,
133+
paramValue: v,
134+
}),
135+
);
136+
}
137+
}
138+
139+
bytesArray.push(
140+
encodeAbiParameters(
141+
types.map((t) => {
142+
return { type: t };
143+
}),
144+
values,
145+
),
146+
);
147+
}
148+
}
149+
150+
return bytesArray;
151+
}
152+
}
153+
}
154+
155+
return paramValue as string;
156+
}

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import type { Chain } from "../../chains/types.js";
33
import type { ThirdwebClient } from "../../client/client.js";
44
import { fetchPublishedContractMetadata } from "../../contract/deployment/publisher.js";
55
import { computeCreate2FactoryAddress } from "../../contract/deployment/utils/create-2-factory.js";
6+
import { computeRefDeployments } from "../../extensions/prebuilts/compute-ref-deployments.js";
7+
import type { ImplementationConstructorParam } from "../../extensions/prebuilts/process-ref-deployments.js";
68
import { encodeAbiParameters } from "../abi/encodeAbiParameters.js";
79
import { normalizeFunctionParams } from "../abi/normalizeFunctionParams.js";
810
import { ensureBytecodePrefix } from "../bytecode/prefix.js";
@@ -51,6 +53,20 @@ export async function computeDeploymentInfoFromMetadata(args: {
5153
constructorParams?: Record<string, unknown>;
5254
salt?: string;
5355
}) {
56+
const { client, chain, constructorParams, contractMetadata } = args;
57+
const definedConstructorParams =
58+
constructorParams || contractMetadata.constructorParams;
59+
const processedConstructorParams: Record<string, string | string[]> = {};
60+
for (const key in definedConstructorParams) {
61+
processedConstructorParams[key] = await computeRefDeployments({
62+
client,
63+
chain,
64+
paramValue: definedConstructorParams[key] as
65+
| string
66+
| ImplementationConstructorParam,
67+
});
68+
}
69+
5470
return computeDeploymentInfoFromBytecode({
5571
client: args.client,
5672
chain: args.chain,
@@ -60,7 +76,7 @@ export async function computeDeploymentInfoFromMetadata(args: {
6076
client: args.client,
6177
chain: args.chain,
6278
}),
63-
constructorParams: args.constructorParams,
79+
constructorParams: processedConstructorParams,
6480
salt: args.salt,
6581
});
6682
}

0 commit comments

Comments
 (0)