Overview
ViewPallet is a platform on the Bittensor blockchain for indexing ink! smart contracts, subscribing to on-chain events via webhooks, and trading PSP22 tokens peer-to-peer through an OTC marketplace.
What ViewPallet Does
- Contract indexing — Register any deployed ink! contract to index its events, transactions, and (for token contracts) holder balances in real time. The indexer processes finalized blocks and decodes
ContractEmittedevents using your contract's ABI. - Webhooks — Subscribe to on-chain events and receive HTTP POST deliveries to your endpoint. Two kinds of events are supported: native TAO transfers (with sender, receiver, and amount filters) and contract events (admin-curated per contract). Each delivery includes an HMAC-SHA256 signature for verification.
- OTC marketplace — Create and fill peer-to-peer swap orders between native TAO and PSP22 tokens. Orders follow a deposit-then-payout flow with on-chain confirmation at each step.
Architecture at a Glance
| Component | Description |
|---|---|
| Indexer | Connects to Bittensor via WebSocket, processes finalized blocks, decodes events/transactions, updates balances, matches webhooks and OTC deposits |
| API Server | REST API — auth, subscriptions, invoices, webhook CRUD, OTC order management, admin endpoints |
| Explorer | Public read-only views of blocks, transactions, events, addresses, contracts, and tokens |
| Oracle | On-chain price feed (multi-reporter with round-based commitment), used for TAO/USD conversion |
Getting Started
Ready to use ViewPallet? Go to the dashboard to connect your wallet and get started.
Public resource
This documentation page is publicly accessible. No wallet connection is required to read it.
Subscription Tiers
ViewPallet offers two paid subscription plans — NORMAL and PRO — plus a free GUEST tier for exploring the platform. Subscriptions are paid in TAO (the native currency of Bittensor) and billed monthly or yearly.
Plan Comparison
| Feature | NORMAL | PRO |
|---|---|---|
| Explorer access | ||
| Webhook endpoints | 1 | 5 |
| Contract registrations | 1 | Up to 5 |
| Webhook event types | All enabled events | All enabled events |
| OTC order creation | ||
| OTC order management | ||
| Delivery queue | Standard | Priority |
| HMAC-SHA256 signatures | ||
| Support | Community | Priority |
| Billing | Monthly or yearly | Monthly or yearly |
Pricing
Pricing is set in TAO and locked at invoice creation. The TAO/USD rate is sourced from the on-chain oracle.
1 TAO| Plan | Monthly | Yearly |
|---|---|---|
| NORMAL | 0.05 TAO | 0.5 TAO |
| PRO | 0.1 TAO | 1 TAO |
Yearly billing gives you 2 months free compared to monthly billing.
Warning
Invoices expire after 30 minutes. If you don't send the TAO transfer before expiry, the invoice is cancelled and you'll need to create a new one. Always use the block hash (not the transaction hash) when confirming payment — this avoids issues with hardware wallets like Ledger, which may report different extrinsic hashes.
How Billing Works
- Choose a plan and billing cycle from the Subscription page
- An invoice is created with the TAO amount and the admin wallet address
- Send the exact TAO amount to the address shown on the invoice
- Capture the block hash from your wallet after the transfer confirms
- Submit the block hash to confirm payment
- The indexer detects your transfer on-chain and activates your subscription
All payments are processed on-chain. There is no off-chain payment rail.
Contract Indexing
Register any deployed ink! smart contract on Bittensor to index its events, transactions, and metadata. For token contracts implementing the PSP22 standard, the indexer also maintains a real-time balance sheet of all holders.
Registration Workflow
- 1
Register
Submit your contract's address, display name, ABI JSON, and deployment block number via the Contracts page. Mark the "Token" checkbox if the contract implements the PSP22 standard. - 2
Admin Review
An admin reviews your submission. The contract status is set to pending_review. Admins verify the ABI, check for PSP22 traits, and confirm the deployment block. - 3
Approval
Once approved, the status changes to approved. The indexer picks up the contract and begins indexing events from the deployment block forward. The contract appears in your "My Contracts" list. - 4
Indexing Active
Events and transactions are decoded in real time as blocks are finalized. For token contracts, holder balances are maintained incrementally from transfer events. The sidebar sync indicator shows the latest indexed block.
Token Contracts
When a contract is flagged as a token (isToken: true), the indexer provides additional capabilities:
- Balance sheet — A complete ledger of every holder's balance, updated incrementally from PSP22
Transferevents - Holder list — View all token holders with their balances on the explorer
- Transfer history — Every token transfer is indexed and searchable
- Token metadata — Name, symbol, decimals, and image URL are fetched from the contract
The system detects PSP22 support by checking the contract's ABI for standard PSP22 trait signatures. Token contracts also become eligible for OTC trading (after admin enables the otcEnabled flag).
Info
The otcEnabled flag determines whether a token appears in the OTC marketplace. Even after contract approval, OTC trading requires a separate admin action to set this flag. See the OTC Token Enabling section below.
Contract Statuses
| Status | Meaning |
|---|---|
Active (approved + isActive: true) | Contract is approved and being actively indexed. Events, transactions, and (if token) balances are updated in real time. |
Pending Review (pending_review) | Contract has been submitted but not yet reviewed by an admin. No indexing occurs. |
Rejected (rejected) | Admin has rejected the contract. The contract won't be indexed. |
Inactive (isActive: false) | Contract has been deactivated by the user or admin. Indexing is paused. |
Contract Limits
Your subscription tier determines how many contracts you can register:
| Tier | Max Contracts |
|---|---|
| GUEST | 0 |
| NORMAL | 1 |
| PRO | 5 |
You can view your current usage and limit on the Contracts page.
Webhook Implementation
Webhooks deliver real-time on-chain events to your HTTP endpoints via POST requests. ViewPallet supports two kinds of webhooks: native TAO events and contract events.
Webhook Kinds
Native TAO Events
Subscribe to native TAO transfers (balances.Transfer events) on Bittensor. You can filter by:
| Filter | Description |
|---|---|
senderAddress | Only match transfers from this SS58 address |
receiverAddress | Only match transfers to this SS58 address |
minValue | Only match transfers with amount ≥ this value (in Planck) |
Every TAO transfer that matches your filters produces a delivery to your webhook URL.
Contract Events
Subscribe to specific events emitted by registered ink! contracts. Events must be admin-curated — an admin selects which contract events are "subscribable" from the contract's ABI before users can attach webhooks to them.
Each webhook is attached to a single event on a single contract. When that event is emitted on-chain, a delivery is triggered.
Info
Only admin-approved events appear in the available events list. If you need an event that isn't available, contact support to request it.
Delivery Flow
- 1
Event detected
The indexer processes a finalized block and decodes a ContractEmitted event (or balances.Transfer for native TAO) matching your webhook's filters. - 2
Delivery job created
A delivery job is created with status pending and enqueued to BullMQ for processing. - 3
HTTP POST with HMAC signature
The job worker sends an HTTP POST to your webhookUrl. The request body is signed with HMAC-SHA256 using your secretKey. The signature is included in the X-ViewPallet-Signature header. - 4
Retry on failure
If the delivery fails (non-2xx response or network error), it is retried up to 3 times with exponential backoff: 30 seconds, 2 minutes, 5 minutes. - 5
Final status
After all retries: status becomes delivered (2xx response received) or failed (all retries exhausted).
Verifying Deliveries
Every webhook delivery includes an X-ViewPallet-Signature header containing the HMAC-SHA256 hex digest of the raw request body, keyed by your webhook's secretKey.
To verify a delivery:
1. Take the raw request body (as bytes)
2. Compute HMAC-SHA256(body, yourSecretKey)
3. Compare the hex digest against the X-ViewPallet-Signature header
4. If they match, the delivery is authenticRequest Body Schema
{
"blockNumber": 1234567,
"kind": "contract_event",
"eventSummary": "Transfer(from, to, value)",
"deliveryId": "d_abc123",
"contractAddress": "5GrwvaEF...",
"eventName": "Transfer",
"args": {
"from": "5GrwvaEF...",
"to": "5FHneW46...",
"value": "1000000000000"
}
}Webhook Limits
| Tier | Max Endpoints |
|---|---|
| GUEST | 0 |
| NORMAL | 1 |
| PRO | 5 |
Each endpoint can be configured with one kind (native TAO or contract event) and optional filters. You can view your current usage on the Webhooks page.
OTC Token Enabling
ViewPallet OTC enables peer-to-peer swaps between native TAO and PSP22 tokens. Orders follow a deposit-then-payout flow with on-chain confirmation at each step.
Token Lifecycle
Before a token can be traded on OTC, it goes through these steps:
- 1
Register token contract
Submit the contract via the Contracts page with isToken: true. See the Contract Indexing section for details on the registration and review process. - 2
Admin enables OTC trading
After the contract is approved, an admin sets the otcEnabled flag on the contract. This is a separate action from contract approval — a contract can be indexed without being OTC-tradeable. - 3
Token appears in selector
Once otcEnabled is set, the token appears in the OTC token selector dropdown (visible in the dashboard TopBar) and on the public OTC explorer page. - 4
Users create orders
Users can create buy or sell orders for the token. Orders specify: side (sell_token_for_tao or buy_token_for_tao), offer amount, want amount, and expiry time.
Fee Structure
The platform charges a fee on completed OTC trades. The fee is:
- Applied as basis points (bps) on the maker's offer amount
- Deducted at payout time — the maker receives
offerAmount - fee - Visible in the OTC configuration
The current fee rate is displayed on the OTC page. Fee proceeds are routed to the protocol treasury.
Order Lifecycle
OTC orders follow a state machine with on-chain deposit confirmations at each step. The indexer detects on-chain deposits and advances the order automatically.
State Transitions
| From | To | Trigger | By |
|---|---|---|---|
open | maker_deposit_pending | Maker submits deposit tx details | Maker |
maker_deposit_pending | maker_deposited | Indexer confirms deposit on-chain | System |
maker_deposited | taker_matched | Taker accepts the order | Taker |
taker_matched | taker_deposit_pending | Taker submits deposit tx details | Taker |
taker_deposit_pending | ready_for_payout | Indexer confirms deposit on-chain | System |
ready_for_payout | completed | Operator processes payout | Operator |
open | cancelled | Maker cancels before deposit confirmation | Maker |
maker_deposit_pending | cancelled | Maker cancels before on-chain confirmation | Maker |
maker_deposited | expired | Order expiry time reached without taker | System |
ready_for_payout | refund_required | Payout fails (e.g. insufficient balance) | Operator |
refund_required | refunded | Operator processes refund | Operator |
expired | refund_required | Admin marks expired order for refund | Admin |
Deposit Matching
Deposits are matched to orders using a 3-tier identifier system (not just transaction hash). This is important because hardware wallets (like Ledger) may report different extrinsic hashes than what appears on-chain:
| Tier | Matches On | Action |
|---|---|---|
| 1 — txHash | Exact match of transaction hash | Auto-proceed |
| 2 — blockHash | Transaction hash differs but block hash matches | Auto-proceed (warn) |
| 3 — content | Both differ but from + to + amount + contract match | Manual admin review |
Warning
Orders lock the maker's token balance from the moment the maker deposit is confirmed on-chain until the order reaches a terminal state (completed, cancelled, expired, or refunded). The maker cannot transfer the locked tokens during this period. Use the expiry time carefully — orders in maker_deposited state do NOT auto-expire; the maker must manually cancel and request a refund if no taker accepts.