Documentation
Everything you need to integrate Awarizon — from a cold install to a live reward claim.
Introduction
Three tools cover the whole surface. awarizon.js is the general-purpose chain SDK — wallets, providers, signers, and every on-chain module (identity, assets, NFTs, DEX, campaigns, and more). @awarizon/app is a thin, purpose-built layer on top of it for one job: detecting a user who arrived from an Awarizon wallet inbox and claiming their engagement reward — three lines of code, no key management. @awarizon/kendra is a separate CLI toolchain for a different job entirely — writing, compiling, and deploying ink! smart contracts to Awarizon.
Installation
Install whichever SDK matches what you're building. awarizon.js re-exports @awarizon/sdk in full, so you never need to install that separately.
npm install awarizon.js
# Only if you're building a reward-earning app,
# not a full chain integration:
npm install @awarizon/appQuick Start
The core API is a Wallet / Provider / Signer model, deliberately shaped like ethers.js.
import { Wallet, Provider } from 'awarizon.js'
// Create a new wallet — mnemonic, address, and publicKey are
// always plain, readable properties.
const wallet = await Wallet.createRandom()
console.log(wallet.mnemonic, wallet.address)
// Read-only access to the chain — no wallet required.
const provider = await Provider.connect('wss://rpc.awarizon.com')
const balance = await provider.wallet.balance(wallet.address)
console.log(balance.free) // '0.0000 RIZ'
// Connect a wallet to the chain for read + write access.
const signer = await wallet.connect('wss://rpc.awarizon.com')
await signer.wallet.send('harry.riz', '10 RIZ')
await provider.disconnect()
await signer.disconnect()Wallet
Key material only — a Wallet never touches the network.
Wallet.createRandom(wordCount?: 12 | 24) // new random wallet
Wallet.fromMnemonic(phrase) // restore from seed phrase
wallet.encrypt(password, onProgress?) // -> encrypted JSON string
Wallet.fromEncryptedJson(json, password, onProgress?)
wallet.connect(endpoint?) // -> Signerwallet.mnemonic, wallet.address, and wallet.publicKey are always accessible, plain readonly properties. fromEncryptedJson cannot recover the original mnemonic — mnemonic will be '', matching ethers.js behavior.
Provider & Signer
Provider.connect(endpoint?) gives read-only chain access. wallet.connect(endpoint?) gives a Signer — everything a Provider has, plus write access signed by the wallet's keypair. Both expose the same modules:
| Module | Read | Write (Signer only) |
|---|---|---|
| wallet | balance(), totalSupply() | send() |
| inbox | list(), count() | engage(), claim(), dismiss() |
| identity | get(), resolve(), available(), total() | register(), update() |
| links | list(), evmMessage(), solanaMessage() | linkEvm(), linkSolana(), unlink() |
| developer | status() | register(), stake() |
| apps | list() | register() |
| campaigns | get(), stats(), activeCount() | create(), terminate(), deliver() |
| assets | balance(), metadata() | create(), mint(), transfer(), burn() |
| nfts | ownerOf() | createCollection(), mint(), transfer(), burn() |
| validators | list(), count(), performance() | register(), delegate(), undelegate(), updatePerformance() |
| network | stats(), block(), subscribe() | — |
| history | indexer-backed tx / campaign / DEX history — works pre-connect() | — |
| dex | quotes, pools, TWAP | swapExactIn(), addLiquidity(), createPool() |
Read methods work on both Provider and Signer. Write methods throw an AwarizonError with code NOT_SIGNED if called on a plain Provider.
Addresses accept either an SS58 address or a registered .riz name (e.g. signer.wallet.send('harry.riz', '10 RIZ')). Amounts accept a string, number, or bigint, with or without a RIZ suffix, and are always returned as formatted strings ('10.0000 RIZ').
React Hooks
awarizon.js/react exports a provider and a single hook that exposes every module, switching automatically between read-only and signed access depending on whether a wallet is connected.
import { AwarizonProvider, useAwarizon } from 'awarizon.js/react'
function App() {
return (
<AwarizonProvider endpoint="wss://rpc.awarizon.com">
<Balance />
</AwarizonProvider>
)
}
function Balance() {
const {
connected, connecting, error, address, signed,
connectWallet, disconnectWallet,
wallet, inbox, identity, links, developer,
apps, campaigns, assets, nfts, validators,
network, history, dex,
} = useAwarizon()
// wallet is read-only until connectWallet(walletInstance) is called
...
}awarizon.js/native re-exports the same AwarizonProvider / useAwarizon for React Native — neither touches a DOM API. Under Expo, @polkadot/util-crypto needs a native crypto.getRandomValues source — use expo-crypto, or react-native-get-random-values in a bare or dev-client build.
@awarizon/app
Zero-friction engagement SDK. Add a few lines of code — your users earn RIZ.
import { AwarizonApp } from '@awarizon/app'
const app = new AwarizonApp()
// Initialize once when your app loads
const user = await app.init()
if (user) {
console.log('User from Awarizon:', user.address)
}
// Option 1 — auto reward after 2 minutes
app.autoRewardAfter()
// Option 2 — reward after a specific event
app.rewardAfterEvents('level_complete', 1)
function onLevelComplete() {
app.trackEvent('level_complete')
}
// Option 3 — manual trigger
async function onUserFinishedReading() {
await app.triggerReward()
}How it works
- You create a campaign on developer.awarizon.com.
- Users receive your app in their Awarizon wallet inbox.
- The user opens the app — the SDK detects the campaign context automatically.
- The user engages with the app normally.
- Once the engagement threshold is met, the SDK calls
submit_engagement+claim_rewardautomatically. - The user sees a "You earned 1.5000 RIZ!" toast.
Engagement thresholds
The chain requires a minimum of 120 seconds in session and 5 interactions. The SDK tracks both automatically — the options accepted by triggerReward() exist for API symmetry, but the on-chain call always submits the chain's own minimum thresholds; there's nothing to override there.
Works with any app
React web, Vue / Angular, React Native (via WebView), Flutter (via WebView), games (Phaser, PixiJS, Unity WebGL) — or any website. No API key required; the campaign ID is the authentication, and the chain enforces every rule.
App Config
Passed as new AwarizonApp(config). Every field is optional.
| Option | Type | Description |
|---|---|---|
| rpc | string | wss://rpc.awarizon.com — chain RPC endpoint |
| showToasts | boolean | true — show built-in toast notifications |
| paramPrefix | string | 'riz' — URL param prefix, e.g. ?riz_address=... |
| context | Partial<AwarizonContext> | Manual context override, for testing |
| onUserDetected | (user: AwarizonUser) => void | Fires once the inbox context is detected |
| onRewardClaimed | (result: RewardResult) => void | Fires after a successful reward claim |
| onError | (error: Error) => void | Fires on any SDK-level failure |
App Methods
| Method | Description |
|---|---|
| init() | Detects campaign context and connects the wallet. Call once on app load. |
| getUser() | Returns the detected AwarizonUser, or null if not opened from the inbox. |
| isFromInbox() | Whether this session came from an Awarizon inbox delivery. |
| triggerReward(options?) | Manually claims the reward after genuine engagement. |
| autoRewardAfter(options?) | Claims automatically once time + interaction thresholds are met. |
| trackEvent(event) | Records a named event, e.g. app.trackEvent('level_complete'). |
| rewardAfterEvents(event, count) | Triggers a reward once an event has fired `count` times. |
| getSessionTime() | Seconds elapsed in the current session. |
| getInteractionCount() | Interactions tracked so far. |
| isEngagementEligible() | Whether session time + interactions already clear the chain minimum. |
| generateDeepLink(baseUrl) | Builds a deep link to include as your campaign manifest app_url. |
| destroy() | Clears timers/listeners and disconnects the signer. Call on unmount. |
Error Handling
Every failure — chain rejection, bad input, missing wallet — throws an AwarizonError with a stable .code.
import { AwarizonError } from 'awarizon.js'
try {
await provider.wallet.send(to, amount)
} catch (e) {
if (e instanceof AwarizonError && e.code === 'NOT_SIGNED') {
// provider has no wallet attached — connect one first
}
}Kendra CLI
@awarizon/kendra is the Hardhat of Awarizon — build, deploy, and test ink! smart contracts without touching Rust directly. Rust and cargo-contract are installed automatically on first compile; you only need Node.js to get started.
npm install -g @awarizon/kendra
# or without installing globally:
npx kendra init my_contractnpx kendra init my_contract
cd my_contract
npm install
# In one terminal:
kendra node
# In another terminal:
kendra compile
kendra deployKendra Commands
| Command | Description |
|---|---|
| kendra init [name] | Scaffold a new contract project — sample ink! contract, deploy script, and test file. |
| kendra compile [contract] | Compile ink! contracts to Wasm. Installs Rust + cargo-contract automatically if needed. Outputs to artifacts/ and generates types in typechain/. |
| kendra deploy [--network] [--contract] | Deploy compiled contracts to local, testnet, or mainnet. Saves addresses to deployments/<network>.json. |
| kendra node | Start a local Awarizon dev node (--dev mode, RPC at ws://127.0.0.1:9944). |
| kendra accounts [list|generate] | List dev accounts (//Alice, //Bob, ...) or generate a new random one. |
| kendra call <contract> <method> [args] | Call a deployed contract method — coming in a future release. |
Networks
| Network | Endpoint |
|---|---|
| local | ws://127.0.0.1:9944 |
| testnet | wss://testnet.awarizon.com |
| mainnet | wss://rpc.awarizon.com |
Kendra Config & API
Every project has a kendra.config.ts defining networks, contracts, and compiler options.
import { defineConfig } from '@awarizon/kendra'
import * as dotenv from 'dotenv'
dotenv.config()
export default defineConfig({
networks: {
local: {
endpoint: 'ws://127.0.0.1:9944',
accounts: ['//Alice'],
},
testnet: {
endpoint: 'wss://testnet.awarizon.com',
accounts: [process.env.DEPLOYER_MNEMONIC ?? ''],
},
mainnet: {
endpoint: 'wss://rpc.awarizon.com',
accounts: [process.env.DEPLOYER_MNEMONIC ?? ''],
},
},
contracts: {
MyToken: 'contracts/my_token',
},
compiler: {
optimization: true,
},
typechain: {
outDir: 'typechain',
},
defaultNetwork: 'local',
})Use kendra directly from deploy scripts or tests instead of the CLI:
import { kendra } from '@awarizon/kendra'
const [alice] = await kendra.getAccounts()
const result = await kendra.deploy('MyContract', [42], {
signer: alice,
network: 'local',
})
console.log('Deployed to:', result.address)After compiling, Kendra generates TypeScript types for every contract in typechain/ — typed query and transaction methods, so calling a contract from a script or test is fully type-checked without writing the bindings by hand.
Token List
A single canonical JSON feed of every asset created via pallet-assets — symbol, name, decimals, and logo — so wallets, DEXes, and explorers don't each invent their own lookup. Same idea as Solana's token-list project.
Open to every origin (Access-Control-Allow-Origin: *) — fetch it directly from a browser, no proxy needed:
https://developer.awarizon.com/api/assetlist.json{
"name": "Awarizon Token List",
"logoURI": "https://developer.awarizon.com/logo.png",
"keywords": ["awarizon", "riz", "pallet-assets"],
"timestamp": "2026-07-17T06:42:12.841Z",
"tokens": [
{
"chainId": 1,
"address": "2",
"symbol": "CORE",
"name": "Core",
"decimals": 12,
"logoURI": "https://...",
"tags": [],
"extensions": { "website": "...", "description": "..." }
}
]
}address is the pallet-assets asset ID, stringified for shape-compatibility with the EVM/SPL mint-address convention — Awarizon assets have no contract address of their own.
