Skip to content

Commit

Permalink
[alpha] - breaking change prepareTransaction() -> `prepareContractC…
Browse files Browse the repository at this point in the history
…all()` (#2302)
  • Loading branch information
jnsdls authored Feb 13, 2024
1 parent a199eb4 commit 2222c09
Show file tree
Hide file tree
Showing 81 changed files with 1,002 additions and 903 deletions.
42 changes: 21 additions & 21 deletions packages/thirdweb/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ npm install thirdweb@alpha
A client is the entry point to the thirdweb SDK. It is required for all other actions.

```ts
import { createClient } from "thirdweb";
import { createThirdwebClient } from "thirdweb";

const client = createClient({
const client = createThirdwebClient({
// one of these is required to initialize a client - create a free api key at https://thirdweb.com/dashboard
secretKey: "<you secret key>",
// or
Expand All @@ -37,9 +37,9 @@ const client = createClient({
A "contract" is a wrapper around a smart contract that is deployed on a chain. It is what you use to create [transactions](#transactions) and [read contract state](#read---reading-contract-state).

```ts
import { createClient, getContract } from "thirdweb";
import { createThirdwebClient, getContract } from "thirdweb";

const client = createClient({...})
const client = createThirdwebClient({...})
const contract = getContract({
// pass in the client
client,
Expand All @@ -61,9 +61,9 @@ There are 4 ways to create a transaction, all of these return the same transacti
##### Method Signature

```ts
import { prepareTransaction } from "thirdweb";
import { prepareContractCall } from "thirdweb";

const tx = prepareTransaction({
const tx = prepareContractCall({
contract,
// pass the method signature that you want to call
method: "function mintTo(address to, uint256 amount)",
Expand All @@ -76,8 +76,8 @@ const tx = prepareTransaction({
##### Automatic ABI Resolution

```ts
import { prepareTransaction } from "thirdweb";
const tx = prepareTransaction({
import { prepareContractCall } from "thirdweb";
const tx = prepareContractCall({
contract,
// in this case we only pass the name of the method we want to call
method: "mintTo",
Expand All @@ -89,7 +89,7 @@ const tx = prepareTransaction({
##### Explicit Contract ABI

```ts
import { getContract, prepareTransaction } from "thirdweb";
import { getContract, prepareContractCall } from "thirdweb";

const contract = getContract({
{...}
Expand All @@ -114,7 +114,7 @@ const contract = getContract({
],
});

const tx = prepareTransaction({
const tx = prepareContractCall({
contract,
// we get auto-completion for all the available functions on the contract ABI
method: "mintTo",
Expand All @@ -126,8 +126,8 @@ const tx = prepareTransaction({
##### ABI Snippet

```ts
import { prepareTransaction } from "thirdweb";
const tx = prepareTransaction({
import { prepareContractCall } from "thirdweb";
const tx = prepareContractCall({
client,
// in this case we pass the piece of the abi for the method we want to call
abi: {
Expand Down Expand Up @@ -155,7 +155,7 @@ Transactions have a variety of actions that can be called on them, in all cases

##### `read` - reading contract state

For reading contract state, there is a shortcut function called `read` that can be used instead of `prepareTransaction`:
For reading contract state, there is a shortcut function called `read` that can be used instead of `prepareContractCall`:

```ts
import { readContract } from "thirdweb";
Expand All @@ -172,9 +172,9 @@ const balance = await readContract({
Which is the equivalent of doing:

```ts
import { prepareTransaction, readTransaction } from "thirdweb";
import { prepareContractCall, readTransaction } from "thirdweb";

const tx = prepareTransaction({
const tx = prepareContractCall({
contract,
method: "function balanceOf(address) view returns (uint256)",
params: ["0x123..."],
Expand Down Expand Up @@ -262,7 +262,7 @@ import { balanceOf, mintTo } from "thirdweb/extensions/erc20";

```ts
import {
createClient,
createThirdwebClient,
getContract,
sendTransaction,
waitForReceipt,
Expand All @@ -271,7 +271,7 @@ import { privateKeyWallet } from "thirdweb/wallets/private-key";
import { balanceOf, mintTo } from "thirdweb/extensions/erc20";

// Step 1: create a client
const client = createClient({
const client = createThirdwebClient({
// create a secret key at https://thirdweb.com/dashboard
secretKey: process.env.SECRET_KEY as string,
});
Expand Down Expand Up @@ -332,17 +332,17 @@ console.log("ending balance", newBalance);

```ts
import {
createClient,
createThirdwebClient,
getContract,
readContract,
sendTransaction,
prepareTransaction,
prepareContractCall,
waitForReceipt,
} from "thirdweb";
import { privateKeyWallet } from "thirdweb/wallets/private-key";

// Step 1: create a client
const client = createClient({
const client = createThirdwebClient({
// create a secret key at https://thirdweb.com/dashboard
secretKey: process.env.SECRET_KEY as string,
});
Expand Down Expand Up @@ -372,7 +372,7 @@ const wallet = privateKeyWallet({
});

// Step 5: create a transaction
const tx = prepareTransaction({
const tx = prepareContractCall({
contract,
method: "function mintTo(address to, uint256 amount)",
params: ["0x0890C23024089675D072E984f28A93bb391a35Ab", 100n * 10n ** 18n],
Expand Down
4 changes: 2 additions & 2 deletions packages/thirdweb/comparison/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ npm install thirdweb@alpha
### Hello World

```javascript
import { createClient, getContract } from "thirdweb";
import { createThirdwebClient, getContract } from "thirdweb";
import { totalSupply } from "thirdweb/extensions/erc20";

const client = createClient({
const client = createThirdwebClient({
clientId: "<my-client-id>",
});

Expand Down
15 changes: 12 additions & 3 deletions packages/thirdweb/src/abi/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,32 @@ import type {
AbiEvent,
ExtractAbiEvent,
} from "abitype";
import type { ThirdwebContract } from "../contract/contract.js";

export type ParseMethod<abi extends Abi, method extends AbiFunction | string> =
export type ParseMethod<
abi extends Abi,
method extends
| AbiFunction
| string
| ((contract: ThirdwebContract<abi>) => Promise<AbiFunction>),
> =
// if the method IS an AbiFunction, return it
method extends AbiFunction
? method
: method extends string // we now know we are in "string" territory
? // if the string starts with `function` then we can parse it
method extends `function ${string}`
? ParseAbiItem<method>
? ParseAbiItem<method> extends AbiFunction
? ParseAbiItem<method>
: never
: // do we have an ABI to check, check the length
abi extends { length: 0 }
? // if not, we return AbiFunction
AbiFunction
: // if we do have a length, extract the abi function
ExtractAbiFunction<abi, method>
: // this means its neither have an AbiFunction NOR a string -> never
never;
AbiFunction;

export type ParseEvent<abi extends Abi, event extends AbiEvent | string> =
// if the method IS an AbiEvent, return it
Expand Down
10 changes: 5 additions & 5 deletions packages/thirdweb/src/client/client.test.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
import { describe, it, expect } from "vitest";
import { createClient } from "./client.js";
import { createThirdwebClient } from "./client.js";
import { computeClientIdFromSecretKey } from "../utils/client-id.js";

describe("client", () => {
it("should create a client with a clientId", () => {
const client = createClient({ clientId: "foo" });
const client = createThirdwebClient({ clientId: "foo" });
expect(client.clientId).toBe("foo");
expect(client.secretKey).toBeUndefined();
});
it("should create a client with a secretKey", () => {
const client = createClient({ secretKey: "bar" });
const client = createThirdwebClient({ secretKey: "bar" });
expect(client.clientId).toBe(computeClientIdFromSecretKey("bar"));
expect(client.secretKey).toBe("bar");
});
it("should ignore clientId if secretKey is provided", () => {
// @ts-expect-error - testing invalid input
const client = createClient({ clientId: "foo", secretKey: "bar" });
const client = createThirdwebClient({ clientId: "foo", secretKey: "bar" });
expect(client.clientId).toBe(computeClientIdFromSecretKey("bar"));
expect(client.secretKey).toBe("bar");
});
it("should throw an error if neither clientId nor secretKey is provided", () => {
// @ts-expect-error - testing invalid input
expect(() => createClient({})).toThrowError(
expect(() => createThirdwebClient({})).toThrowError(
"clientId or secretKey must be provided",
);
});
Expand Down
10 changes: 6 additions & 4 deletions packages/thirdweb/src/client/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type ClientOptions = {
};
};

export type CreateClientOptions = (
export type CreateThirdwebClientOptions = (
| {
clientId: string;
secretKey?: never;
Expand All @@ -33,11 +33,13 @@ export type ThirdwebClient = {
* @throws An error if neither `clientId` nor `secretKey` is provided.
* @example
* ```ts
* import { createClient } from "thirdweb";
* const client = createClient({ clientId: "..." });
* import { createThirdwebClient } from "thirdweb";
* const client = createThirdwebClient({ clientId: "..." });
* ```
*/
export function createClient(options: CreateClientOptions): ThirdwebClient {
export function createThirdwebClient(
options: CreateThirdwebClientOptions,
): ThirdwebClient {
const { clientId, secretKey, ...rest } = options;
// if secretKey is provided, compute the clientId from it (and ignore any clientId passed in)
if (secretKey) {
Expand Down
26 changes: 14 additions & 12 deletions packages/thirdweb/src/contract/actions/resolve-abi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { getClientFetch } from "../../utils/fetch.js";
import { getBytecode } from "./get-bytecode.js";
import { download } from "../../storage/download.js";
import { extractIPFSUri } from "../../utils/bytecode/extractIPFS.js";
import { readContractRaw } from "../../transaction/actions/raw/raw-read.js";

const ABI_RESOLUTION_CACHE = new WeakMap<ThirdwebContract<Abi>, Promise<Abi>>();

Expand All @@ -19,9 +18,9 @@ const ABI_RESOLUTION_CACHE = new WeakMap<ThirdwebContract<Abi>, Promise<Abi>>();
* @returns A promise that resolves to the ABI of the contract.
* @example
* ```ts
* import { createClient, getContract } from "thirdweb";
* import { createThirdwebClient, getContract } from "thirdweb";
* import { resolveContractAbi } from "thirdweb/contract"
* const client = createClient({ clientId: "..." });
* const client = createThirdwebClient({ clientId: "..." });
* const myContract = getContract({
* client,
* address: "...",
Expand Down Expand Up @@ -61,9 +60,9 @@ export function resolveContractAbi<abi extends Abi>(
* @returns A promise that resolves to the ABI of the contract.
* @example
* ```ts
* import { createClient, getContract } from "thirdweb";
* import { createThirdwebClient, getContract } from "thirdweb";
* import { resolveAbiFromContractApi } from "thirdweb/contract"
* const client = createClient({ clientId: "..." });
* const client = createThirdwebClient({ clientId: "..." });
* const myContract = getContract({
* client,
* address: "...",
Expand Down Expand Up @@ -91,9 +90,9 @@ export async function resolveAbiFromContractApi(
* @throws Error if no IPFS URI is found in the bytecode.
* @example
* ```ts
* import { createClient, getContract } from "thirdweb";
* import { createThirdwebClient, getContract } from "thirdweb";
* import { resolveAbiFromBytecode } from "thirdweb/contract"
* const client = createClient({ clientId: "..." });
* const client = createThirdwebClient({ clientId: "..." });
* const myContract = getContract({
* client,
* address: "...",
Expand Down Expand Up @@ -243,9 +242,9 @@ const DIAMOND_ABI = {
* @returns The resolved ABI for the contract.
* @example
* ```ts
* import { createClient, getContract } from "thirdweb";
* import { createThirdwebClient, getContract } from "thirdweb";
* import { resolveCompositeAbiFromBytecode } from "thirdweb/contract"
* const client = createClient({ clientId: "..." });
* const client = createThirdwebClient({ clientId: "..." });
* const myContract = getContract({
* client,
* address: "...",
Expand Down Expand Up @@ -299,7 +298,8 @@ async function resolvePluginPatternAddresses(
contract: ThirdwebContract,
): Promise<string[]> {
try {
const pluginMap = await readContractRaw({
const { readContract } = await import("../../transaction/read-contract.js");
const pluginMap = await readContract({
contract,
method: PLUGINS_ABI,
});
Expand All @@ -319,7 +319,8 @@ async function resolveBaseRouterAddresses(
contract: ThirdwebContract,
): Promise<string[]> {
try {
const pluginMap = await readContractRaw({
const { readContract } = await import("../../transaction/read-contract.js");
const pluginMap = await readContract({
contract,
method: BASE_ROUTER_ABI,
});
Expand All @@ -339,7 +340,8 @@ async function resolveDiamondFacetAddresses(
contract: ThirdwebContract,
): Promise<string[]> {
try {
const facets = await readContractRaw({ contract, method: DIAMOND_ABI });
const { readContract } = await import("../../transaction/read-contract.js");
const facets = await readContract({ contract, method: DIAMOND_ABI });
// if there are no facets, return the root ABI
if (!facets.length) {
return [];
Expand Down
4 changes: 2 additions & 2 deletions packages/thirdweb/src/contract/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ export type ThirdwebContract<abi extends Abi = []> = Readonly<
* @returns The Thirdweb contract.
* @example
* ```ts
* import { createClient, getContract } from "thirdweb";
* const client = createClient({ clientId: "..." });
* import { createThirdwebClient, getContract } from "thirdweb";
* const client = createThirdwebClient({ clientId: "..." });
* const contract = getContract({
* client,
* address: "...",
Expand Down
4 changes: 2 additions & 2 deletions packages/thirdweb/src/contract/verification/publisher.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { ThirdwebClient } from "../../client/client.js";
import { download } from "../../storage/download.js";
import { readContract } from "../../transaction/actions/read.js";
import { readContract } from "../../transaction/index.js";
import { extractIPFSUri, resolveImplementation } from "../../utils/index.js";
import { getContract, type ThirdwebContract } from "../contract.js";

const CONTRACT_PUBLISHER_ADDRESS = "0xf5b896Ddb5146D5dA77efF4efBb3Eae36E300808"; // Polygon only

// TODO: clea this up
// TODO: clean this up
/**
*
* @param contract
Expand Down
4 changes: 2 additions & 2 deletions packages/thirdweb/src/event/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ export type ContractEvent<event extends AbiEvent> = ContractEventOptions<
* @returns The contract event.
* @example
* ```ts
* import { createClient, getContract } from "thirdweb";
* import { createThirdwebClient, getContract } from "thirdweb";
* import { prepareEvent } from "thirdweb";
* const client = createClient({ clientId: "..." });
* const client = createThirdwebClient({ clientId: "..." });
* const contract = getContract({
* client,
* address: "...",
Expand Down
8 changes: 5 additions & 3 deletions packages/thirdweb/src/extensions/common/read/contractURI.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { readContract } from "../../../transaction/actions/read.js";
import type { TxOpts } from "../../../transaction/transaction.js";
import {
readContract,
type BaseTransactionOptions,
} from "../../../transaction/index.js";

/**
* Retrieves the contract URI for a given transaction options.
Expand All @@ -12,7 +14,7 @@ import type { TxOpts } from "../../../transaction/transaction.js";
* const uri = await contractURI({ contract });
* ```
*/
export function contractURI(options: TxOpts): Promise<string> {
export function contractURI(options: BaseTransactionOptions): Promise<string> {
return readContract({
...options,
method: "function contractURI() returns (string)",
Expand Down
Loading

0 comments on commit 2222c09

Please sign in to comment.