Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compute addresses with ref contracts #5699

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fresh-gorillas-sip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"thirdweb": patch
---

Compute addresses with ref contracts
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import type { Chain } from "../../chains/types.js";
import type { ThirdwebClient } from "../../client/client.js";
import { encodeAbiParameters } from "../../utils/abi/encodeAbiParameters.js";
import { computePublishedContractAddress } from "../../utils/any-evm/compute-published-contract-address.js";
import type { ImplementationConstructorParam } from "./process-ref-deployments.js";

type ComputeRefDeploymentsOptions = {
client: ThirdwebClient;
chain: Chain;
paramValue: string | ImplementationConstructorParam;
};

/**
* Computes addresses for published contract references in constructor params.
* @returns Param value after processing references.
* @internal
*/
export async function computeRefDeployments(
options: ComputeRefDeploymentsOptions,
): Promise<string | string[]> {
joaquim-verges marked this conversation as resolved.
Show resolved Hide resolved
const { client, chain, paramValue } = options;

if (typeof paramValue === "object") {
if (
"defaultValue" in paramValue &&
paramValue.defaultValue &&
paramValue.defaultValue.length > 0
) {
return paramValue.defaultValue;
}

if ("dynamicValue" in paramValue && paramValue.dynamicValue) {
const dynamicValue = paramValue.dynamicValue;
const contracts = dynamicValue.refContracts;

Check warning on line 34 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L33-L34

Added lines #L33 - L34 were not covered by tests

if (dynamicValue.type === "address") {
if (!contracts || contracts.length === 0 || !contracts[0]?.contractId) {
throw new Error("Invalid or empty param value");
}
const salt =
contracts[0]?.salt && contracts[0]?.salt.length > 0
? contracts[0]?.salt
: "thirdweb";

Check warning on line 43 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L36-L43

Added lines #L36 - L43 were not covered by tests

const addr = await computePublishedContractAddress({
client,
chain,
contractId: contracts[0]?.contractId,
publisher: contracts[0]?.publisherAddress,
version: contracts[0]?.version,
salt,
});

Check warning on line 52 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L45-L52

Added lines #L45 - L52 were not covered by tests

return addr;
}

Check warning on line 55 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L54-L55

Added lines #L54 - L55 were not covered by tests

if (dynamicValue.type === "address[]") {
if (!contracts || contracts.length === 0) {
throw new Error("Invalid or empty param value");
}
const addressArray: string[] = [];

Check warning on line 61 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L57-L61

Added lines #L57 - L61 were not covered by tests

for (const c of contracts) {
const salt = c?.salt && c?.salt.length > 0 ? c?.salt : "thirdweb";

Check warning on line 64 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L63-L64

Added lines #L63 - L64 were not covered by tests

addressArray.push(
await computePublishedContractAddress({
client,
chain,
contractId: c.contractId,
publisher: c.publisherAddress,
version: c.version,
salt,
}),
);
}

Check warning on line 76 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L66-L76

Added lines #L66 - L76 were not covered by tests

return addressArray;
}

Check warning on line 79 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L78-L79

Added lines #L78 - L79 were not covered by tests

if (dynamicValue.type === "bytes") {
if (!dynamicValue.paramsToEncode) {
throw new Error("Invalid or empty param value");
}
const paramsToEncode = dynamicValue.paramsToEncode[0];

Check warning on line 85 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L81-L85

Added lines #L81 - L85 were not covered by tests

if (paramsToEncode) {
const types: string[] = [];
const values: (string | string[])[] = [];
for (const v of paramsToEncode) {
types.push(v.type);

Check warning on line 91 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L87-L91

Added lines #L87 - L91 were not covered by tests

if (v.defaultValue) {
values.push(v.defaultValue);
} else if (v.dynamicValue) {
values.push(
await computeRefDeployments({
client,
chain,
paramValue: v,
}),
);
}
}

Check warning on line 104 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L93-L104

Added lines #L93 - L104 were not covered by tests

return encodeAbiParameters(
types.map((t) => {
return { type: t };
}),
values,
);
}
}

Check warning on line 113 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L106-L113

Added lines #L106 - L113 were not covered by tests

if (dynamicValue.type === "bytes[]") {
if (!dynamicValue.paramsToEncode) {
throw new Error("Invalid or empty param value");
}
const bytesArray: string[] = [];
const paramArray = dynamicValue.paramsToEncode;

Check warning on line 120 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L115-L120

Added lines #L115 - L120 were not covered by tests

for (const a of paramArray) {
const paramsToEncode = a;

Check warning on line 123 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L122-L123

Added lines #L122 - L123 were not covered by tests

if (paramsToEncode) {
const types: string[] = [];
const values: (string | string[])[] = [];
for (const v of paramsToEncode) {
types.push(v.type);

Check warning on line 129 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L125-L129

Added lines #L125 - L129 were not covered by tests

if (v.defaultValue) {
values.push(v.defaultValue);
} else if (v.dynamicValue) {
values.push(
await computeRefDeployments({
client,
chain,
paramValue: v,
}),
);
}
}

Check warning on line 142 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L131-L142

Added lines #L131 - L142 were not covered by tests

bytesArray.push(
encodeAbiParameters(
types.map((t) => {
return { type: t };
}),
values,
),
);
}
}

Check warning on line 153 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L144-L153

Added lines #L144 - L153 were not covered by tests

return bytesArray;
}
}

Check warning on line 157 in packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/extensions/prebuilts/compute-ref-deployments.ts#L155-L157

Added lines #L155 - L157 were not covered by tests
}

return paramValue as string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ type ProcessRefDeploymentsOptions = {
paramValue: string | ImplementationConstructorParam;
};

/**
* Processes published contract references in constructor params. Deploys recursively if needed.
* @returns Param value after processing references.
* @internal
*/
export async function processRefDeployments(
options: ProcessRefDeploymentsOptions,
): Promise<string | string[]> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import type { Chain } from "../../chains/types.js";
import type { ThirdwebClient } from "../../client/client.js";
import { fetchPublishedContractMetadata } from "../../contract/deployment/publisher.js";
import { computeCreate2FactoryAddress } from "../../contract/deployment/utils/create-2-factory.js";
import { computeRefDeployments } from "../../extensions/prebuilts/compute-ref-deployments.js";
import type { ImplementationConstructorParam } from "../../extensions/prebuilts/process-ref-deployments.js";
import { encodeAbiParameters } from "../abi/encodeAbiParameters.js";
import { normalizeFunctionParams } from "../abi/normalizeFunctionParams.js";
import { ensureBytecodePrefix } from "../bytecode/prefix.js";
Expand Down Expand Up @@ -51,6 +53,20 @@ export async function computeDeploymentInfoFromMetadata(args: {
constructorParams?: Record<string, unknown>;
salt?: string;
}) {
const { client, chain, constructorParams, contractMetadata } = args;
const definedConstructorParams =
constructorParams || contractMetadata.constructorParams;
const processedConstructorParams: Record<string, string | string[]> = {};
for (const key in definedConstructorParams) {
processedConstructorParams[key] = await computeRefDeployments({
client,
chain,
paramValue: definedConstructorParams[key] as
| string
| ImplementationConstructorParam,
});
}

return computeDeploymentInfoFromBytecode({
client: args.client,
chain: args.chain,
Expand All @@ -60,7 +76,7 @@ export async function computeDeploymentInfoFromMetadata(args: {
client: args.client,
chain: args.chain,
}),
constructorParams: args.constructorParams,
constructorParams: processedConstructorParams,
salt: args.salt,
});
}
Expand Down
Loading