View PalletViewPalletDocs
Dashboard

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 ContractEmitted events 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

ComponentDescription
IndexerConnects to Bittensor via WebSocket, processes finalized blocks, decodes events/transactions, updates balances, matches webhooks and OTC deposits
API ServerREST API — auth, subscriptions, invoices, webhook CRUD, OTC order management, admin endpoints
ExplorerPublic read-only views of blocks, transactions, events, addresses, contracts, and tokens
OracleOn-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

FeatureNORMALPRO
Explorer access
Webhook endpoints15
Contract registrations1Up to 5
Webhook event typesAll enabled eventsAll enabled events
OTC order creation
OTC order management
Delivery queueStandardPriority
HMAC-SHA256 signatures
SupportCommunityPriority
BillingMonthly or yearlyMonthly 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
PlanMonthlyYearly
NORMAL0.05 TAO0.5 TAO
PRO0.1 TAO1 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

  1. Choose a plan and billing cycle from the Subscription page
  2. An invoice is created with the TAO amount and the admin wallet address
  3. Send the exact TAO amount to the address shown on the invoice
  4. Capture the block hash from your wallet after the transfer confirms
  5. Submit the block hash to confirm payment
  6. 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. 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. 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. 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. 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 Transfer events
  • 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

StatusMeaning
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:

TierMax Contracts
GUEST0
NORMAL1
PRO5

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:

FilterDescription
senderAddressOnly match transfers from this SS58 address
receiverAddressOnly match transfers to this SS58 address
minValueOnly 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. 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. 2

    Delivery job created

    A delivery job is created with status pending and enqueued to BullMQ for processing.
  3. 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. 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. 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 authentic

Request 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

TierMax Endpoints
GUEST0
NORMAL1
PRO5

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

FromToTriggerBy
openmaker_deposit_pendingMaker submits deposit tx detailsMaker
maker_deposit_pendingmaker_depositedIndexer confirms deposit on-chainSystem
maker_depositedtaker_matchedTaker accepts the orderTaker
taker_matchedtaker_deposit_pendingTaker submits deposit tx detailsTaker
taker_deposit_pendingready_for_payoutIndexer confirms deposit on-chainSystem
ready_for_payoutcompletedOperator processes payoutOperator
opencancelledMaker cancels before deposit confirmationMaker
maker_deposit_pendingcancelledMaker cancels before on-chain confirmationMaker
maker_depositedexpiredOrder expiry time reached without takerSystem
ready_for_payoutrefund_requiredPayout fails (e.g. insufficient balance)Operator
refund_requiredrefundedOperator processes refundOperator
expiredrefund_requiredAdmin marks expired order for refundAdmin

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:

TierMatches OnAction
1 — txHashExact match of transaction hashAuto-proceed
2 — blockHashTransaction hash differs but block hash matchesAuto-proceed (warn)
3 — contentBoth differ but from + to + amount + contract matchManual 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.