Skip to content

Commit

Permalink
erc721
Browse files Browse the repository at this point in the history
  • Loading branch information
kyscott18 committed Sep 20, 2023
1 parent 519bd23 commit 03fad2d
Show file tree
Hide file tree
Showing 36 changed files with 1,731 additions and 716 deletions.
25 changes: 25 additions & 0 deletions packages/core/src/erc721/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export type {
ERC721,
ERC721IDData,
ERC721Data,
} from "./types.js";

export { createERC721, createERC721Data, createERC721IDData } from "./utils.js";

export { solmateErc721ABI as solmateERC721 } from "../generated.js";

export { getERC721 } from "./publicActions/getERC721.js";
export { getERC721Approved } from "./publicActions/getERC721Approved.js";
export { getERC721BalanceOf } from "./publicActions/getERC721BalanceOf.js";
export { getERC721Data } from "./publicActions/getERC721Data.js";
export { getERC721IDData } from "./publicActions/getERC721IDData.js";
export { getERC721IsApprovedForAll } from "./publicActions/getERC721IsApprovedForAll.js";
export { getERC721Name } from "./publicActions/getERC721Name.js";
export { getERC721Symbol } from "./publicActions/getERC721Symbol.js";
export { getERC721OwnerOf } from "./publicActions/getERC721OwnerOf.js";
export { getERC721SupportsInterface } from "./publicActions/getERC721SupportsInterface.js";
export { getERC721TokenURI } from "./publicActions/getERC721TokenURI.js";

export { simulateERC721Transfer } from "./walletActions/simulateERC721Transfer.js";
export { simulateERC721Approve } from "./walletActions/simulateERC721Approve.js";
export { simulateERC721SetApprovalForAll } from "./walletActions/simulateERC721SetApprovalForAll.js";
61 changes: 61 additions & 0 deletions packages/core/src/erc721/publicActions/getERC721.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import invariant from "tiny-invariant";
import type { Hex } from "viem";
import { foundry } from "viem/chains";
import { beforeAll, expect, test } from "vitest";
import ERC721Bytecode from "../../../../../contracts/out/ERC721.sol/ERC721.json";
import { ALICE } from "../../_test/constants.js";
import { publicClient, testClient, walletClient } from "../../_test/utils.js";
import { erc721ABI } from "../../generated.js";
import type { ERC721 } from "../types.js";
import { createERC721 } from "../utils.js";
import { getERC721 } from "./getERC721.js";

let id: Hex | undefined = undefined;

let erc721: ERC721;

beforeAll(async () => {
if (id === undefined || erc721 === undefined) {
const deployHash = await walletClient.deployContract({
account: ALICE,
abi: erc721ABI,
bytecode: ERC721Bytecode.bytecode.object as Hex,
args: ["name", "symbol", "mitch.com"],
});

const { contractAddress } = await publicClient.waitForTransactionReceipt({
hash: deployHash,
});
invariant(contractAddress);
erc721 = createERC721(
contractAddress,
"name",
"symbol",
0n,
"mitch.com",
foundry.id,
);
} else {
await testClient.revert({ id });
}
id = await testClient.snapshot();
});

test("read erc721", async () => {
const _erc721 = await getERC721(publicClient, {
erc721,
});
expect(_erc721).toStrictEqual(erc721);
});

test("read erc721 select", async () => {
const rm = getERC721(
publicClient,
{
erc721,
},
"select",
);

expect(await rm.read().then((data) => rm.parse(data))).toStrictEqual(erc721);
});
61 changes: 61 additions & 0 deletions packages/core/src/erc721/publicActions/getERC721.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import type { Chain, Client, ReadContractParameters, Transport } from "viem";
import { solmateErc721ABI as solmateERC721ABI } from "../../generated.js";
import type { ReverseMirage } from "../../types/rm.js";
import type { ERC721 } from "../types.js";
import { createERC721 } from "../utils.js";
import { getERC721Name } from "./getERC721Name.js";
import { getERC721Symbol } from "./getERC721Symbol.js";
import { getERC721TokenURI } from "./getERC721TokenURI.js";

export type GetERC721Parameters = Omit<
ReadContractParameters<typeof solmateERC721ABI, "name">,
"address" | "abi" | "functionName" | "args"
> & {
erc721: Pick<ERC721, "address" | "id" | "chainID"> &
Partial<Pick<ERC721, "blockCreated">>;
};

export type GetERC721ReturnType = ERC721;

export const getERC721 = <
TChain extends Chain | undefined,
T extends "select" | undefined,
>(
client: Client<Transport, TChain>,
args: GetERC721Parameters,
type?: T,
): ReverseMirage<[string, string, string], GetERC721ReturnType, T> =>
(type === undefined
? Promise.all([
getERC721Name(client, args),
getERC721Symbol(client, args),
getERC721TokenURI(client, args),
]).then(([name, symbol, tokenURI]) =>
createERC721(
args.erc721.address,
name,
symbol,
args.erc721.id,
tokenURI,
args.erc721.chainID,
args.blockNumber,
),
)
: {
read: () =>
Promise.all([
getERC721Name(client, args, "select").read(),
getERC721Symbol(client, args, "select").read(),
getERC721TokenURI(client, args, "select").read(),
]),
parse: ([name, symbol, tokenURI]) =>
createERC721(
args.erc721.address,
name,
symbol,
args.erc721.id,
tokenURI,
args.erc721.chainID,
args.blockNumber,
),
}) as ReverseMirage<[string, string, string], GetERC721ReturnType, T>;
77 changes: 77 additions & 0 deletions packages/core/src/erc721/publicActions/getERC721Approved.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import invariant from "tiny-invariant";
import type { Hex } from "viem";
import { foundry } from "viem/chains";
import { beforeAll, expect, test } from "vitest";
import ERC721Bytecode from "../../../../../contracts/out/ERC721.sol/ERC721.json";
import { ALICE, BOB } from "../../_test/constants.js";
import { publicClient, testClient, walletClient } from "../../_test/utils.js";
import { erc721ABI } from "../../generated.js";
import type { ERC721 } from "../types.js";
import { createERC721 } from "../utils.js";
import { getERC721Approved } from "./getERC721Approved.js";

let id: Hex | undefined = undefined;

let erc721: ERC721;

beforeAll(async () => {
if (id === undefined || erc721 === undefined) {
const deployHash = await walletClient.deployContract({
account: ALICE,
abi: erc721ABI,
bytecode: ERC721Bytecode.bytecode.object as Hex,
args: ["name", "symbol", "mitch.com"],
});

const { contractAddress } = await publicClient.waitForTransactionReceipt({
hash: deployHash,
});
invariant(contractAddress);
erc721 = createERC721(
contractAddress,
"name",
"symbol",
0n,
"mitch.com",
foundry.id,
);

const mintHash = await walletClient.writeContract({
abi: erc721ABI,
functionName: "mint",
address: contractAddress,
args: [ALICE, 0n],
});
await publicClient.waitForTransactionReceipt({ hash: mintHash });

const approvedHash = await walletClient.writeContract({
abi: erc721ABI,
functionName: "approve",
address: contractAddress,
args: [BOB, 0n],
});
await publicClient.waitForTransactionReceipt({ hash: approvedHash });
} else {
await testClient.revert({ id });
}
id = await testClient.snapshot();
});

test("read approved", async () => {
const owner = await getERC721Approved(publicClient, {
erc721,
});
expect(owner).toBe(BOB);
});

test("read approved select", async () => {
const rm = getERC721Approved(
publicClient,
{
erc721,
},
"select",
);

expect(await rm.read().then((data) => rm.parse(data))).toBe(BOB);
});
44 changes: 44 additions & 0 deletions packages/core/src/erc721/publicActions/getERC721Approved.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type {
Address,
Chain,
Client,
ReadContractParameters,
Transport,
} from "viem";
import { readContract } from "viem/contract";
import { solmateErc721ABI as solmateERC721ABI } from "../../generated.js";
import type { ReverseMirage } from "../../types/rm.js";
import type { ERC721 } from "../types.js";

export type GetERC721ApprovedParameters = Omit<
ReadContractParameters<typeof solmateERC721ABI, "getApproved">,
"address" | "abi" | "functionName" | "args"
> & { erc721: Pick<ERC721, "address" | "id"> };

export type GetERC721ApprovedReturnType = Address;

export const getERC721Approved = <
TChain extends Chain | undefined,
T extends "select" | undefined,
>(
client: Client<Transport, TChain>,
args: GetERC721ApprovedParameters,
type?: T,
): ReverseMirage<Address, GetERC721ApprovedReturnType, T> =>
(type === undefined
? readContract(client, {
abi: solmateERC721ABI,
address: args.erc721.address,
functionName: "getApproved",
args: [args.erc721.id],
})
: {
read: () =>
readContract(client, {
abi: solmateERC721ABI,
address: args.erc721.address,
functionName: "getApproved",
args: [args.erc721.id],
}),
parse: (data) => data,
}) as ReverseMirage<Address, GetERC721ApprovedReturnType, T>;
71 changes: 71 additions & 0 deletions packages/core/src/erc721/publicActions/getERC721BalanceOf.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import invariant from "tiny-invariant";
import type { Hex } from "viem";
import { foundry } from "viem/chains";
import { beforeAll, expect, test } from "vitest";
import ERC721Bytecode from "../../../../../contracts/out/ERC721.sol/ERC721.json";
import { ALICE } from "../../_test/constants.js";
import { publicClient, testClient, walletClient } from "../../_test/utils.js";
import { erc721ABI } from "../../generated.js";
import type { ERC721 } from "../types.js";
import { createERC721 } from "../utils.js";
import { getERC721BalanceOf } from "./getERC721BalanceOf.js";

let id: Hex | undefined = undefined;

let erc721: ERC721;

beforeAll(async () => {
if (id === undefined || erc721 === undefined) {
const deployHash = await walletClient.deployContract({
account: ALICE,
abi: erc721ABI,
bytecode: ERC721Bytecode.bytecode.object as Hex,
args: ["name", "symbol", "mitch.com"],
});

const { contractAddress } = await publicClient.waitForTransactionReceipt({
hash: deployHash,
});
invariant(contractAddress);
erc721 = createERC721(
contractAddress,
"name",
"symbol",
0n,
"mitch.com",
foundry.id,
);

const mintHash = await walletClient.writeContract({
abi: erc721ABI,
functionName: "mint",
address: contractAddress,
args: [ALICE, 0n],
});
await publicClient.waitForTransactionReceipt({ hash: mintHash });
} else {
await testClient.revert({ id });
}
id = await testClient.snapshot();
});

test("read balance", async () => {
const balanceOfAlice = await getERC721BalanceOf(publicClient, {
erc721,
address: ALICE,
});
expect(balanceOfAlice).toBe(1n);
});

test("read balance select", async () => {
const rm = getERC721BalanceOf(
publicClient,
{
erc721,
address: ALICE,
},
"select",
);

expect(await rm.read().then((data) => rm.parse(data))).toBe(1n);
});
44 changes: 44 additions & 0 deletions packages/core/src/erc721/publicActions/getERC721BalanceOf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type {
Address,
Chain,
Client,
ReadContractParameters,
Transport,
} from "viem";
import { readContract } from "viem/contract";
import { solmateErc721ABI as solmateERC721ABI } from "../../generated.js";
import type { ReverseMirage } from "../../types/rm.js";
import type { ERC721 } from "../types.js";

export type GetERC721BalanceOfParameters = Omit<
ReadContractParameters<typeof solmateERC721ABI, "balanceOf">,
"address" | "abi" | "functionName" | "args"
> & { erc721: Pick<ERC721, "address">; address: Address };

export type GetERC721BalanceOfReturnType = bigint;

export const getERC721BalanceOf = <
TChain extends Chain | undefined,
T extends "select" | undefined,
>(
client: Client<Transport, TChain>,
args: GetERC721BalanceOfParameters,
type?: T,
): ReverseMirage<bigint, GetERC721BalanceOfReturnType, T> =>
(type === undefined
? readContract(client, {
abi: solmateERC721ABI,
address: args.erc721.address,
functionName: "balanceOf",
args: [args.address],
})
: {
read: () =>
readContract(client, {
abi: solmateERC721ABI,
address: args.erc721.address,
functionName: "balanceOf",
args: [args.address],
}),
parse: (data) => data,
}) as ReverseMirage<bigint, GetERC721BalanceOfReturnType, T>;
Loading

0 comments on commit 03fad2d

Please sign in to comment.