From 6bf92578ddb5298d307e2e6320d60e76decd848a Mon Sep 17 00:00:00 2001 From: Yash Date: Tue, 15 Apr 2025 13:42:18 +0530 Subject: [PATCH 1/3] Fix dynamic contract publish --- .../dynamic-contracts/IExtensionManager.json | 3 +- .../write/getAllExtensions.ts | 88 +++++++++++++++++++ .../src/extensions/thirdweb/write/publish.ts | 16 +++- 3 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 packages/thirdweb/src/extensions/dynamic-contracts/__generated__/IExtensionManager/write/getAllExtensions.ts diff --git a/packages/thirdweb/scripts/generate/abis/dynamic-contracts/IExtensionManager.json b/packages/thirdweb/scripts/generate/abis/dynamic-contracts/IExtensionManager.json index 8e6684149bc..3b4cbf585d1 100644 --- a/packages/thirdweb/scripts/generate/abis/dynamic-contracts/IExtensionManager.json +++ b/packages/thirdweb/scripts/generate/abis/dynamic-contracts/IExtensionManager.json @@ -1,4 +1,5 @@ [ "function addExtension(((string name, string metadataURI, address implementation) metadata, (bytes4 functionSelector, string functionSignature)[] functions) extension)", - "function removeExtension(string extensionName)" + "function removeExtension(string extensionName)", + "function getAllExtensions() returns (((string name, string metadataURI, address implementation) metadata, (bytes4 functionSelector, string functionSignature)[] functions)[])" ] \ No newline at end of file diff --git a/packages/thirdweb/src/extensions/dynamic-contracts/__generated__/IExtensionManager/write/getAllExtensions.ts b/packages/thirdweb/src/extensions/dynamic-contracts/__generated__/IExtensionManager/write/getAllExtensions.ts new file mode 100644 index 00000000000..ef5489723ee --- /dev/null +++ b/packages/thirdweb/src/extensions/dynamic-contracts/__generated__/IExtensionManager/write/getAllExtensions.ts @@ -0,0 +1,88 @@ +import type { BaseTransactionOptions } from "../../../../../transaction/types.js"; +import { prepareContractCall } from "../../../../../transaction/prepare-contract-call.js"; + +import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js"; + +export const FN_SELECTOR = "0x4a00cc48" as const; +const FN_INPUTS = [] as const; +const FN_OUTPUTS = [ + { + type: "tuple[]", + components: [ + { + type: "tuple", + name: "metadata", + components: [ + { + type: "string", + name: "name", + }, + { + type: "string", + name: "metadataURI", + }, + { + type: "address", + name: "implementation", + }, + ], + }, + { + type: "tuple[]", + name: "functions", + components: [ + { + type: "bytes4", + name: "functionSelector", + }, + { + type: "string", + name: "functionSignature", + }, + ], + }, + ], + }, +] as const; + +/** + * Checks if the `getAllExtensions` method is supported by the given contract. + * @param availableSelectors An array of 4byte function selectors of the contract. You can get this in various ways, such as using "whatsabi" or if you have the ABI of the contract available you can use it to generate the selectors. + * @returns A boolean indicating if the `getAllExtensions` method is supported. + * @extension DYNAMIC-CONTRACTS + * @example + * ```ts + * import { isGetAllExtensionsSupported } from "thirdweb/extensions/dynamic-contracts"; + * + * const supported = isGetAllExtensionsSupported(["0x..."]); + * ``` + */ +export function isGetAllExtensionsSupported(availableSelectors: string[]) { + return detectMethod({ + availableSelectors, + method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const, + }); +} + +/** + * Prepares a transaction to call the "getAllExtensions" function on the contract. + * @param options - The options for the "getAllExtensions" function. + * @returns A prepared transaction object. + * @extension DYNAMIC-CONTRACTS + * @example + * ```ts + * import { sendTransaction } from "thirdweb"; + * import { getAllExtensions } from "thirdweb/extensions/dynamic-contracts"; + * + * const transaction = getAllExtensions(); + * + * // Send the transaction + * await sendTransaction({ transaction, account }); + * ``` + */ +export function getAllExtensions(options: BaseTransactionOptions) { + return prepareContractCall({ + contract: options.contract, + method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const, + }); +} diff --git a/packages/thirdweb/src/extensions/thirdweb/write/publish.ts b/packages/thirdweb/src/extensions/thirdweb/write/publish.ts index 5ae855d6719..cd3590d7334 100644 --- a/packages/thirdweb/src/extensions/thirdweb/write/publish.ts +++ b/packages/thirdweb/src/extensions/thirdweb/write/publish.ts @@ -1,4 +1,5 @@ import type { Abi } from "abitype"; +import { isGetAllExtensionsSupported } from "src/extensions/dynamic-contracts/__generated__/IExtensionManager/write/getAllExtensions.js"; import { encodePacked, keccak256, toFunctionSelector } from "viem/utils"; import { polygon } from "../../../chains/chain-definitions/polygon.js"; import type { ThirdwebClient } from "../../../client/client.js"; @@ -79,8 +80,14 @@ export function publishContract( compositeAbi: options.metadata.compositeAbi, constructorParams: options.metadata.constructorParams, implConstructorParams: options.metadata.implConstructorParams, - defaultExtensions: options.metadata.defaultExtensions, - defaultModules: options.metadata.defaultModules, + defaultExtensions: + routerType === "dynamic" + ? options.metadata.defaultExtensions + : undefined, + defaultModules: + routerType === "modular" + ? options.metadata.defaultModules + : undefined, deployType: options.metadata.deployType, description: options.metadata.description, displayName: options.metadata.displayName, @@ -131,6 +138,7 @@ function getRouterType(abi: Abi) { .filter((f) => f.type === "function") .map((f) => toFunctionSelector(f)); const isModule = isGetInstalledModulesSupported(fnSelectors); - // TODO add dynamic detection - return isModule ? "modular" : "none"; + const isDynamic = isGetAllExtensionsSupported(fnSelectors); + + return isModule ? "modular" : isDynamic ? "dynamic" : "none"; } From fc1a8c2f887ac7efea055dfbaaeef91f2bc561ef Mon Sep 17 00:00:00 2001 From: Yash Date: Tue, 15 Apr 2025 13:45:24 +0530 Subject: [PATCH 2/3] lint --- packages/thirdweb/src/extensions/thirdweb/write/publish.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/thirdweb/src/extensions/thirdweb/write/publish.ts b/packages/thirdweb/src/extensions/thirdweb/write/publish.ts index cd3590d7334..f7a1dec7137 100644 --- a/packages/thirdweb/src/extensions/thirdweb/write/publish.ts +++ b/packages/thirdweb/src/extensions/thirdweb/write/publish.ts @@ -1,11 +1,11 @@ import type { Abi } from "abitype"; -import { isGetAllExtensionsSupported } from "src/extensions/dynamic-contracts/__generated__/IExtensionManager/write/getAllExtensions.js"; import { encodePacked, keccak256, toFunctionSelector } from "viem/utils"; import { polygon } from "../../../chains/chain-definitions/polygon.js"; import type { ThirdwebClient } from "../../../client/client.js"; import { ZERO_ADDRESS } from "../../../constants/addresses.js"; import { getContract } from "../../../contract/contract.js"; import { CONTRACT_PUBLISHER_ADDRESS } from "../../../contract/deployment/publisher.js"; +import { isGetAllExtensionsSupported } from "../../../extensions/dynamic-contracts/__generated__/IExtensionManager/write/getAllExtensions.js"; import { download } from "../../../storage/download.js"; import { upload } from "../../../storage/upload.js"; import type { BaseTransactionOptions } from "../../../transaction/types.js"; From 23c21533de49aad79e968cc948c7677411207ff6 Mon Sep 17 00:00:00 2001 From: Yash Date: Tue, 15 Apr 2025 13:50:46 +0530 Subject: [PATCH 3/3] correct function type --- .../dynamic-contracts/IExtensionManager.json | 2 +- .../{write => read}/getAllExtensions.ts | 38 +++++++++++++------ .../src/extensions/thirdweb/write/publish.ts | 2 +- 3 files changed, 29 insertions(+), 13 deletions(-) rename packages/thirdweb/src/extensions/dynamic-contracts/__generated__/IExtensionManager/{write => read}/getAllExtensions.ts (65%) diff --git a/packages/thirdweb/scripts/generate/abis/dynamic-contracts/IExtensionManager.json b/packages/thirdweb/scripts/generate/abis/dynamic-contracts/IExtensionManager.json index 3b4cbf585d1..eef8b474805 100644 --- a/packages/thirdweb/scripts/generate/abis/dynamic-contracts/IExtensionManager.json +++ b/packages/thirdweb/scripts/generate/abis/dynamic-contracts/IExtensionManager.json @@ -1,5 +1,5 @@ [ "function addExtension(((string name, string metadataURI, address implementation) metadata, (bytes4 functionSelector, string functionSignature)[] functions) extension)", "function removeExtension(string extensionName)", - "function getAllExtensions() returns (((string name, string metadataURI, address implementation) metadata, (bytes4 functionSelector, string functionSignature)[] functions)[])" + "function getAllExtensions() view returns (((string name, string metadataURI, address implementation) metadata, (bytes4 functionSelector, string functionSignature)[] functions)[])" ] \ No newline at end of file diff --git a/packages/thirdweb/src/extensions/dynamic-contracts/__generated__/IExtensionManager/write/getAllExtensions.ts b/packages/thirdweb/src/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.ts similarity index 65% rename from packages/thirdweb/src/extensions/dynamic-contracts/__generated__/IExtensionManager/write/getAllExtensions.ts rename to packages/thirdweb/src/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.ts index ef5489723ee..e3a8808253c 100644 --- a/packages/thirdweb/src/extensions/dynamic-contracts/__generated__/IExtensionManager/write/getAllExtensions.ts +++ b/packages/thirdweb/src/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.ts @@ -1,6 +1,8 @@ +import { readContract } from "../../../../../transaction/read-contract.js"; import type { BaseTransactionOptions } from "../../../../../transaction/types.js"; -import { prepareContractCall } from "../../../../../transaction/prepare-contract-call.js"; +import { decodeAbiParameters } from "viem"; +import type { Hex } from "../../../../../utils/encoding/hex.js"; import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js"; export const FN_SELECTOR = "0x4a00cc48" as const; @@ -53,7 +55,6 @@ const FN_OUTPUTS = [ * @example * ```ts * import { isGetAllExtensionsSupported } from "thirdweb/extensions/dynamic-contracts"; - * * const supported = isGetAllExtensionsSupported(["0x..."]); * ``` */ @@ -65,24 +66,39 @@ export function isGetAllExtensionsSupported(availableSelectors: string[]) { } /** - * Prepares a transaction to call the "getAllExtensions" function on the contract. - * @param options - The options for the "getAllExtensions" function. - * @returns A prepared transaction object. + * Decodes the result of the getAllExtensions function call. + * @param result - The hexadecimal result to decode. + * @returns The decoded result as per the FN_OUTPUTS definition. + * @extension DYNAMIC-CONTRACTS + * @example + * ```ts + * import { decodeGetAllExtensionsResult } from "thirdweb/extensions/dynamic-contracts"; + * const result = decodeGetAllExtensionsResultResult("..."); + * ``` + */ +export function decodeGetAllExtensionsResult(result: Hex) { + return decodeAbiParameters(FN_OUTPUTS, result)[0]; +} + +/** + * Calls the "getAllExtensions" function on the contract. + * @param options - The options for the getAllExtensions function. + * @returns The parsed result of the function call. * @extension DYNAMIC-CONTRACTS * @example * ```ts - * import { sendTransaction } from "thirdweb"; * import { getAllExtensions } from "thirdweb/extensions/dynamic-contracts"; * - * const transaction = getAllExtensions(); + * const result = await getAllExtensions({ + * contract, + * }); * - * // Send the transaction - * await sendTransaction({ transaction, account }); * ``` */ -export function getAllExtensions(options: BaseTransactionOptions) { - return prepareContractCall({ +export async function getAllExtensions(options: BaseTransactionOptions) { + return readContract({ contract: options.contract, method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const, + params: [], }); } diff --git a/packages/thirdweb/src/extensions/thirdweb/write/publish.ts b/packages/thirdweb/src/extensions/thirdweb/write/publish.ts index f7a1dec7137..49bf3a13c14 100644 --- a/packages/thirdweb/src/extensions/thirdweb/write/publish.ts +++ b/packages/thirdweb/src/extensions/thirdweb/write/publish.ts @@ -5,7 +5,7 @@ import type { ThirdwebClient } from "../../../client/client.js"; import { ZERO_ADDRESS } from "../../../constants/addresses.js"; import { getContract } from "../../../contract/contract.js"; import { CONTRACT_PUBLISHER_ADDRESS } from "../../../contract/deployment/publisher.js"; -import { isGetAllExtensionsSupported } from "../../../extensions/dynamic-contracts/__generated__/IExtensionManager/write/getAllExtensions.js"; +import { isGetAllExtensionsSupported } from "../../../extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.js"; import { download } from "../../../storage/download.js"; import { upload } from "../../../storage/upload.js"; import type { BaseTransactionOptions } from "../../../transaction/types.js";