NFT Standards
0xio Wallet supports two NFT standards on the Octra Network. The wallet automatically detects which standard a contract uses via on-chain ABI inspection and adapts its behavior accordingly.SNS-1 (Spectrum NFT Standard)
SNS-1 is the collection-based NFT standard on Octra, designed by Spectrum. It supports multiple tokens per contract with sequential token IDs, IPFS metadata, royalties, and operator approvals.View Functions
State-Changing Functions
Metadata JSON (IPFS)
Example Contract
- Devnet:
octFc9ynSen79FarWJqsLExjJTHbp27iQAfy3CG9218pr9z
Bionts (Single-Contract NFT)
Bionts are autonomous, single-contract NFTs created by Euint Labs, where each biont is its own deployed smart contract. Total supply is always 1, and the token ID is always 0. Thetoken_uri() function returns full SVG markup directly from contract state. It is fully on-chain, with no IPFS or external servers.
View Functions
State-Changing Functions
On-Chain SVG
Unlike SNS-1 which uses IPFS for metadata, Bionts return full SVG markup fromtoken_uri(). The SVG is generated from live contract state: name, wander count, defense stats, and alive/dead status all render dynamically.
0xio Wallet detects raw SVG responses (strings starting with <svg) and renders them inline via base64 data URIs.
Example Contract
- Devnet:
octHgHJLvxtEhjzXT5ZyBHTEAKYf8s7da4iWfmHShLrtdbM
Living NFTs (Euint Labs Geodesics and Chain-State Collections)
A living NFT’s art is a program: an HTML page hosted in a public Octra Circle. The collection is one contract with many token ids, andtoken_uri(id) does not return SVG.
token_uri Shapes
Inline JSON is UTF-8 text, not base64, and URLs inside it keep their own percent escapes. The wallet parses it in place (capped at 256 KB) and never sends it to
fetch(). Percent-encoded and ;base64 bodies are read too.
The metadata’s animation_url (and usually image) points at the program, for example:
Two Kinds of Program
- Seed-only (Geodesics): the program draws from
?seed=alone and makes no network requests. Its frame hasconnect-src 'none'. - Chain-state (the query names
contract=): the program reads its own state with read-onlycontract_callrequests to the Octra JSON-RPC.st=carries a state snapshot with commas and colons, and devnet tokens carryrpc=https://devnet.octrascan.io/rpc. Mainnet tokens carry norpc=, and the program defaults tohttps://octra.network/rpc.
What a Program May Reach
- The frame runs sandboxed in an opaque origin, with no wallet access, no keys and no storage.
- A chain-state program may reach exactly one endpoint, the
/rpcpath of the network its token lives on:https://octra.network/rpcon mainnet,https://devnet.octrascan.io/rpcon devnet, or the user’s own node on a custom network. The frame’sconnect-srcnames only that endpoint. - An
rpc=value is kept only when it names that endpoint. Any other host is dropped and the network’s endpoint is used, so a token cannot make the wallet contact a server of its choosing. The 0xio RPC proxy is never reachable from a program. - The full query reaches the program byte for byte, through
new URLSearchParams(location.search). - In the extension the sandbox policy names the mainnet and devnet endpoints, and each program document narrows it to its own network. On a custom node the program has no network, and its
contract_callrequests are answered through the wallet’s read-only bridge instead. - Live programs run on the detail screen only, one at a time. Every read counts against the same per-IP rate limit as the wallet.
Burns, Reveals and Caching
- Tokens can be burned. A burned id reverts on
token_uri, and the wallet drops it from the gallery instead of leaving an empty tile. A busy or unreachable node is not a burn. - Files at one
oct://path can change, so program and metadata files are not kept on disk. A program stays in memory for 5 minutes. token_uriis read again when a moving token’s page opens, after a manual refresh, and once per session, so reveals, burns and new state show up.
Chunked Circle Files
A large file can be stored in a circle as chunks, the way the Octra reference client uploads it. The extension, the mobile app and 0xio Desktop put the file back together and check it before showing it: in NFT art and living NFT programs on all three, in the mobile app’s browser, and in the desktop’s Circles screen and browser. A chunk or a whole file that does not match its hash is not shown.- The file’s own path answers with content type
application/vnd.octra.circle.chunks+jsonand a manifest:formatoctra.circle.asset.chunks.v1, the realcontent_type,encodingidentity,size_bytes(digits) and thesha256of the whole file. chunkslists each part in order:path/.octra/chunks/<sha256>/0000,0001and so on, itssize_bytesand its ownsha256. Each chunk is served asapplication/octet-stream.- Limits: up to 32 chunks of at most 2 MiB each, and 32 MiB in all.
- The wallet checks the sha256 of every chunk and of the assembled file.
Discovery
Devnet’soctra_tokensByAddress does not list the new-layout contracts yet. For an imported contract the registry does not list, the wallet reads balance_of(wallet), then owners_page(start, 50) when the ABI has it (one owner or - per id), else owner_of id by id. Burned ids leave gaps past the live supply, so the scan does not stop at get_total_supply. These contracts answer get_name and get_symbol instead of collection_name and symbol.
Devnet Test Set
EVM NFTs (Extension)
The browser extension also shows ERC-721 and ERC-1155 tokens held by the wallet’s 0x address, in the same NFTs list as Octra collections, with a network badge on each cover.- Holdings are read through the 0xio oracle (
/api/evm/nfts), one network at a time; tokens the explorer flags as scam or spam are dropped. See Oracle API. - Images load through the 0xio proxy.
- Import takes a contract and token ID; the network is detected, and the preview checks that this wallet holds the token.
- Send uses
safeTransferFromfor the token’s standard, after a review with the fee.
How 0xio Wallet Detects the Standard
- Fetch ABI via
octra_contractAbito determine which methods the contract exposes - Name detection: tries
collection_name()(SNS-1),name(),biont_name(),get_name()in priority order - Transfer method: detects
transfer(to, token_id)(SNS-1) ortransfer_to(address)(Bionts) from ABI - Image rendering: if
token_uri()returns<svg..., renders inline; inlinedata:application/jsonis parsed in place;oct://andipfs://metadata JSON is fetched and its image resolved; anoct://...htmlanimation_urlrenders as a living program
transfer(to, token_id) and IPFS metadata).