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

Adding automated anvil testing client creation. #324

Merged
merged 3 commits into from
Nov 8, 2023
Merged
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
4 changes: 4 additions & 0 deletions .github/workflows/foundry.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ jobs:
run: |
npx turbo run build

- name: Test js package
run: |
npx turbo run test:js
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!


coverage-1155:
uses: ./.github/workflows/coverage.yml
name: "Test coverage - 1155"
Expand Down
2 changes: 0 additions & 2 deletions packages/protocol-sdk/.env.anvil

This file was deleted.

7 changes: 3 additions & 4 deletions packages/protocol-sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zoralabs/premint-sdk",
"version": "0.1.1",
"name": "@zoralabs/protocol-sdk",
"version": "0.2.0",
"repository": "https://github.com/ourzora/zora-protocol",
"license": "MIT",
"main": "./dist/index.js",
Expand All @@ -10,8 +10,7 @@
"build": "tsup",
"prepack": "yarn build",
"test:js": "vitest src",
"generate-types": "npx openapi-typescript https://api.zora.co/premint/openapi.json -o src/generated/premint-api-types.ts && npx openapi-typescript https://api.zora.co/discover/openapi.json -o src/generated/discover-api-types.ts",
"anvil": "source .env.anvil && anvil --fork-url $FORK_RPC_URL --fork-block-number $FORK_BLOCK_NUMBER --chain-id 31337"
"generate-types": "npx openapi-typescript https://api.zora.co/premint/openapi.json -o src/generated/premint-api-types.ts && npx openapi-typescript https://api.zora.co/discover/openapi.json -o src/generated/discover-api-types.ts"
},
"dependencies": {
"@zoralabs/protocol-deployments": "*",
Expand Down
84 changes: 84 additions & 0 deletions packages/protocol-sdk/src/anvil.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { spawn } from "node:child_process";
import { join } from "path";
import { test } from "vitest";
import {
PublicClient,
TestClient,
WalletClient,
createPublicClient,
createTestClient,
createWalletClient,
http,
} from "viem";
import { foundry } from "viem/chains";

export interface AnvilViemClientsTest {
viemClients: {
walletClient: WalletClient;
publicClient: PublicClient;
testClient: TestClient;
};
}

async function waitForAnvilInit(anvil: any) {
return new Promise((resolve) => {
anvil.stdout.once("data", () => {
resolve(true);
});
});
}

export const anvilTest = test.extend<AnvilViemClientsTest>({
viemClients: async ({task}, use) => {
console.log('setting up clients for ', task.name);
const port = Math.floor(Math.random() * 2000) + 4000;
const anvil = spawn(
"anvil",
[
"--port",
`${port}`,
"--fork-url",
"https://rpc.zora.co/",
"--fork-block-number",
"6133407",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about allowing chain name (zora, or zora-sepolia) and blockNumber to be specified as arguments with defaults?

"--chain-id",
"31337",
],
{
cwd: join(__dirname, ".."),
killSignal: "SIGINT",
},
);
const anvilHost = `http://0.0.0.0:${port}`;
await waitForAnvilInit(anvil);

const chain = {
...foundry,
};

const walletClient = createWalletClient({
chain,
transport: http(anvilHost),
});

const testClient = createTestClient({
chain,
mode: "anvil",
transport: http(anvilHost),
});

const publicClient = createPublicClient({
chain,
transport: http(anvilHost),
});

await use({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great use of use

publicClient,
walletClient,
testClient,
});

// clean up function, called once after all tests run
anvil.kill("SIGINT");
},
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { foundry, zora, zoraTestnet } from "viem/chains";
import type { BackendChainNames as BackendChainNamesType } from "./premint-api-client";
import type { BackendChainNames as BackendChainNamesType } from "../premint/premint-api-client";
import {
Chain,
PublicClient,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,61 +1,32 @@
import {
Address,
createPublicClient,
createTestClient,
createWalletClient,
http,
parseEther,
} from "viem";
import { foundry } from "viem/chains";
import { describe, it, beforeEach, expect, afterEach } from "vitest";
import { parseEther } from "viem";
import { describe, expect } from "vitest";
import {
createNew1155Token,
getTokenIdFromCreateReceipt,
} from "./1155-create-helper";

const chain = foundry;

const walletClient = createWalletClient({
chain,
transport: http(),
});

const testClient = createTestClient({
chain,
mode: "anvil",
transport: http(),
});

const publicClient = createPublicClient({
chain,
transport: http(),
});

const [creatorAccount] = (await walletClient.getAddresses()) as [Address];
import { anvilTest } from "src/anvil";

const demoTokenMetadataURI = "ipfs://DUMMY/token.json";
const demoContractMetadataURI = "ipfs://DUMMY/contract.json";

describe("create-helper", () => {
beforeEach(async () => {
await testClient.setBalance({
address: creatorAccount,
value: parseEther("1"),
});
});
afterEach(() => testClient.reset());

it(
anvilTest(
"creates a new contract given arguments",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about renaming to anvilRunningTest

async () => {
async ({ viemClients: { testClient, publicClient, walletClient } }) => {
const addresses = await walletClient.getAddresses();
const creatorAddress = addresses[0]!;
await testClient.setBalance({
address: creatorAddress,
value: parseEther("1"),
});
const new1155TokenRequest = await createNew1155Token({
publicClient,
contract: {
name: "testContract",
uri: demoContractMetadataURI,
},
tokenMetadataURI: demoTokenMetadataURI,
account: creatorAccount,
account: creatorAddress,
mintToCreatorCount: 1,
});
const hash = await new1155TokenRequest.send(walletClient);
Expand All @@ -64,22 +35,27 @@ describe("create-helper", () => {
expect(receipt.to).to.equal("0x777777c338d93e2c7adf08d102d45ca7cc4ed021");
expect(getTokenIdFromCreateReceipt(receipt)).to.be.equal(1n);
},
10 * 1000,
20 * 1000,
);
it(
anvilTest(
"creates a new contract, than creates a new token on this existing contract",
async () => {
async ({ viemClients: { publicClient, walletClient } }) => {
const addresses = await walletClient.getAddresses();
const creatorAccount = addresses[0]!;

const new1155TokenRequest = await createNew1155Token({
publicClient,
contract: {
name: "testContract",
name: "testContract2",
uri: demoContractMetadataURI,
},
tokenMetadataURI: demoTokenMetadataURI,
account: creatorAccount,
mintToCreatorCount: 1,
});
expect(new1155TokenRequest.contractAddress).to.be.equal('0xA72724cC3DcEF210141a1B84C61824074151Dc99');
expect(new1155TokenRequest.contractAddress).to.be.equal(
"0xb1A8928dF830C21eD682949Aa8A83C1C215194d3",
);
expect(new1155TokenRequest.contractExists).to.be.false;
const hash = await new1155TokenRequest.send(walletClient);
const receipt = await publicClient.waitForTransactionReceipt({ hash });
Expand All @@ -90,14 +66,16 @@ describe("create-helper", () => {
const newTokenOnExistingContract = await createNew1155Token({
publicClient,
contract: {
name: "testContract",
name: "testContract2",
uri: demoContractMetadataURI,
},
tokenMetadataURI: demoTokenMetadataURI,
account: creatorAccount,
mintToCreatorCount: 1,
});
expect(newTokenOnExistingContract.contractAddress).to.be.equal('0xA72724cC3DcEF210141a1B84C61824074151Dc99');
expect(newTokenOnExistingContract.contractAddress).to.be.equal(
"0xb1A8928dF830C21eD682949Aa8A83C1C215194d3",
);
expect(newTokenOnExistingContract.contractExists).to.be.true;
const newHash = await newTokenOnExistingContract.send(walletClient);
const newReceipt = await publicClient.waitForTransactionReceipt({
Expand All @@ -107,6 +85,6 @@ describe("create-helper", () => {
expect(tokenId).to.be.equal(2n);
expect(newReceipt).not.toBeNull();
},
10 * 1000,
20 * 1000,
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type {
WalletClient,
} from "viem";
import { decodeEventLog, encodeFunctionData, zeroAddress } from "viem";
import { OPEN_EDITION_MINT_SIZE } from "./constants";
import { OPEN_EDITION_MINT_SIZE } from "../constants";

const saleEndForever = 18446744073709551615n;
const royaltyBPSDefault = 1000;
Expand Down
10 changes: 5 additions & 5 deletions packages/protocol-sdk/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
export * from "./premint-client";
export * from "./premint/premint-client";

export * from "./preminter";
export * from "./premint/preminter";

export * from "./premint-api-client";
export * from "./premint/premint-api-client";

export * from "./mint-api-client";
export * from "./mint/mint-api-client";

export * from "./1155-create-helper";
export * from "./create/1155-create-helper";
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { retries, get, post } from "./http-api-base";
import { paths } from "./generated/discover-api-types";
import { ZORA_API_BASE } from "./premint-api-client";
import { ZORA_SUBGRAPH_URLS } from "./constants";
import { retries, get, post } from "../apis/http-api-base";
import { paths } from "../apis/generated/discover-api-types";
import { ZORA_API_BASE } from "../premint/premint-api-client";
import { ZORA_SUBGRAPH_URLS } from "../constants";

export type MintableGetToken =
paths["/mintables_v2/{chain_name}/{collection_address}"];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,53 +1,27 @@
import {
Address,
createPublicClient,
createTestClient,
createWalletClient,
http,
parseAbi,
parseEther,
} from "viem";
import { foundry, zora } from "viem/chains";
import { describe, it, beforeEach, expect, afterEach } from "vitest";
import { zora } from "viem/chains";
import { describe, expect } from "vitest";
import { MintClient } from "./mint-client";
import { zoraCreator1155ImplABI } from "@zoralabs/protocol-deployments";

const chain = foundry;

const walletClient = createWalletClient({
chain,
transport: http(),
});

const testClient = createTestClient({
chain,
mode: "anvil",
transport: http(),
});

const publicClient = createPublicClient({
chain,
transport: http(),
});

const [creatorAccount] = (await walletClient.getAddresses()) as [Address];
import { anvilTest } from "src/anvil";

const erc721ABI = parseAbi([
"function balanceOf(address owner) public view returns (uint256)",
] as const);

describe("mint-helper", () => {
beforeEach(async () => {
await testClient.setBalance({
address: creatorAccount,
value: parseEther("2000"),
});
});
afterEach(() => testClient.reset());

it(
anvilTest(
"mints a new 1155 token",
async () => {
async ({ viemClients }) => {
const { testClient, walletClient, publicClient } = viemClients;
const creatorAccount = (await walletClient.getAddresses())[0]!;
await testClient.setBalance({
address: creatorAccount,
value: parseEther("2000"),
});
const targetContract = "0xa2fea3537915dc6c7c7a97a82d1236041e6feb2e";
const targetTokenId = 1n;
const minter = new MintClient(zora);
Expand Down Expand Up @@ -84,9 +58,16 @@ describe("mint-helper", () => {
12 * 1000,
);

it(
anvilTest(
"mints a new 721 token",
async () => {
async ({ viemClients }) => {
const { testClient, walletClient, publicClient } = viemClients;
const creatorAccount = (await walletClient.getAddresses())[0]!;
await testClient.setBalance({
address: creatorAccount,
value: parseEther("2000"),
});

const targetContract = "0x7aae7e67515A2CbB8585C707Ca6db37BDd3EA839";
const targetTokenId = undefined;
const minter = new MintClient(zora);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
parseAbiParameters,
zeroAddress,
} from "viem";
import { ClientBase } from "./client-base";
import { ClientBase } from "../apis/client-base";
import { MintAPIClient, MintableGetTokenResponse } from "./mint-api-client";
import {
zoraCreator1155ImplABI,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { post, retries, get } from "./http-api-base";
import { components, paths } from "./generated/premint-api-types";
import { ZORA_API_BASE } from "./constants";
import { post, retries, get } from "../apis/http-api-base";
import { components, paths } from "../apis/generated/premint-api-types";
import { ZORA_API_BASE } from "../constants";

type SignaturePostType = paths["/signature"]["post"];
type PremintSignatureRequestBody =
Expand Down
Loading
Loading