Skip to content

Commit

Permalink
feat(react): test hooks (#457)
Browse files Browse the repository at this point in the history
## Description

Add sdk react hook tests.

## What type of PR is this? (check all applicable)

- [ ] 🍕 Feature (`feat:`)
- [ ] 🐛 Bug Fix (`fix:`)
- [ ] 📝 Documentation Update (`docs:`)
- [ ] 🎨 Style (`style:`)
- [ ] 🧑‍💻 Code Refactor (`refactor:`)
- [ ] 🔥 Performance Improvements (`perf:`)
- [x] ✅ Test (`test:`)
- [ ] 🤖 Build (`build:`)
- [ ] 🔁 CI (`ci:`)
- [ ] 📦 Chore (`chore:`)
- [ ] ⏩ Revert (`revert:`)
- [ ] 🚀 Breaking Changes (`BREAKING CHANGE:`)
  • Loading branch information
gershon authored Sep 16, 2024
1 parent 1bcd652 commit b40ae78
Show file tree
Hide file tree
Showing 43 changed files with 1,196 additions and 471 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/createConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function createConfig({
starknetCurrencyContract = starknetEthContract
}: CreateConfigParameters): Config {
if (starknetNetwork === networks.dev && !starknetExecutorContract) {
throw new Error("starknetExecutorContract is required for dev network");
throw new Error("Executor contract address is required for dev network");
}

return {
Expand Down
122 changes: 0 additions & 122 deletions packages/core/tests/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import {
Account,
cairo,
CairoCustomEnum,
Call,
CallData,
Contract,
ProviderInterface
} from "starknet";
Expand Down Expand Up @@ -47,126 +45,6 @@ export function getTypeFromCairoCustomEnum(cairoCustomEnum: CairoCustomEnum) {
throw new Error("No valid variant found in CairoCustomEnum");
}

const mintERC20ABI = [
{
type: "function",
name: "mint",
inputs: [
{
name: "recipient",
type: "core::starknet::contract_address::ContractAddress"
},
{
name: "amount",
type: "core::integer::u256"
}
],
outputs: [],
state_mutability: "external"
}
];

export const mintERC20 = async ({
account,
amount = 1000
}: {
account: Account;
amount: number;
}) => {
const mintERC20Call: Call = {
contractAddress: config.starknetCurrencyContract,
entrypoint: "mint",
calldata: CallData.compile([account.address, cairo.uint256(amount)])
};

const result = await account.execute(mintERC20Call, [mintERC20ABI]);

await config.starknetProvider.waitForTransaction(result.transaction_hash, {
retryInterval: 1000
});

return result.transaction_hash;
};

const mintERC721ABI = [
{
type: "function",
name: "mint",
inputs: [
{
name: "recipient",
type: "core::starknet::contract_address::ContractAddress"
},
{ name: "token_uri", type: "core::felt252" }
],
outputs: [],
state_mutability: "external"
},
{
type: "function",
name: "get_current_token_id",
inputs: [],
outputs: [{ type: "core::felt252" }],
state_mutability: "view"
}
] as const;

export async function mintERC721({ account }: { account: Account }) {
const contract = new Contract(
mintERC721ABI,
contracts.nftContract,
config.starknetProvider
).typedv2(mintERC721ABI);
const tokenId = BigInt(await contract.get_current_token_id());

const mintCall: Call = {
contractAddress: contracts.nftContract,
entrypoint: "mint",
calldata: CallData.compile({
recipient: account.address,
token_uri: `https://api.everai.xyz/m/1`
})
};

const { transaction_hash } = await account.execute(mintCall, [mintERC721ABI]);

await config.starknetProvider.waitForTransaction(transaction_hash, {
retryInterval: 1000
});

return {
tokenId,
tokenAddress: contracts.nftContract
};
}

const balanceOfERC20ABI = [
{
type: "function",
name: "balanceOf",
inputs: [
{
name: "account",
type: "core::starknet::contract_address::ContractAddress"
}
],
outputs: [{ type: "core::integer::u256" }],
state_mutability: "view"
}
] as const;

export const getBalance = async ({ account }: { account: Account }) => {
const contract = new Contract(
balanceOfERC20ABI,
config.starknetCurrencyContract,
config.starknetProvider
).typedv2(balanceOfERC20ABI);

const balance = await contract.balanceOf(account.address);

return balance as bigint;
};

function fetchAccount(
provider: ProviderInterface,
address: string,
Expand Down
1 change: 1 addition & 0 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"license": "ISC",
"dependencies": {
"@ark-project/core": "workspace:*",
"@ark-project/test": "workspace:*",
"@starknet-react/chains": "^0.1.7",
"@starknet-react/core": "^2.8.1",
"@tanstack/react-query": "^5.55.4",
Expand Down
74 changes: 17 additions & 57 deletions packages/react/src/components/ArkProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,77 +1,37 @@
"use client";

import React, {
createContext,
PropsWithChildren,
useEffect,
useState
} from "react";
import React, { createContext, PropsWithChildren, useMemo } from "react";

import { useAccount, useNetwork, useProvider } from "@starknet-react/core";
import { useNetwork, useProvider } from "@starknet-react/core";

import {
Config,
createConfig,
CreateConfigParameters,
Network
CreateConfigParameters
} from "@ark-project/core";

import { getOwner } from "../lib/getOwner";

const OwnerDataContext = createContext<string | undefined>(undefined);
const ConfigDataContext = createContext<Config | undefined>(undefined);
const ArkContext = createContext<Config | undefined>(undefined);

export type ArkProviderProviderProps = {
config: CreateConfigParameters;
};

function ArkProvider(props: PropsWithChildren<ArkProviderProviderProps>) {
const { children, config: baseConfig } = props;
const [owner, setOwner] = useState<string | undefined>(undefined);
const { provider: starknetProvider } = useProvider();
const { chain: starknetChain } = useNetwork();
const [config, setConfig] = useState<Config>(
createConfig({
starknetProvider: starknetProvider,
starknetNetwork: baseConfig.starknetNetwork as Network
})
const { provider } = useProvider();
const { chain } = useNetwork();

const config = useMemo(
() =>
createConfig({
...baseConfig,
starknetProvider: provider,
starknetNetwork: baseConfig.starknetNetwork
}),
[chain, provider, baseConfig.starknetNetwork]
);

useEffect(() => {
const newConfig = createConfig({
starknetProvider: starknetProvider,
starknetNetwork: baseConfig.starknetNetwork as Network
});
setConfig(newConfig);
}, [starknetProvider, starknetChain, baseConfig]);

const { address, connector } = useAccount();

useEffect(() => {
const fetchOwner = async () => {
if (address && config.starknetProvider && connector?.id) {
const owner = await getOwner(
address,
config.starknetProvider,
connector?.id
);
if (Array.isArray(owner) && owner[0]) {
setOwner(owner[0]);
}
} else {
setOwner(undefined);
}
};
fetchOwner();
}, [address, config.starknetProvider, connector]);

return (
<ConfigDataContext.Provider value={config}>
<OwnerDataContext.Provider value={owner}>
{children}
</OwnerDataContext.Provider>
</ConfigDataContext.Provider>
);
return <ArkContext.Provider value={config}>{children}</ArkContext.Provider>;
}

export { ArkProvider, ConfigDataContext, OwnerDataContext };
export { ArkContext, ArkProvider };
22 changes: 15 additions & 7 deletions packages/react/src/hooks/useArkFees.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import { expect, it } from "vitest";
import { describe, expect, it } from "vitest";

import { renderHook } from "../test/react";
import { renderHook, waitFor } from "../../../test/src/react";
import { useArkFees } from "./useArkFees";

it("default", async () => {
const { result, rerender } = renderHook(() => useArkFees());
describe("useArkFees", () => {
it("default", async () => {
const { result } = renderHook(() => useArkFees());

expect(result.current.isSuccess).toBe(false);
rerender();
expect(result.current.isSuccess).toBe(true);
await waitFor(() => expect(result.current.isSuccess).toBe(true));

expect(result.current.data).toMatchInlineSnapshot(`
{
"denominator": 1n,
"formatted": "0.00",
"numerator": 0n,
}
`);
});
});
9 changes: 3 additions & 6 deletions packages/react/src/hooks/useArkFees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,17 @@ import { useConfig } from "./useConfig";

function useArkFees() {
const config = useConfig();
const query = useQuery({

return useQuery({
queryKey: ["getArkFees"],
queryFn: async () => {
if (!config) {
throw new Error("Config not found");
}

const fees = await getArkFees(config);

return fees;
return getArkFees(config);
}
});

return query;
}

export { useArkFees };
26 changes: 26 additions & 0 deletions packages/react/src/hooks/useBrokerFees.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { describe, expect, it } from "vitest";

import { accounts } from "@ark-project/test";

import { renderHook, waitFor } from "../../../test/src/react";
import { useBrokerFees } from "./useBrokerFees";

describe("useBrokerFees", () => {
it("default", async () => {
const { listingBroker } = accounts;

const { result } = renderHook(() =>
useBrokerFees({ brokerAdress: listingBroker.address })
);

await waitFor(() => expect(result.current.isSuccess).toBe(true));

expect(result.current.data).toMatchInlineSnapshot(`
{
"denominator": 1n,
"formatted": "0.00",
"numerator": 0n,
}
`);
});
});
9 changes: 3 additions & 6 deletions packages/react/src/hooks/useBrokerFees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,17 @@ interface UseBrokerFeesParams {

function useBrokerFees({ brokerAdress }: UseBrokerFeesParams) {
const config = useConfig();
const query = useQuery({

return useQuery({
queryKey: ["getBrokerFees", brokerAdress],
queryFn: async () => {
if (!config) {
throw new Error("Config not found");
}

const fees = await getBrokerFees(config, brokerAdress);

return fees;
return getBrokerFees(config, brokerAdress);
}
});

return query;
}

export { useBrokerFees };
Loading

0 comments on commit b40ae78

Please sign in to comment.