Skip to content

Commit

Permalink
[sdk] - properly parse ABIs (thirdweb-dev#782)
Browse files Browse the repository at this point in the history
  • Loading branch information
jnsdls authored Mar 21, 2023
1 parent d1e2d5f commit d8c1c94
Show file tree
Hide file tree
Showing 18 changed files with 94 additions and 63 deletions.
5 changes: 5 additions & 0 deletions .changeset/plenty-spoons-lay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@thirdweb-dev/sdk": patch
---

parse ABIs correctly (knowing function names can be empty strings)
39 changes: 23 additions & 16 deletions packages/sdk/src/evm/common/feature-detection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
Abi,
AbiEvent,
AbiFunction,
AbiInput,
AbiSchema,
AbiTypeSchema,
FullPublishMetadata,
Expand All @@ -31,7 +32,7 @@ import { z } from "zod";
* @param abi
* @param feature
*/
function matchesAbiInterface(abi: Abi, feature: Feature): boolean {
function matchesAbiInterface(abi: AbiInput, feature: Feature): boolean {
// returns true if all the functions in `interfaceToMatch` are found in `contract` (removing any duplicates)
return hasMatchingAbi(abi, feature.abis);
}
Expand All @@ -44,9 +45,9 @@ function matchesAbiInterface(abi: Abi, feature: Feature): boolean {
*/
export function matchesPrebuiltAbi<T extends BaseContract>(
contractWrapper: ContractWrapper<BaseContract>,
abi: Abi,
abi: AbiInput,
): contractWrapper is ContractWrapper<T> {
return hasMatchingAbi(contractWrapper.abi as Abi, [abi]);
return hasMatchingAbi(AbiSchema.parse(contractWrapper.abi || []), [abi]);
}

/**
Expand All @@ -55,7 +56,10 @@ export function matchesPrebuiltAbi<T extends BaseContract>(
* @param featureAbis
* @returns
*/
export function hasMatchingAbi(contractAbi: Abi, featureAbis: readonly Abi[]) {
export function hasMatchingAbi(
contractAbi: AbiInput,
featureAbis: readonly AbiInput[],
) {
const contractFn = extractFunctionsFromAbi(contractAbi);
const interfaceFn = featureAbis.flatMap((i: any) =>
extractFunctionsFromAbi(i),
Expand Down Expand Up @@ -139,10 +143,9 @@ function extractCommentFromMetadata(
* @returns
* @internal
*/
export function extractConstructorParamsFromAbi(
abi: z.input<typeof AbiSchema>,
) {
for (const input of abi) {
export function extractConstructorParamsFromAbi(abi: AbiInput) {
const parsedAbi = AbiSchema.parse(abi || []);
for (const input of parsedAbi) {
if (input.type === "constructor") {
return input.inputs || [];
}
Expand All @@ -158,10 +161,11 @@ export function extractConstructorParamsFromAbi(
* @internal
*/
export function extractFunctionParamsFromAbi(
abi: z.input<typeof AbiSchema>,
abi: AbiInput,
functionName: string,
) {
for (const input of abi) {
const parsedAbi = AbiSchema.parse(abi || []);
for (const input of parsedAbi) {
if (input.type === "function" && input.name === functionName) {
return input.inputs || [];
}
Expand All @@ -175,10 +179,11 @@ export function extractFunctionParamsFromAbi(
* @param metadata
*/
export function extractFunctionsFromAbi(
abi: Abi,
abi: AbiInput,
metadata?: Record<string, any>,
): AbiFunction[] {
const functions = (abi || []).filter((el) => el.type === "function");
const parsedAbi = AbiSchema.parse(abi || []);
const functions = parsedAbi.filter((el) => el.type === "function");

const parsed: AbiFunction[] = [];
for (const f of functions) {
Expand Down Expand Up @@ -208,10 +213,11 @@ export function extractFunctionsFromAbi(
* @param metadata
*/
export function extractEventsFromAbi(
abi: Abi,
abi: AbiInput,
metadata?: Record<string, any>,
): AbiEvent[] {
const events = (abi || []).filter((el) => el.type === "event");
const parsedAbi = AbiSchema.parse(abi || []);
const events = parsedAbi.filter((el) => el.type === "event");
const parsed: AbiEvent[] = [];
for (const e of events) {
const doc = extractCommentFromMetadata(e.name, metadata, "events");
Expand Down Expand Up @@ -533,10 +539,11 @@ export function getAllDetectedFeatureNames(abi: Abi): string[] {
* @param featureName
*/
export function isFeatureEnabled(
abi: z.input<typeof AbiSchema>,
abi: AbiInput,
featureName: FeatureName,
): boolean {
const features = detectFeatures(abi);
const parsedAbi = AbiSchema.parse(abi || []);
const features = detectFeatures(parsedAbi);
return _featureEnabled(features, featureName);
}

Expand Down
10 changes: 6 additions & 4 deletions packages/sdk/src/evm/contracts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
TokenErc721ContractSchema,
VoteContractSchema,
} from "../schema";
import { Abi } from "../schema/contracts/custom";
import { Abi, AbiSchema } from "../schema/contracts/custom";
import { DropErc20ContractSchema } from "../schema/contracts/drop-erc20";
import { MultiwrapContractSchema } from "../schema/contracts/multiwrap";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
Expand Down Expand Up @@ -201,7 +201,7 @@ export const MarketplaceV3Initializer = {
).default;
return await getCompositePluginABI(
address,
localAbi,
AbiSchema.parse(localAbi || []),
provider,
{},
storage,
Expand Down Expand Up @@ -370,8 +370,10 @@ export const PackInitializer = {
return abi;
}
// Deprecated - only needed for backwards compatibility with non-published contracts - should remove in v4
return (await import("@thirdweb-dev/contracts-js/dist/abis/Pack.json"))
.default;
return AbiSchema.parse(
(await import("@thirdweb-dev/contracts-js/dist/abis/Pack.json"))
.default || [],
);
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { Transaction } from "../../core/classes/transactions";
import { NetworkInput, TransactionResultWithId } from "../../core/types";
import { PaperCheckout } from "../../integrations/thirdweb-checkout";
import { Address, AddressOrEns } from "../../schema";
import { Abi } from "../../schema/contracts/custom";
import { Abi, AbiInput, AbiSchema } from "../../schema/contracts/custom";
import { DropErc1155ContractSchema } from "../../schema/contracts/drop-erc1155";
import { SDKOptions } from "../../schema/sdk-options";
import { PrebuiltEditionDrop } from "../../types/eips";
Expand Down Expand Up @@ -124,7 +124,7 @@ export class EditionDrop extends StandardErc1155<PrebuiltEditionDrop> {
address: string,
storage: ThirdwebStorage,
options: SDKOptions = {},
abi: Abi,
abi: AbiInput,
chainId: number,
contractWrapper = new ContractWrapper<PrebuiltEditionDrop>(
network,
Expand All @@ -134,7 +134,7 @@ export class EditionDrop extends StandardErc1155<PrebuiltEditionDrop> {
),
) {
super(contractWrapper, storage, chainId);
this.abi = abi;
this.abi = AbiSchema.parse(abi);
this.metadata = new ContractMetadata(
this.contractWrapper,
DropErc1155ContractSchema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { GasCostEstimator } from "../../core/classes/gas-cost-estimator";
import { Transaction } from "../../core/classes/transactions";
import { NetworkInput, TransactionResultWithId } from "../../core/types";
import { Address, AddressOrEns } from "../../schema";
import { Abi } from "../../schema/contracts/custom";
import { Abi, AbiInput, AbiSchema } from "../../schema/contracts/custom";
import { TokenErc1155ContractSchema } from "../../schema/contracts/token-erc1155";
import { SDKOptions } from "../../schema/sdk-options";
import { EditionMetadataOrUri } from "../../schema/tokens/edition";
Expand Down Expand Up @@ -105,7 +105,7 @@ export class Edition extends StandardErc1155<TokenERC1155> {
address: string,
storage: ThirdwebStorage,
options: SDKOptions = {},
abi: Abi,
abi: AbiInput,
chainId: number,
contractWrapper = new ContractWrapper<TokenERC1155>(
network,
Expand All @@ -115,7 +115,7 @@ export class Edition extends StandardErc1155<TokenERC1155> {
),
) {
super(contractWrapper, storage, chainId);
this.abi = abi;
this.abi = AbiSchema.parse(abi || []);
this.metadata = new ContractMetadata(
this.contractWrapper,
TokenErc1155ContractSchema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { Transaction } from "../../core/classes/transactions";
import { UpdateableNetwork } from "../../core/interfaces/contract";
import { NetworkInput } from "../../core/types";
import { ListingType } from "../../enums";
import { Abi } from "../../schema/contracts/custom";
import { Abi, AbiInput, AbiSchema } from "../../schema/contracts/custom";
import { MarketplaceContractSchema } from "../../schema/contracts/marketplace";
import { SDKOptions } from "../../schema/sdk-options";
import { AddressOrEns } from "../../schema/shared";
Expand Down Expand Up @@ -153,7 +153,7 @@ export class Marketplace implements UpdateableNetwork {
address: string,
storage: ThirdwebStorage,
options: SDKOptions = {},
abi: Abi,
abi: AbiInput,
chainId: number,
contractWrapper = new ContractWrapper<MarketplaceContract>(
network,
Expand All @@ -163,7 +163,7 @@ export class Marketplace implements UpdateableNetwork {
),
) {
this._chainId = chainId;
this.abi = abi;
this.abi = AbiSchema.parse(abi || []);
this.contractWrapper = contractWrapper;
this.storage = storage;
this.metadata = new ContractMetadata(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { MarketplaceV3Offers } from "../../core/classes/marketplacev3-offers";
import { Transaction } from "../../core/classes/transactions";
import { UpdateableNetwork } from "../../core/interfaces/contract";
import { NetworkInput } from "../../core/types";
import { Abi } from "../../schema/contracts/custom";
import { Abi, AbiInput, AbiSchema } from "../../schema/contracts/custom";
import { MarketplaceContractSchema } from "../../schema/contracts/marketplace";
import { SDKOptions } from "../../schema/sdk-options";
import { Address } from "../../schema/shared";
Expand Down Expand Up @@ -205,7 +205,7 @@ export class MarketplaceV3 implements UpdateableNetwork {
address: string,
storage: ThirdwebStorage,
options: SDKOptions = {},
abi: Abi,
abi: AbiInput,
chainId: number,
contractWrapper = new ContractWrapper<MarketplaceV3Contract>(
network,
Expand All @@ -215,7 +215,7 @@ export class MarketplaceV3 implements UpdateableNetwork {
),
) {
this._chainId = chainId;
this.abi = abi;
this.abi = AbiSchema.parse(abi || []);
this.contractWrapper = contractWrapper;
this.storage = storage;
this.metadata = new ContractMetadata(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ import { StandardErc721 } from "../../core/classes/erc-721-standard";
import { GasCostEstimator } from "../../core/classes/gas-cost-estimator";
import { Transaction } from "../../core/classes/transactions";
import { NetworkInput, TransactionResultWithId } from "../../core/types";
import { Abi, AddressOrEns, SDKOptions } from "../../schema";
import {
Abi,
AbiInput,
AbiSchema,
AddressOrEns,
SDKOptions,
} from "../../schema";
import { MultiwrapContractSchema } from "../../schema/contracts/multiwrap";
import {
ERC1155Wrappable,
Expand Down Expand Up @@ -102,7 +108,7 @@ export class Multiwrap extends StandardErc721<MultiwrapContract> {
address: string,
storage: ThirdwebStorage,
options: SDKOptions = {},
abi: Abi,
abi: AbiInput,
chainId: number,
contractWrapper = new ContractWrapper<MultiwrapContract>(
network,
Expand All @@ -113,7 +119,7 @@ export class Multiwrap extends StandardErc721<MultiwrapContract> {
) {
super(contractWrapper, storage, chainId);

this.abi = abi;
this.abi = AbiSchema.parse(abi || []);
this.metadata = new ContractMetadata(
this.contractWrapper,
MultiwrapContractSchema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { GasCostEstimator } from "../../core/classes/gas-cost-estimator";
import { Transaction } from "../../core/classes/transactions";
import type { NetworkInput, TransactionResultWithId } from "../../core/types";
import { Address, AddressOrEns } from "../../schema";
import { Abi } from "../../schema/contracts/custom";
import { Abi, AbiInput, AbiSchema } from "../../schema/contracts/custom";
import { TokenErc721ContractSchema } from "../../schema/contracts/token-erc721";
import { SDKOptions } from "../../schema/sdk-options";
import type { TokenERC721 } from "@thirdweb-dev/contracts-js";
Expand Down Expand Up @@ -109,7 +109,7 @@ export class NFTCollection extends StandardErc721<TokenERC721> {
address: string,
storage: ThirdwebStorage,
options: SDKOptions = {},
abi: Abi,
abi: AbiInput,
chainId: number,
contractWrapper = new ContractWrapper<TokenERC721>(
network,
Expand All @@ -120,7 +120,7 @@ export class NFTCollection extends StandardErc721<TokenERC721> {
) {
super(contractWrapper, storage, chainId);

this.abi = abi;
this.abi = AbiSchema.parse(abi || []);
this.metadata = new ContractMetadata(
this.contractWrapper,
TokenErc721ContractSchema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { Transaction } from "../../core/classes/transactions";
import { NetworkInput, TransactionResultWithId } from "../../core/types";
import { PaperCheckout } from "../../integrations/thirdweb-checkout";
import { Address, AddressOrEns } from "../../schema";
import { Abi } from "../../schema/contracts/custom";
import { Abi, AbiInput, AbiSchema } from "../../schema/contracts/custom";
import { DropErc721ContractSchema } from "../../schema/contracts/drop-erc721";
import { SDKOptions } from "../../schema/sdk-options";
import { PrebuiltNFTDrop } from "../../types/eips";
Expand Down Expand Up @@ -161,7 +161,7 @@ export class NFTDrop extends StandardErc721<PrebuiltNFTDrop> {
address: string,
storage: ThirdwebStorage,
options: SDKOptions = {},
abi: Abi,
abi: AbiInput,
chainId: number,
contractWrapper = new ContractWrapper<PrebuiltNFTDrop>(
network,
Expand All @@ -171,7 +171,7 @@ export class NFTDrop extends StandardErc721<PrebuiltNFTDrop> {
),
) {
super(contractWrapper, storage, chainId);
this.abi = abi;
this.abi = AbiSchema.parse(abi || []);
this.metadata = new ContractMetadata(
this.contractWrapper,
DropErc721ContractSchema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { GasCostEstimator } from "../../core/classes/gas-cost-estimator";
import { PackVRF } from "../../core/classes/pack-vrf";
import { Transaction } from "../../core/classes/transactions";
import { NetworkInput, TransactionResultWithId } from "../../core/types";
import { Abi, Address, AddressOrEns } from "../../schema";
import { Abi, AbiInput, AbiSchema, Address, AddressOrEns } from "../../schema";
import { PackContractSchema } from "../../schema/contracts/packs";
import { SDKOptions } from "../../schema/sdk-options";
import {
Expand Down Expand Up @@ -117,7 +117,7 @@ export class Pack extends StandardErc1155<PackContract> {
address: string,
storage: ThirdwebStorage,
options: SDKOptions = {},
abi: Abi,
abi: AbiInput,
chainId: number,
contractWrapper = new ContractWrapper<PackContract>(
network,
Expand All @@ -137,7 +137,7 @@ export class Pack extends StandardErc1155<PackContract> {
),
) {
super(contractWrapper, storage, chainId);
this.abi = abi;
this.abi = AbiSchema.parse(abi || []);
this.erc1155 = new Erc1155(this.contractWrapper, this.storage, chainId);
this.metadata = new ContractMetadata(
this.contractWrapper,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { Transaction } from "../../core/classes/transactions";
import { NetworkInput, TransactionResultWithId } from "../../core/types";
import { PaperCheckout } from "../../integrations/thirdweb-checkout";
import { Address, AddressOrEns } from "../../schema";
import { Abi } from "../../schema/contracts/custom";
import { Abi, AbiInput, AbiSchema } from "../../schema/contracts/custom";
import { DropErc721ContractSchema } from "../../schema/contracts/drop-erc721";
import { SDKOptions } from "../../schema/sdk-options";
import { ClaimOptions } from "../../types/claim-conditions/claim-conditions";
Expand Down Expand Up @@ -172,7 +172,7 @@ export class SignatureDrop extends StandardErc721<SignatureDropContract> {
address: string,
storage: ThirdwebStorage,
options: SDKOptions = {},
abi: Abi,
abi: AbiInput,
chainId: number,
contractWrapper = new ContractWrapper<SignatureDropContract>(
network,
Expand All @@ -182,7 +182,7 @@ export class SignatureDrop extends StandardErc721<SignatureDropContract> {
),
) {
super(contractWrapper, storage, chainId);
this.abi = abi;
this.abi = AbiSchema.parse(abi || []);
this.metadata = new ContractMetadata(
this.contractWrapper,
DropErc721ContractSchema,
Expand Down
Loading

0 comments on commit d8c1c94

Please sign in to comment.