Skip to content

Commit

Permalink
feat: generate rtk hooks with @graphql-codegen/cli
Browse files Browse the repository at this point in the history
  • Loading branch information
nezz0746 committed Dec 4, 2023
1 parent dba3b4f commit b329644
Show file tree
Hide file tree
Showing 29 changed files with 3,954 additions and 164 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ apps/subgraph/subgraph.yaml
apps/subgraph/build
apps/contracts/data

packages/kit/operations.graphql

## Hardhat files ##
packages/hardhat/*.txt
packages/hardhat/cache
Expand Down
2 changes: 1 addition & 1 deletion apps/contracts/deployments/1337/Counter.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"address":"0x2dE080e97B0caE9825375D31f5D0eD5751fDf16D"}
{"address":"0xbCF26943C0197d2eE0E5D05c716Be60cc2761508"}
1 change: 0 additions & 1 deletion apps/contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"scripts": {
"test": "forge test",
"chain": "rm -rf ./data && docker-compose up",
"dev": "anvil --chain-id 1337",
"deploy:local": "forge script CounterScript -s 'deployCounterLocal()' --broadcast",
"deploy:testnets": "forge script CounterScript -s 'deployCounterTesnet()' --broadcast --verify",
"build": "forge compile"
Expand Down
2 changes: 1 addition & 1 deletion apps/subgraph/config/1337.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"counterAddress": "0x2dE080e97B0caE9825375D31f5D0eD5751fDf16D",
"counterAddress": "0xbCF26943C0197d2eE0E5D05c716Be60cc2761508",
"startBlock": 0,
"network": "localhost"
}
55 changes: 55 additions & 0 deletions apps/subgraph/generated/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,61 @@ import {
BigDecimal
} from "@graphprotocol/graph-ts";

export class Number extends Entity {
constructor(id: Bytes) {
super();
this.set("id", Value.fromBytes(id));
}

save(): void {
let id = this.get("id");
assert(id != null, "Cannot save Number entity without an ID");
if (id) {
assert(
id.kind == ValueKind.BYTES,
`Entities of type Number must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`
);
store.set("Number", id.toBytes().toHexString(), this);
}
}

static loadInBlock(id: Bytes): Number | null {
return changetype<Number | null>(
store.get_in_block("Number", id.toHexString())
);
}

static load(id: Bytes): Number | null {
return changetype<Number | null>(store.get("Number", id.toHexString()));
}

get id(): Bytes {
let value = this.get("id");
if (!value || value.kind == ValueKind.NULL) {
throw new Error("Cannot return null for a required field.");
} else {
return value.toBytes();
}
}

set id(value: Bytes) {
this.set("id", Value.fromBytes(value));
}

get value(): BigInt {
let value = this.get("value");
if (!value || value.kind == ValueKind.NULL) {
throw new Error("Cannot return null for a required field.");
} else {
return value.toBigInt();
}
}

set value(value: BigInt) {
this.set("value", Value.fromBigInt(value));
}
}

export class NumberSet extends Entity {
constructor(id: Bytes) {
super();
Expand Down
5 changes: 5 additions & 0 deletions apps/subgraph/schema.graphql
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
type Number @entity(immutable: false) {
id: Bytes!
value: BigInt! # uint256
}

type NumberSet @entity(immutable: true) {
id: Bytes!
newValue: BigInt! # uint256
Expand Down
94 changes: 52 additions & 42 deletions apps/subgraph/src/counter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,95 +4,105 @@ import {
Initialized as InitializedEvent,
NumberSet as NumberSetEvent,
OwnershipTransferred as OwnershipTransferredEvent,
Upgraded as UpgradedEvent
} from "../generated/Counter/Counter"
Upgraded as UpgradedEvent,
} from "../generated/Counter/Counter";
import {
AdminChanged,
BeaconUpgraded,
Initialized,
Number,
NumberSet,
OwnershipTransferred,
Upgraded
} from "../generated/schema"
Upgraded,
} from "../generated/schema";

export function handleAdminChanged(event: AdminChangedEvent): void {
let entity = new AdminChanged(
event.transaction.hash.concatI32(event.logIndex.toI32())
)
entity.previousAdmin = event.params.previousAdmin
entity.newAdmin = event.params.newAdmin
);
entity.previousAdmin = event.params.previousAdmin;
entity.newAdmin = event.params.newAdmin;

entity.blockNumber = event.block.number
entity.blockTimestamp = event.block.timestamp
entity.transactionHash = event.transaction.hash
entity.blockNumber = event.block.number;
entity.blockTimestamp = event.block.timestamp;
entity.transactionHash = event.transaction.hash;

entity.save()
entity.save();
}

export function handleBeaconUpgraded(event: BeaconUpgradedEvent): void {
let entity = new BeaconUpgraded(
event.transaction.hash.concatI32(event.logIndex.toI32())
)
entity.beacon = event.params.beacon
);
entity.beacon = event.params.beacon;

entity.blockNumber = event.block.number
entity.blockTimestamp = event.block.timestamp
entity.transactionHash = event.transaction.hash
entity.blockNumber = event.block.number;
entity.blockTimestamp = event.block.timestamp;
entity.transactionHash = event.transaction.hash;

entity.save()
entity.save();
}

export function handleInitialized(event: InitializedEvent): void {
let entity = new Initialized(
event.transaction.hash.concatI32(event.logIndex.toI32())
)
entity.version = event.params.version
);
entity.version = event.params.version;

entity.blockNumber = event.block.number
entity.blockTimestamp = event.block.timestamp
entity.transactionHash = event.transaction.hash
entity.blockNumber = event.block.number;
entity.blockTimestamp = event.block.timestamp;
entity.transactionHash = event.transaction.hash;

entity.save()
entity.save();
}

export function handleNumberSet(event: NumberSetEvent): void {
let number = Number.load(event.address);

if (number == null) {
number = new Number(event.address);
}

number.value = event.params.newValue;
number.save();

let entity = new NumberSet(
event.transaction.hash.concatI32(event.logIndex.toI32())
)
entity.newValue = event.params.newValue
);
entity.newValue = event.params.newValue;

entity.blockNumber = event.block.number
entity.blockTimestamp = event.block.timestamp
entity.transactionHash = event.transaction.hash
entity.blockNumber = event.block.number;
entity.blockTimestamp = event.block.timestamp;
entity.transactionHash = event.transaction.hash;

entity.save()
entity.save();
}

export function handleOwnershipTransferred(
event: OwnershipTransferredEvent
): void {
let entity = new OwnershipTransferred(
event.transaction.hash.concatI32(event.logIndex.toI32())
)
entity.previousOwner = event.params.previousOwner
entity.newOwner = event.params.newOwner
);
entity.previousOwner = event.params.previousOwner;
entity.newOwner = event.params.newOwner;

entity.blockNumber = event.block.number
entity.blockTimestamp = event.block.timestamp
entity.transactionHash = event.transaction.hash
entity.blockNumber = event.block.number;
entity.blockTimestamp = event.block.timestamp;
entity.transactionHash = event.transaction.hash;

entity.save()
entity.save();
}

export function handleUpgraded(event: UpgradedEvent): void {
let entity = new Upgraded(
event.transaction.hash.concatI32(event.logIndex.toI32())
)
entity.implementation = event.params.implementation
);
entity.implementation = event.params.implementation;

entity.blockNumber = event.block.number
entity.blockTimestamp = event.block.timestamp
entity.transactionHash = event.transaction.hash
entity.blockNumber = event.block.number;
entity.blockTimestamp = event.block.timestamp;
entity.transactionHash = event.transaction.hash;

entity.save()
entity.save();
}
1 change: 1 addition & 0 deletions apps/subgraph/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ dataSources:
- BeaconUpgraded
- Initialized
- NumberSet
- Number
- OwnershipTransferred
- Upgraded
abis:
Expand Down
9 changes: 8 additions & 1 deletion apps/web/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
{
"extends": "next/core-web-vitals"
"extends": [
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"rules": {
"@typescript-eslint/ban-ts-comment": "off"
}
}
7 changes: 7 additions & 0 deletions apps/web/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"semi": false,
"trailingComma": "es5",
"singleQuote": true,
"tabWidth": 2,
"useTabs": false
}
5 changes: 4 additions & 1 deletion apps/web/components/DappProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { RainbowKitProvider } from "@rainbow-me/rainbowkit";
import { AppProvider } from "kit";
import { WagmiConfig } from "wagmi";
import { chains, wagmiConfig } from "wagmi-config";

Expand All @@ -9,7 +10,9 @@ type DappProviderProps = {
const DappProvider = ({ children }: DappProviderProps) => {
return (
<WagmiConfig config={wagmiConfig}>
<RainbowKitProvider chains={chains}>{children}</RainbowKitProvider>
<RainbowKitProvider chains={chains}>
<AppProvider>{children}</AppProvider>
</RainbowKitProvider>
</WagmiConfig>
);
};
Expand Down
2 changes: 1 addition & 1 deletion apps/web/hooks/useChain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { localhost } from "wagmi/chains";
const useChain = () => {
const { chain } = useNetwork();

const chainId = chain?.id ?? defaultChain;
const chainId = chain?.id ?? defaultChain.id;

return {
isLocal: chainId === localhost.id,
Expand Down
84 changes: 84 additions & 0 deletions apps/web/hooks/useIndexed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { Exact, InputMaybe, Scalars } from 'kit'
import { UseQuery } from '@reduxjs/toolkit/dist/query/react/buildHooks'
import { QueryDefinition } from '@reduxjs/toolkit/query'
import { useEffect, useState } from 'react'
import { useContractWrite, useWaitForTransaction } from 'wagmi'
import useChain from './useChain'
import { PrepareWriteContractResult } from 'wagmi/dist/actions'

const useIndexedTransaction = <SubgraphQuery>(
config: PrepareWriteContractResult,
useQuery: UseQuery<
QueryDefinition<
{
variables: Exact<{
where?: InputMaybe<{
transactionHash?: InputMaybe<Scalars['Bytes']['input']>
}>
}>
chainId?: number | undefined
},
any,
never,
SubgraphQuery,
'subgraphAPI'
>
>,
selectFromResult: (result: SubgraphQuery) => {
indexed: boolean
},
onSuccessfulIndexing?: () => void
) => {
const { chainId } = useChain()
const [polling, setPolling] = useState(false)

const {
data,
write,
isLoading: confirmationPending,
} = useContractWrite(config)

const { isSuccess: transactionSucess, isLoading: transactionPending } =
useWaitForTransaction({
hash: data?.hash,
})

const { indexed } = useQuery(
{ variables: { where: { transactionHash: data?.hash } }, chainId },
{
pollingInterval: polling ? 2000 : 0,
skip: !polling || !Boolean(data?.hash),
selectFromResult: (result) => {
if (!result.data) {
return { indexed: false }
}
const { indexed } = selectFromResult(result.data)
return {
indexed,
}
},
}
)

useEffect(() => {
if (transactionSucess) {
setPolling(true)
}
}, [transactionSucess])

useEffect(() => {
if (indexed) {
onSuccessfulIndexing?.()
setPolling(false)
}
}, [indexed])

return {
loading: confirmationPending || transactionPending || polling,
execute: () => {
write && write()
},
}
}

export default useIndexedTransaction
Loading

0 comments on commit b329644

Please sign in to comment.