@niklasp/use-inkathon
v0.10.3
Published
Typesafe React Hooks abstracting functionality by polkadot.js for working with Substrate-based networks and ink! Smart Contracts.
Downloads
2
Readme
useInkathon
– React Hooks & Utility Library
This library provides typesafe React hooks and utility functions that simplify the process of working with Substrate-based networks and ink! smart contracts. It abstracts away the complexities of polkadot{.js} but still lets you access the full power of the underlying API.
The project is part of a Scio Labs initiative to improve the developer experience in the ink! ecosystem and a proud member of the Aleph Zero EFP. 💜
Other projects include:
create-ink-app
CLI (Coming soon)ink!athon
BoilerplateuseInkathon
Hooks & Utility Libraryzink!
Smart Contract Macros
Join the discussion in our Telegram Group 💬
Checkout our TypeDoc Documentation 📃
Getting started 🚀
[!IMPORTANT]
If you are looking for a boilerplate to start your dApp project from scratch, checkout ink!athon.
- Go to your existing project and install the package from the npm registry:
pnpm add @scio-labs/use-inkathon
# or
npm install @scio-labs/use-inkathon
# or
yarn add @scio-labs/use-inkathon
- Wrap it around your app or parent component:
import { development, UseInkathonProvider } from '@scio-labs/use-inkathon'
<UseInkathonProvider appName="My dApp" defaultChain={development}>
<Component {...pageProps} />
</UseInkathonProvider>
- Use the primary
useInkathon
hook for connecting the wallet or accessing the API:
import { useInkathon } from '@scio-labs/use-inkathon'
const { api, connect, activeChain, activeAccount, … } = useInkathon()
Features ✨
At its core, this library serves as a wrapper for polkadot{.js}, potentially saving you over 100 lines of code. This includes:
- Utility functions for API initialization, connection, account management, balance checks, transfers, contract interactions, etc.
- React hooks & provider for easy access to all of the above, including:
useInkathon
– Main Hook responsible for connection, account management, etc.useBalance
usePSP22Balances
useContract
useRegisteredContract
(read more below)
- Contract interaction helper functions with automatic upfront gas estimation, including:
- 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
viauseRegisteredTypedContract
[!NOTE]
Checkout our TypeDoc Documentation for more details.
Contract Registry 🗳️
Often when working with smart contracts in the frontend, you have to import the contract metadata multiple times across a project, then determine the matching deployment address for the active chain, and create a ContractPromise
instance manually each time.
The idea of a Contract Registry is to define contract metadata & addresses only once and use them everywhere with a simple hook:
const { contract } = useRegisteredContract('greeter')
How it works
Start by defining an async getDeployments
function that returns SubstrateDeployment[]
metadata objects for each contract deployment on each chain.
[!NOTE]
Checkout an advanced example within the ink!athon boilerplate here where metadata is imported dynamically based on defined chains and contract identifiers.
import { alephzeroTestnet, SubstrateDeployment } from '@scio-labs/use-inkathon'
export const getDeployments = async (): Promise<SubstrateDeployment[]> => {
return [
{
contractId: 'greeter',
networkId: alephzeroTestnet.network,
abi: await import(`../deployments/metadata.json`),
address: '5HPwzKmJ6wgs18BEcLdH5P3mULnfnowvRzBtFcgQcwTLVwFc',
},
]
}
The function's result passed to the UseInkathonProvider
provider:
<UseInkathonProvider
appName="My dApp"
defaultChain={alephzeroTestnet}
deployments={getDeployments()}
>
<Component {...pageProps} />
</UseInkathonProvider>
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 theink!athon boilerplate
.
If you are using typechain-polkadot
to generate type-safe contracts, you can use the useRegisteredTypedContract
hook instead:
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 is merged. Alternatively, we're considering switching to theprosopo/typechain-polkadot
fork completely.
Examples 📚
Within this repository:
- Vanilla React Example (
examples/react-ts
) - Vanilla CLI Scripts Example (
examples/scripts-ts
)
Live examples:
Package Development 🛠
If you want to contribute, please read our Contributor Guidelines 🙏
Pre-requisites:
- Setup Node.js v18 (recommended via nvm)
- Install pnpm (recommended via Node.js Corepack)
- Clone this repository
# Install dependencies
pnpm i
# Enable pre-commit hooks
pnpm simple-git-hooks
# Run tsup in development mode (watching)
pnpm dev
# Run package compilation in parallel with vanilla React example
pnpm run dev:react-example
# Build the package
pnpm build
Unfortunately, importing this package locally into other local projects requires some manual steps. You need to build & pack this package into a .tgz
-build and then update this dependency in your other project. These steps must be repeated each time you make changes to this package.
# 1. [THIS PACKAGE] Generate a .tgz package of the build
pnpm tsup && pnpm pack
# 2. [OTHER PROJECT] Add it as a dependency in your other project like:
# `"@scio-labs/use-inkathon": "file:../scio-labs-use-inkathon-0.0.X.tgz"`
pnpm add ../use-inkathon/scio-labs-use-inkathon-0.0.X.tgz
# 3. [OTHER PROJECT] Subsequent updates can be done via
pnpm update @scio-labs/use-inkathon --force