NEXAR is a Private Intelligence Graph — an infrastructure layer that lets anyone register, encrypt, license, and monetize any file as on-chain intellectual property.
Built on
Story Protocol
IP registry and licensing
CDR
Encrypted vault storage
Privy MPC
Non-custodial wallet infrastructure
Pinata IPFS
Decentralized file storage
Aeneid Testnet
Story Protocol's EVM chain (Chain ID: 1315)
What NEXAR provides
A REST API that wraps all of the above
A Telegram bot for zero-friction onboarding
iMessage and WhatsApp via Photon Spectrum
An operator-pays-gas architecture — users never need ETH
Multi-signal plagiarism detection at registration
Automatic royalty distribution via Story Protocol PIL terms
What NEXAR does not do
Store your private keys (Privy MPC handles this)
Charge platform fees on revenue (0% cut)
Require users to know anything about blockchain
Expose your files publicly (always AES-256 encrypted)
Getting Started
Core Concepts
The building blocks of the NEXAR graph — IP assets, vaults, licenses, and the operator model.
IP Asset
Every registered file becomes an IP Asset on Story Protocol. It gets a unique ipId (Ethereum address), a vaultUuid (CDR), and a licenseTermsId (PIL terms contract).
Every IP Asset has an associated CDR (Confidential Data Rail) vault. The vault stores the AES encryption key for the file. Access is controlled by on-chain conditions.
Vault type
Behavior
licenseGated
Anyone with a license token can access
ownerOnly
Only the registered owner can access
timedAccess
Access expires after a set time
inferenceOnly
Access limited to compute operations
License Token
When someone pays for access, a license token (ERC-721) is minted to their wallet. This token is their on-chain proof of access. It is checked before any vault decryption.
Operator Pattern
One server wallet (the operator) signs all blockchain transactions and pays all gas. Users own the IP — their address is the registered owner — but never need ETH or a wallet setup.
NEXAR Handle
Every user gets a NEXAR handle (e.g. zaid_01). Separate from their Telegram or iMessage username. One handle → one Privy MPC wallet → works across all platforms.
Access Token
A signed, time-limited download link. No NEXAR account needed to use. Can be single-use (burns after one download) or multi-use (unlimited downloads within expiry).
PIL Terms (Programmable IP License)
Every registered file gets Story Protocol PIL terms attached. These terms define the license type and economics:
commercialUse
Can buyers use it commercially?
derivativesAllowed
Can buyers build on it?
commercialRevShare
What % do you earn on derivatives?
defaultMintingFee
What does a license cost?
royaltyPolicy
LAP (Liquid Absolute Protocol)
Getting Started
Quick Start
Get your first file registered as IP in under 5 minutes — over Telegram or via the API.
STEP 1 — OPEN TELEGRAM
Find @nexar_intel_bot on Telegram and send /start.
STEP 2 — CREATE YOUR HANDLE
register yourhandle
Rules
3–20 characters
Letters, numbers, underscores only
Lowercase only
Must be unique — cannot be changed later
What happens
NEXAR checks availability
Privy MPC wallet created (you own the keys)
Handle linked to your Telegram identity
Wallet address returned
STEP 3 — SEND A FILE
Send any file as a Telegram attachment. NEXAR walks you through:
Q: Who can access this?
A: anyone / @username / timed
Q: License terms? (if "anyone")
A: strict (no re-selling) / open (re-selling allowed, you earn 20%)
Q: Price in $IP? (or "free")
A: 0.1
Q: Name this asset? (or "skip" for filename)
A: My Dataset
STEP 4 — REGISTERED
✅ My Dataset registered as your IP!
Price: 0.1 $IP
Access: Anyone who pays
IP ID: 0x6A6d38...
Explorer: https://aeneid.explorer.story.foundation/ipa/0x...
Your file is encrypted on IPFS.
Plagiarism fingerprint stored. 🛡️
STEP 5 — GET PAID
When someone buys access via buy yourhandle/my-dataset, you receive a license token minted to the buyer's wallet and a royalty accrued to your IP vault. Text earnings to check your balance and claim to collect.
Via API
Base URL https://your-domain.com · Content-Type: application/json
Every action is a plain-text message. The same commands work on Telegram, iMessage, and WhatsApp.
register <handle> Create your NEXAR identity
wallet View your wallet address
my assets List your registered IP
my licenses List licenses you own
earnings Check claimable royalties
claim Collect all royalties
buy @handle/asset Purchase a license
access @handle/asset Decrypt and download a file
link email <email> Link email to your account
recover <handle> Recover your account
whoami View your full identity
help Show all commands
Messaging
Identity & Handles
One handle, one wallet, every platform. Includes cross-platform identity, private sharing, and the pending-shares invite queue.
Handle system
One NEXAR handle = one Privy MPC wallet = works on all platforms.
3–20 characters
Lowercase letters, numbers, underscores
Globally unique — first come first served
Permanent — cannot be transferred or changed
Cross-platform recovery
Open Telegram → type recover alice
NEXAR sends a 6-digit code to the original platform
Reply verify 123456
Telegram linked to alice's wallet
Platform linking
One handle can be linked to multiple platforms. Private sharing sends an asset to a specific @handle; if the target hasn't registered yet, it sits in the pending-shares queue and is auto-minted the moment they do. Commands: link email alice@example.com · recover alice
DB schema
usernames:
username TEXT PRIMARY KEY
privy_wallet_id TEXT
created_at INTEGER
platform_identities:
username TEXT → references usernames
platform TEXT (telegram|imessage|whatsapp|email)
platform_id TEXT (phone, chat_id, email address)
UNIQUE(platform, platform_id)
pending_shares:
ip_id TEXT
owner_username TEXT
target_username TEXT
→ Auto-minted when target registers
access_tokens:
token TEXT PRIMARY KEY
vault_uuid TEXT
single_use INTEGER
uses_remaining INTEGER
expires_at INTEGER
API Reference
API Overview
A single REST surface wraps Story Protocol, CDR, Privy, and IPFS. Every response follows a consistent envelope.
Base URL: https://your-domain.com
All responses follow the shape:
{ "ok": true, ...data }
{ "ok": false, "error": "ERROR_CODE", "message": "..." }
Authentication is currently open and rate-limited — API keys are on the roadmap. See Rate Limits and Error Codes for the full envelope details.
API Reference
POST
Wallets
POST /api/wallet/create
Create a Privy MPC wallet for a user label. Idempotent — returns the existing wallet if the label exists.
Body
{
"label": "string" // email, username, or any unique ID
}
Response
{
"ok": true,
"label": "alice@example.com",
"address": "0x358dB4C646C313042E11029BBf76431740374c3B",
"mode": "privy" // or "local" in dev mode
}
GET /api/wallet/:label Get wallet address for a label
GET /api/wallet List all wallet labels
API Reference
POST
Asset Registration
POST /api/asset/register
Register any file as a Story Protocol IP Asset. Creates a Privy wallet if the label doesn't exist. Encrypts the file, uploads to IPFS, registers IP, attaches PIL terms, creates a CDR vault.
Body
{
"label": "string", // owner's NEXAR handle or email
"name": "string", // asset display name
"description": "string", // asset description
"tier": "string", // DATASET | MODEL | INFERENCE | STRATEGY | PROMPT
"content": "string", // base64-encoded file bytes
"contentType": "string", // MIME type e.g. "image/jpeg", "text/csv"
"commercial": boolean, // allow commercial use?
"revShare": number, // 0-100, % revenue share on derivatives
"basePrice": "string" // price in $IP e.g. "0.1" or "0" for free
}
Onboard non-crypto users as IP owners without requiring them to hold ETH, set up a wallet, or understand blockchain. This guide also covers how Privy MPC wallets are created and signed.
How it works
1. User sends "register alice" on Telegram.
2. NEXAR creates a Privy MPC wallet for "alice".
Address: 0x358dB4C646...374c3B
The private key is split via MPC between Privy's servers
and the authorized client. NEXAR never holds the full key.
3. When alice registers an IP asset:
→ Story Protocol's registerIpAsset() is called
→ nft.recipient = alice's address ← she OWNS the NFT + IP
→ Transaction signed by OPERATOR wallet ← operator pays gas
→ Gas fee paid from operator's $IP balance
4. Alice's address appears as the IP owner on-chain:
https://aeneid.explorer.story.foundation/ipa/0x...
5. When someone buys alice's license:
→ mintLicenseTokens() called with receiver = buyer's address
→ Minting fee paid by buyer (or operator in free tier)
→ Royalty accrues to alice's IP vault
→ alice claims via "claim" command
Required env variables
PRIVATE_KEY=0x... # Operator wallet
# Holds $IP for gas
# The ONLY key on server
PRIVY_APP_ID=...
PRIVY_APP_SECRET=...
Operator wallet funding
Faucet: faucet.story.foundation
Estimate: ~0.01 $IP per asset registration · ~0.005 $IP per license mint
Security considerations
Operator private key should be in env vars only
Never commit PRIVATE_KEY to git
Use a dedicated operator wallet (not your personal wallet)
Monitor operator balance — if it runs out, registrations fail
Rotate key quarterly in production
Guides
File Encryption Deep Dive
Every file goes through a multi-layer encryption pipeline before storage. This covers the encryption architecture, key management, and threat model.
Input file bytes
│
▼
AES-256-GCM encryption
→ Random 256-bit key generated per file
→ Random 96-bit IV generated per file
→ Produces: encrypted bytes + auth tag
│
▼
Pinata IPFS upload
→ Encrypted bytes uploaded as raw blob
→ Returns CID (content identifier)
→ CID is public — but content is unreadable without key
│
▼
CDR vault creation
→ AES key + CID encoded together as vault payload
→ Uploaded to CDR with access condition
→ CDR vault UUID returned
│
▼
SQLite vault_secrets
→ AES key + CID stored for server-side access
→ Used for operator-mediated decryption
CDR on-chain key management
Decentralized, trustless key release. CDR validators verify license conditions and release the key only to valid holders. Roadmap: Mini App.
SQLite vault_secrets server-side
MVP approach — operator verifies license on-chain, then serves decrypted content directly. Faster, works without user-side signing.
Decryption flow
User calls POST /api/vault/access
Server checks DB: does user hold a valid license token?
Fetches AES key from vault_secrets
Downloads encrypted blob from Pinata (using CID)
AES-256-GCM decrypt with key + IV from payload
Returns decrypted bytes as base64
File never stored in plain text
Plain file bytes exist only in memory during encryption/decryption (milliseconds) and on the user's device after delivery. They are never written to disk on our server, stored in the database, or logged anywhere.
Guides
Plagiarism Detection
Every file is fingerprinted at registration. Future registrations are checked against the fingerprint database.
Detection methods by file type
Type
Algorithm
Threshold
Survives
Image jpg, png, gif, webp
DCT perceptual hash (pHash), 64-bit
85%
Resize, compression, minor edits, color shifts, format conversion
Audio mp3, aac, wav, ogg, flac
Energy distribution fingerprint, 48-char
85%
Re-encoding, bitrate change, format conversion, minor pitch/tempo
Video mp4, mov, avi, webm, mkv
Frame region sampling (16 keyframes)
80%
Re-encoding, resolution change, compression, format conversion
PDF
Text extraction + chunk hashing
70%
Font changes, margins, page reorder, reformatting
Text / Data csv, json, txt, code
20-sample chunk hashing
70%
Minor modifications, added rows, reformatting
All files
SHA256 exact hash
100%
Byte-for-byte identical copies blocked instantly
Registration flow with duplicate detection
File received
│
▼
Compute fingerprint (SHA256 + type-specific)
│
▼
Check against all existing fingerprints in DB
│
┌─┴──────────────────────────────┐
│ │
No match Match found
│ │
▼ ▼
Register normally Report to user:
"⚠️ Similar content found
Match: 94% (perceptual)
Original: @alice/photo.jpg
Do you still want to register?"
DB schema — asset_fingerprints
ip_id TEXT PRIMARY KEY
owner TEXT
asset_name TEXT
sha256 TEXT -- exact hash
phash TEXT -- image perceptual hash
audio_hash TEXT -- audio energy fingerprint
video_hash TEXT -- video frame fingerprint
fingerprints TEXT -- JSON: text/pdf chunk hashes
file_type TEXT -- image|audio|video|pdf|text|data|other
mime_type TEXT
created_at INTEGER
Contracts
Deployed Contracts
All NEXAR and Story Protocol contracts on the Aeneid testnet.
Network
Aeneid Testnet
Chain ID
1315
RPC
https://aeneid.storyrpc.io
Explorer
https://aeneid.explorer.story.foundation
NEXAR Contracts
NEXARRegistry
0x0abf194137a47E8cC6D8773E38c8CD399D674128
Maps ipId → vaultUuid on-chain. Central registry for all NEXAR IP assets. registerAsset(ipId, vaultUuid, tier, basePrice)
DynamicPricingHook
0xeAA90ff07786E2f8Ed7012faB5949a0257cCfb96
Handles license pricing per asset. Implements Story Protocol ILicensingHook. registerAsset(ipId, tier, basePrice)
Gates model inference access. Verifies compute units and license terms. Custom condition for INFERENCE tier assets.
ReputationRegistry
0x6Cd86319C6977811432881b08F14dC8E7dc2640F
Tracks operator reputation scores. Used for future trust-based access control.
Story Protocol Contracts (Aeneid)
SPG NFT Collection (NEXAR)
0x6901E30ed2a14A78aB50BA13a4eE8a75D19467AE
CDR Proxy
0xCCCCCC0000000000000000000000000000000005
CDR Implementation
0xDC78a37C28A2d53441B8F09E26237320E0F9C0f9
Deployer Wallet
0xb92736aaE34B913497E775dFb52Bb7D334B11B2b
Verifying a NEXAR IP on-chain
Explorer: https://aeneid.explorer.story.foundation/ipa/<ipId>
Programmatically:
GET https://aeneid.storyrpc.io
eth_call → IPAssetRegistry.isRegistered(ipId)
Returns: true if registered, false if not