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
npm install awarizon.js

# Only if you're building a reward-earning app,
# not a full chain integration:
npm install @awarizon/app

Quick Start

The core API is a Wallet / Provider / Signer model, deliberately shaped like ethers.js.

quickstart.ts
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?)                      // -> Signer

wallet.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:

ModuleReadWrite (Signer only)
walletbalance(), totalSupply()send()
inboxlist(), count()engage(), claim(), dismiss()
identityget(), resolve(), available(), total()register(), update()
linkslist(), evmMessage(), solanaMessage()linkEvm(), linkSolana(), unlink()
developerstatus()register(), stake()
appslist()register()
campaignsget(), stats(), activeCount()create(), terminate(), deliver()
assetsbalance(), metadata()create(), mint(), transfer(), burn()
nftsownerOf()createCollection(), mint(), transfer(), burn()
validatorslist(), count(), performance()register(), delegate(), undelegate(), updatePerformance()
networkstats(), block(), subscribe()
historyindexer-backed tx / campaign / DEX history — works pre-connect()
dexquotes, pools, TWAPswapExactIn(), 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.

App.tsx
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.

quickstart.ts
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

  1. You create a campaign on developer.awarizon.com.
  2. Users receive your app in their Awarizon wallet inbox.
  3. The user opens the app — the SDK detects the campaign context automatically.
  4. The user engages with the app normally.
  5. Once the engagement threshold is met, the SDK calls submit_engagement + claim_reward automatically.
  6. 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.

OptionTypeDescription
rpcstringwss://rpc.awarizon.com — chain RPC endpoint
showToastsbooleantrue — show built-in toast notifications
paramPrefixstring'riz' — URL param prefix, e.g. ?riz_address=...
contextPartial<AwarizonContext>Manual context override, for testing
onUserDetected(user: AwarizonUser) => voidFires once the inbox context is detected
onRewardClaimed(result: RewardResult) => voidFires after a successful reward claim
onError(error: Error) => voidFires on any SDK-level failure

App Methods

MethodDescription
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.

install
npm install -g @awarizon/kendra

# or without installing globally:
npx kendra init my_contract
quick start (5 minutes)
npx kendra init my_contract
cd my_contract
npm install

# In one terminal:
kendra node

# In another terminal:
kendra compile
kendra deploy

Kendra Commands

CommandDescription
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 nodeStart 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

NetworkEndpoint
localws://127.0.0.1:9944
testnetwss://testnet.awarizon.com
mainnetwss://rpc.awarizon.com

Kendra Config & API

Every project has a kendra.config.ts defining networks, contracts, and compiler options.

kendra.config.ts
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:

scripts/deploy.ts
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:

GET
https://developer.awarizon.com/api/assetlist.json
response shape
{
  "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.