Skip to content

Commit

Permalink
Merge pull request #57 from scio-labs/feat/27-typechain-integration
Browse files Browse the repository at this point in the history
Feat/27 typechain integration
  • Loading branch information
wottpal authored Jan 24, 2024
2 parents 10a3ab2 + 1d54238 commit 036117f
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/spicy-geckos-love.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@scio-labs/use-inkathon': minor
---

Add support for type-safe contract-interactions via `typechain-polkadot`. A new hook `useRegisteredTypedContract` enables easy instantiation with automatic assignment of api instance, network-dependant contract address, and the connected signer. Currently, only queries (read-only) are supported with those instances. – See README.md for more information.
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ Other projects include:

1. [Getting started 🚀](#getting-started-)
2. [Features ✨](#features-)
3. [Contract Registry 🗳️](#contract-registry-️)
3. [Contract Registry 🗳️](#contract-registry-️%EF%B8%8F)
1. [How it works](#how-it-works)
2. [Typed Contracts](#typed-contracts)
4. [Examples 📚](#examples-)
5. [Package Development 🛠](#package-development-)

Expand Down Expand Up @@ -87,6 +88,7 @@ At its core, this library serves as a **wrapper for polkadot{.js}, potentially s
- [`decodeOutput`](https://scio-labs.github.io/use-inkathon/functions/decodeOutput.html)
- Constants definitions for Substrate-based chains, wallets, and assets
- Works multichain with live & dynamic chain-switching out of the box
- Full contract-level type-safety with [`typechain-polkadot`](https://github.com/Brushfam/typechain-polkadot) via [`useRegisteredTypedContract`](https://scio-labs.github.io/use-inkathon/functions/useRegisteredTypedContract.html)

> [!NOTE]
> Checkout our [TypeDoc Documentation](https://scio-labs.github.io/use-inkathon/) for more details.
Expand Down Expand Up @@ -141,6 +143,25 @@ Then access the contract as above:
const { contract } = useRegisteredContract('greeter')
```

### Typed Contracts

> [!NOTE]
> Make sure to also install `@727-ventures/typechain-types`, `bn.js`, and `@types/bn.js` as dependencies in your project. Find a complete setup & usage example in the [`ink!athon boilerplate`](https://github.com/scio-labs/inkathon).
If you are using [`typechain-polkadot`](https://github.com/Brushfam/typechain-polkadot) to generate type-safe contracts, you can use the `useRegisteredTypedContract` hook instead:

```ts
import GreeterContract from '[…]/typed-contracts/contracts/greeter'

//

const { typedContract } = useRegisteredTypedContract('greeter', GreeterContract)
const result = await typedContract.query.greet()
```

> [!IMPORTANT]
> Currently, only queries are supported until [typechain-polkadot#138](https://github.com/Brushfam/typechain-polkadot/pull/138) is merged. Alternatively, we're considering switching to the [`prosopo/typechain-polkadot`](https://github.com/prosopo/typechain-polkadot) fork completely.
## Examples 📚

Within this repository:
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"@polkadot/api": ">=10",
"@polkadot/api-contract": ">=10",
"@polkadot/extension-inject": ">=0.46",
"@polkadot/keyring": ">=10",
"@polkadot/types": ">=10",
"@polkadot/util": ">=10",
"@polkadot/util-crypto": ">=10",
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export * from './useBalance'
export * from './useContract'
export * from './usePSP22Balances'
export * from './useRegisteredContract'
export * from './useRegisteredTypedContract'
// @endindex
4 changes: 2 additions & 2 deletions src/hooks/useRegisteredContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { useContract } from './useContract'

/**
* React Hook that returns a `ContractPromise` object configured with
* the active api & chain as well as the given deployment contract id
* which is looked up from the deployments registry.
* the active api & chain with the given deployment contract id which
* is looked up from the deployments registry.
*/
export const useRegisteredContract = (contractId: string, networkId?: string) => {
const { deployments, activeChain } = useInkathon()
Expand Down
37 changes: 37 additions & 0 deletions src/hooks/useRegisteredTypedContract.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useRegisteredContract } from '@/hooks/useRegisteredContract'
import { useInkathon } from '@/provider'
import { TypechainContractConstructor } from '@/types'
import { useEffect, useState } from 'react'

/**
* React Hook that returns a type-safe contract object by `typechain-polkadot`,
* configured with the active api & chain for the given deployment contract id
* which is looked up from the deployments registry.
*/
export const useRegisteredTypedContract = <T>(
contractId: string,
Contract: TypechainContractConstructor<T>,
networkId?: string,
) => {
const { api, activeAccount } = useInkathon()
const registeredContract = useRegisteredContract(contractId, networkId)

const [typedContract, setTypedContract] = useState<T | undefined>(undefined)
useEffect(() => {
if (!registeredContract?.address || !activeAccount?.address || !api) {
setTypedContract(undefined)
return
}

// IMPORTANT: Right now, only KeyringPair is supported as signer, but as we don't have
// those anyways in the frontend, we can alreaday start using the new API.
const typedContract = new Contract(
registeredContract.address.toString(),
activeAccount.address as any,
api,
)
setTypedContract(typedContract)
}, [registeredContract?.address, activeAccount?.address])

return { ...registeredContract, typedContract }
}
8 changes: 8 additions & 0 deletions src/types/TypechainContractConstructor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ApiPromise } from '@polkadot/api'
import { KeyringPair } from '@polkadot/keyring/types'

export type TypechainContractConstructor<T> = new (
address: string,
signer: KeyringPair,
nativeAPI: ApiPromise,
) => T
1 change: 1 addition & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export * from './DeployedContract'
export * from './SubstrateChain'
export * from './SubstrateDeployment'
export * from './SubstrateWallet'
export * from './TypechainContractConstructor'
export * from './UseInkathonProviderContext'
// @endindex

0 comments on commit 036117f

Please sign in to comment.