Package Exports
- sui.ski
- sui.ski/assets/au.png
- sui.ski/assets/basmr.mp4
- sui.ski/assets/basmr.webm
- sui.ski/assets/btc-icon.svg
- sui.ski/assets/diamond-192.png
- sui.ski/assets/iusd-256.png
- sui.ski/assets/iusd.svg
- sui.ski/assets/ski-192.png
- sui.ski/assets/ski-512.png
- sui.ski/assets/ski-idle.gif
- sui.ski/assets/ski-idle.mp4
- sui.ski/assets/ski-idle.webm
- sui.ski/assets/ski.svg
- sui.ski/assets/sol-icon.svg
- sui.ski/assets/sui-drop.svg
- sui.ski/assets/sui-icon.svg
- sui.ski/assets/sui-ski-qr.svg
- sui.ski/assets/waap-icon.svg
- sui.ski/assets/waap-qr.svg
- sui.ski/embed
- sui.ski/styles
Readme
.SKI — .Sui Key-In
.SKI once, everywhere.
What .SKI Is
.SKI is a Sui-native messaging and cross-chain identity dApp where SuiNS names are communication endpoints. You send a thunder to @name and it lands as an encrypted storm conversation whose ciphertext lives on Walrus and whose keys live behind Seal. Every wallet, agent, and cross-chain address is IKA-native — no private keys sit on Cloudflare Workers, ever. The same UI rails carry Thunder messages, Thunder IOU transfers, shielded Pedersen commitments, Shade grace-period snipes, and SUIAMI cross-chain identity proofs.
Agents (ultron, chronicoms, t2000s) are Durable Objects that sign via IKA dWallet user shares + DWalletCap wrappers. brando.sui runs DKG in the browser and re-encrypts the user share to the agent. Either brando OR agent + IKA network = a valid signature.
For Hackathon Devs (Frontier Colosseum)
SKI is the best IKA-based Web2 social login experience you can build with today. Here's what you get out of the box:
WaaP — Wallet as a Protocol
Sign in with X.com, Google, phone, or email. No API keys. No seed phrases. No wallet extensions. It just works. If you're a dev, you know how amazing "no API keys" is.
Rumble Your Squids
One button runs IKA DKG and provisions native Bitcoin, Solana, and EVM dWallet addresses — all from a single Sui account. Not wrapped. Not bridged. Real cross-chain keys. This is built and live on mainnet today.
Anti-Spam — Stables Only
SKI is inherently anti-spam. Everything is measured in stables. You have 8 billion MONKE PENIS coins? SKI checks all exchanges, sees it's worth less than a cent, and filters it out — or auto-swaps it to USD (or Argentine Peso). No more 0.000256 CHODE in your portfolio.
Subcent Intents
The 6-7 digits after $0.01 aren't noise — they're steganographic intent tags:
- Which chain are you swapping to?
- What is the receiving address?
- Other privately encoded data only legible to the participants
One number carries the instruction. No metadata leaks.
What You Can Build With
- Tradeport — SuiNS marketplace listing proxy (
/api/tradeport/listing/:label) - Walrus — Seal-encrypted blob storage for Thunder ciphertext, Shade payloads, quilted batch writes
- Solana/Helius — Webhook-driven deposit watchers, SPL token resolution, Jupiter routing
- Seal — 2-of-3 threshold encryption (Overclock, Studio Mirai, H2O Nodes key servers)
- IKA dWallets — Native cross-chain signing, batch DKG, DWalletCap wrappers
Native Cross-Chain Wallets via IKA dWallets
Real Bitcoin, Ethereum, and Solana addresses controlled by your Sui account — no bridges, no wrapping, no custodians. Powered by IKA's 2PC-MPC threshold signatures.
What One Sui Account Controls
| Curve | Chains | Address Format |
|---|---|---|
| secp256k1 (1 DKG) | Bitcoin, Ethereum, Base, Polygon, Arbitrum, Optimism, Tron (USDT only) | bc1q..., 0x..., T... |
| ed25519 (1 DKG) | Solana | base58 |
Two DKG ceremonies. Two dWallets. Eight chains. One Sui account.
Why This Matters
- No bridges — BTC stays on Bitcoin, SOL stays on Solana. IKA generates real native addresses whose signing is governed by Sui smart contracts.
- Non-collusive security — 2PC-MPC means neither the user nor the network can sign alone. 100+ mainnet operators with Byzantine threshold.
- Quantum-ready architecture — Sui's flag-byte signature scheme lets the network add post-quantum primitives via a new flag byte — no hard fork, no address migration. See
docs/ika-quantum-resistance.md.
First Commandment: IKA-Native, Keyless Agents
- Every wallet, agent, and cross-chain address MUST be IKA-native.
- No private keys on Cloudflare Workers — ever. Agents sign via IKA dWallet user shares + DWalletCap wrapper.
- Cross-chain addresses (BTC, ETH, SOL) come from IKA dWallet DKG — always. No raw keypair re-encoding as cross-chain addresses.
brando.suiruns DKG in-browser, re-encrypts user share to the agent. Either brando OR agent + IKA network = valid signature.- Batch DKG provisioning for agents = "Rumble your squids."
- If a dWallet doesn't exist yet, the feature is blocked until DKG is run — no shortcuts.
Magneton — Sealed Messaging Through a Keyless Blind Relay
Magneton is SKI's sealed messaging layer. One sentence, canonical:
A Prismoid opens a storm with its squids. Each thunder — and each prism — is scribed by ultron into both Prismoids' chronicoms, the chronicoms write through to the timestream, and sibyl reads the timestream to score trust — turning strangers into inkas as each carries the other's suiami.
- Prismoid — your identity vessel. A Move object wrapping one or more IKA dWallets that carries your SuiNS name and every cross-chain address you can touch. Transfer one object, transfer the whole identity atomically.
- Squid — a single chain-capable appendage of a Prismoid. One per curve: secp256k1 squid reaches BTC/EVM, ed25519 squid reaches SOL/Sui. Multiple squids can cooperate on cross-chain multi-sig. "Rumble your squids" provisions them in a single DKG ceremony.
- Opening — the first squid-sign between two Prismoids that opens a storm. Scribed into both chronicoms as the anchor of the relationship. The squid used matches the recipient's native chain, so the anchor is verifiable from any chain the recipient cares about.
- Scribe — the verb. Ultron scribes each thunder and each prism into both Prismoids' chronicoms. The chronicoms write through to the timestream. One unified pipeline for messages and transactions.
- Inscribe — the opt-in non-repudiable variant. To inscribe a thunder or prism = attach a squid signature so the entry is permanently third-party verifiable in the timestream. Default is deniable; flip to inscribed when you want proof. Signal cannot do this for messages; suiami can do it for messages and transactions, in one substrate.
- Chronicom — your per-Prismoid Durable Object. Holds the suiamis you carry (your inka set), every storm you participate in, and every prism you exchange. The chronicom is your local view; the timestream is the authoritative one.
- Timestream — the temporal substrate every chronicom writes through to. The on-chain time-ordered ledger of all scribed entries — both thunders and prisms — between Prismoids.
- Sibyl — the oracle. Reads the timestream to score trust, predict spam, and signal inka eligibility.
- inka / inkas vs strangers — an inka is someone whose suiami you carry. The moment your chronicom holds another Prismoid's SUI-AUTH-MSG-ID credential, they're an inka. Strangers are anyone whose suiami you don't carry. Country-pool inkas (everyone with a Full SKI Pass in your country) are auto-shared by ultron at key-in time; cross-country inkas are earned through scribed thunders or sent prisms.
- suiami — SUI-AUTH-MSG-ID. The authenticated message-identity credential — a tamper-evident proof of ownership of a Prismoid + its SuiNS name + its squids, stamped with country metadata at minting time. Published as the
suiaminpm package. - SKI Pass — a roster of credentials per SuiNS name (NFT + squids), bound by the name, auto-minted on first key-in, country-attested. Comes in two tiers: Full (default for primary country) and Temporary (any new country until upgraded by either multiple key-ins over time or by sending a Prism worth a threshold to ultron). No expiry unless you don't key in for 3 years.
The topology: Thunder through ultron
Every thunder is a double envelope. The outer envelope is encrypted to ultron and contains only { recipient_prismoid, inner_ciphertext }. The inner envelope is encrypted to the recipient's squid. Ultron routes the inner envelope but cannot read it — it is a keyless blind relay. It knows who talks to who; it does not know what they say. First commandment holds: no private keys on Cloudflare Workers, ever.
Thunder isn't a performance compromise — it's the decision that unlocks everything downstream:
| Layer | What Thunder unlocks |
|---|---|
| Spam control (inkas vs strangers) | Enforcement lives at ultron, not in N client implementations. Visiting sui.ski and keying in mints a SKI Pass automatically — that's the gate. Strangers to SKI fix it in 10 seconds; inkas (anyone whose suiami you carry) pass through. Zero client trust needed. |
| Delivery model | One WebSocket per Prismoid to ultron, reused for all traffic. Cloudflare Durable Object hibernatable WebSockets are free when idle. Already wired. |
| Forward secrecy | Single write path. Ultron watches Prismoid rotation events on-chain and scribes new anchors into the timestream. No multi-device desync — the anchor lives in the chronicom where both sides read from it. |
| Cross-chain delivery | Collapses into "ultron emits chain-specific notifications." Ultron has its own dWallets (ed25519, secp256k1) and can drop a SOL memo, an EVM event, or a BTC OP_RETURN when the recipient has no SKI client. The non-Sui recipient installs nothing. |
| Magnezone evolution | Uniform traffic is the precondition for onion mixing and cover traffic. Thunder is what makes the mixnet path possible later. |
The alternative — direct peer-to-peer — would leak your entire social graph to any passive observer, force every client to enforce its own spam rules, break cross-chain delivery, and close the door on mixnet evolution forever. Hybrid (direct for inkas, ultron for strangers) doubles the codebase, bifurcates enforcement, and kills mixing. The "latency win" from direct is tens of milliseconds. Not worth it.
Thunder. Ultron sees who, never what. Everything else falls out for free.
Terminology
| Word | Meaning |
|---|---|
| Storm | A conversation (not channel/group) |
| Thunder | A message or signal |
| Quest | The act of reading/opening |
| Purge | Delete-on-read (never "decrypt") |
| Cache | Fund storage (never "treasury/reserve/dao") |
| Rumble | IKA DKG ceremony (never multi-token swap routing) |
| SKI Pass | Access/membership proof |
| Stables | Dollar-pegged value (never "stablecoins") |
| Sibyl | The predictor (never "Sybil") |
| chain@name | Address format: sol@ultron, eth@brando, btc@stables |
| encrypt / decrypt | Always verb forms, never "encrypted/encryption" |
Core Principles
- IKA-native, keyless agents. Every cross-chain address is IKA dWallet derived. No private keys on workers. Batch DKG = "Rumble your squids."
- Cache, not treasury. Funds flow through caches — high-performance temporary stores.
- Stables, not stablecoins. iUSD is a stable backed by activity yield.
- Encrypt, not encrypted. Use verb forms — encrypt/decrypt.
Domain Structure
| Domain | Purpose |
|---|---|
sui.ski |
Root — main application, embeddable widget, API endpoints |
<name>.sui.ski |
SuiNS profile pages (e.g. brando.sui.ski) |
Cross-domain session cookie (ski:xdomain) on domain=sui.ski for auth persistence across subdomains.
UI Overview
The .SKI header bar renders four elements:
- Dot — wallet status shape (green circle = unconnected, black diamond = connected, blue square = has SuiNS name). Toggles modal/menu.
- Profile pill — wallet icon, social badge, SuiNS name + squid emoji (IKA status), live balance. Clicks to
.sui.skiprofile page. - SKI button — branded button. Three-state cycle: menu → idle overlay → menu.
- Balance pill — live USD balance. Click to cycle SUI/USD display.
Idle Overlay
After 5 minutes of inactivity (or via SKI button cycle), the menu collapses into a compact overlay with:
- Pixel art video (cached via Cache API for instant replay)
- Name search input with full SuiNS resolution
- Squids rows — styled SUI/BTC/SOL/ETH/Base/Tron address rows with chain-colored icons, per-row USD balances, toggle-select to copy
- Rumble button — runs IKA DKG to provision all chain wallets
- Thunder messaging row
- Version badge linking to npm
The overlay restores instantly on hard refresh via ski:last-address localStorage fallback, with IKA addresses cached to ski:ika-addrs:${address}.
Squids Panel — Cross-Chain Balance Display
Clicking the 🦑 squid quick-action opens the squids panel, the idle-overlay view of every chain the user's IKA dWallet derives. Each row shows the chain glyph, truncated address, and live USD balance:
- SUI — native + stables via gRPC
listBalances(Mysten fullnode) - BTC — native via mempool.space
/api/address/<addr>(free, key-less) - SOL — native + iUSD-SPL via Helius
/api/sol-rpcproxy (getBalance+getTokenAccountsByOwner) - ETH (mainnet) — native + USDC ERC-20 via viem + Alchemy HTTPS transport (
ALCHEMY_ETH_URLsecret,eth_getBalance+erc20Abi.balanceOf) - TRON — USDT-TRC20 via TronGrid
/v1/accounts/<addr>(free tier)
Derived addresses come from the IKA dWallet public_output — even dWallets stuck in AwaitingKeyHolderSignature produce valid BCS-derived addresses, so users see their cross-chain identity the moment DKG starts instead of waiting for the accept-share step. Balances roll into the single app.usd total alongside Sui and stables so the header balance pill is a true net-worth aggregate across every chain brando holds.
QR top slot — above the chain rows, a chain-colored QR code with the selected chain's logo inlaid (green $ for SUI, orange ₿ for BTC, official Solana parallelograms for SOL, indigo Ξ for ETH, red Tron triangles for TRON). Clicking a chain row updates the QR + highlights the row in its chain color; clicking the QR expands it to 260×260. Hovering a row swaps the truncated hex for the identity form (brando.sui / btc@brando / sol@brando / eth@brando / tron@brando) while the native title tooltip shows the full hex — both visible simultaneously.
SKI Modal
Single-column overlay with key detail pane, Splash legend (keys grouped by shape tier), wallet list, and WaaP social login row. Long-press lock (2.2s) pins a wallet. Layout toggle persists preference.
SKI Menu
Dropdown with SuiNS name management, marketplace purchase (Tradeport/kiosk), Shade orders, Thunder messaging, coin chip swaps, SUIAMI identity proofs, and key management.
Thunder — Seal-Encrypted Messaging
Thunder is a thin wrapper around @mysten/sui-stack-messaging with a custom Cloudflare Durable Object relayer (TimestreamAgent).
- Encryption — Seal 2-of-3 threshold DEK + AES-GCM envelope. Relayer never sees plaintext. Key servers verified on first encrypt (
verifyKeyServers: true). - Transport —
TimestreamAgentDO, one instance pergroupId, speaks HTTP to/api/timestream/:groupId/:action(send,fetch,fetch-one,update,delete,add-participant). - Identity — SuiNS names (
alice.sui) resolved via SuinsClient to target address / NFT owner. - Storm — on-chain
PermissionedGroup<Messaging>(upstream Move package) anchors key-version history and membership; messages live off-chain in the DO. - Global SUIAMI Storm —
0xfe23aad02ff15935b09249b4c5369bcd85f02ce157f54f94a3e7cc6dfa10a6e8(uuidsuiami-global), public identity directory. Joining is a public act by design. - Seal servers — Overclock, Studio Mirai, H2O Nodes (mainnet, open/free). 2-of-3 threshold.
Privacy Phase 1 (2026-04-10)
- No plaintext fallback —
encryptWithRetryretries up to 5× and fails the send rather than storing cleartext. Transfer notes also encrypted. - Message padding — plaintext padded to fixed buckets
[256, 1024, 4096, 16384]bytes before Seal, killing the ciphertext-length side channel. - Timestamp jitter — DO rounds
createdAt/updatedAtto 10s buckets + ±5s noise on ingest. Monotonicorderpreserves UI sort. - Sender index on the wire — new messages store
senderIndex(position in the DO's participant list) instead of the raw Sui address. A dump ofmessagesno longer reveals who authored what. - Attachment guard — DO rejects
attachments: [...]at the send boundary; our transport does not round-trip them, and silently accepting would leak blob IDs outside the Seal envelope.
Thunder Attachments (Regizapdos #147)
Full attachment support lands via @mysten/sui-stack-messaging — Seal-encrypted per file, uploaded to Walrus via the configured HTTP publisher, decrypted on click via the SDK's handle.data(). All three main send paths (iUSD transfer, SUI shielded transfer, plain text send) wire files: AttachmentFile[] through sendThunder. Ancillary paths (read receipts, quick-reply) deliberately don't carry attachments.
Cache hydration — _ThunderEntry in the stale-while-revalidate localStorage cache preserves attachment refs (storageId, fileName, mimeType, fileSize) so reopened storms paint chips/thumbs immediately instead of flashing text-only. Bytes stay in Walrus; only refs cross the localStorage boundary. The AES-GCM key in IndexedDB stays non-extractable.
Size limits (aligned with SDK enforcement):
- Per-file: 2 MB (was 10 MB UI-side, SDK always enforced 2 MB)
- Per message: 4 files (was 10 UI-side)
- Total per message: 5 MB (new pre-upload guard — 4×2 MB silent failures now caught at attach time)
Errors fire as UI toasts before the SDK rejects. Walrus upload failures fail the whole send cleanly — no silent text orphaning. WaaP attachment path verification is deferred (needs live repro).
Remaining Phase 2 items (sealed sender, non-derivable group IDs, encrypted membership) are deferred — see docs/superpowers/specs/2026-04-10-thunder-privacy-audit-and-roadmap.md.
Thunder IOU + Thunder IOU Shielded
Thunder carries value as well as text. A $amount in a thunder composes a token transfer into the same PTB as the signal.
- Thunder IOU — plain escrowed transfers with recall + expiry. Package:
0x5a80b9753d6ccce11dc1f9a5039d9430d3e43a216f82f957ef11df9cb5c4dc79. - Thunder IOU Shielded — BLS12-381 Pedersen commitment transfers. Amounts are hidden on-chain; the recipient decrypts a sealed opening via Seal and reveals via a zero-knowledge verification in Move. Package:
0x3b1dcced3f585157f48afd14a84f42e65ee57dd38be9dd73d7d94a0a1b690782. - Dust gate — sub-cent sends bypass the shielded path (per
Diglett Lv.18) and route to plain IOU. - Batching —
buildShieldedDepositManyTx(Dugtrio Lv.36) and the in-flight Mr. Rime Lv.52 aggregate-vault evolution batch multiple deposits in one PTB.
Active IOU work in the Pokedex covers the activate/redeem UI (Pikachu), iUSD-yield escrow (Typhlosion), iUSD gas (Ampharos), Seal-encrypted sealed_memo (Magnezone), multi-token Iou<T> (Garchomp), and the IKA cross-chain activate to ETH/SOL/BTC (Metagross).
Gas-Free Stables Everywhere
Thunder sends work with zero SUI in the sender's wallet:
- iUSD-native transfers — when the sender lacks SUI, the send routes through
iusdTransfer(plaintransferObjectsof iUSD coins). Gas is either ultron-sponsored (non-WaaP) or covered by a 0.1 SUI drip from ultron (WaaP). - iUSD→USDC→SUI two-hop swap —
buildSwapTxchains the seeded iUSD/USDC DeepBook pool with the main SUI/USDC pool. Slippage protection at 90% minimum output; liquidity pre-check rejects swaps exceeding pool depth. - iUSD→USDC→NS registration —
buildIusdSwappath inbuildRegisterSplashNsTxswaps iUSD through both pools and registers a SuiNS name with the NS-discounted path. One signature. - Tradeport iUSD-redeem —
/api/inferdetects iUSD holders and routes marketplace buys through ultron pre-fund (SUI advanced, user repays in iUSD+USDC). Tightened accounting: Pyth price passed from infer to DO, gas buffer + 0.5% safety margin charged to the buyer. - TTL reduction —
IOU_DEFAULT_TTL_MSreduced from 7 days to 10 minutes. Theiou-sweepercron (every 10 min) auto-recalls expired vaults permissionlessly via ultron.
SUIAMI Batch Claim/Recall
The Storm action button turns green SUIAMI when unclaimed transfer vaults exist in the current conversation. One click builds a batch PTB with claim or recall per vault and signs in one tx. Settled transfers collapse into a single gray summary line showing net amounts and tx count.
The ↩ button on the quick-amount chip row scans ALL ShieldedVault objects on-chain where the connected wallet is the sender, and batch-recalls them.
Shade v5 — Generic Stable Deposits
Shade contract upgraded to v5 (0x9978db0a...) with create_stable<T>, execute_stable<T>, cancel_stable<T>. Shade deposits can now be denominated in any coin type (iUSD, USDC, etc.) — no SUI required. UpgradeCap owned by plankton.sui, policy 0 (compatible).
SOL → Shade Pipeline
One-scan cross-chain shade placement:
- Type a grace-period name → Solana QR appears (centered, large, Solana logo) on the idle overlay
- Scan with Phantom/Solflare → send SOL to
sol@ultron - SOL watcher detects deposit (route=3, shade intent) → attests SOL collateral → mints iUSD to ultron
- Auto-fires
_shadeProxy→create_stable<IUSD>→ shade order placed with iUSD deposit - At grace expiry →
execute_stable<IUSD>→ name registers to the depositor's Sui address
Zero SUI. Zero clicks after the scan. SOL value teleports cross-chain via iUSD synthetic accounting.
iUSD/USDC DeepBook Pool
Pool 0x38df72f5... seeded via seedIusdPoolV3 — one atomic PTB: create shared BalanceManager, deposit all iUSD+USDC, place ASK @ 1.01 + BID @ 0.99, share BM. Current package dispatch uses 0x337f4f4f... (latest DeepBook mainnet), not the origin package.
SUIAMI
SUI-Authenticated Message Identity — cryptographic proof that a SuiNS name belongs to you. Verified server-side via /api/suiami/verify.
SUIAMI Roster
Cross-chain identity resolver. Maps SuiNS names to BTC/ETH/SOL addresses via IKA dWallets in a shared on-chain registry with reverse lookup.
v2 Package: 0xef4fa3fa12a1413cf998ea8b03348281bb9edd09f21a0a245a42b103a2e9c3b4
SUIAMI Reciprocal Roster
Seal-encrypted cross-chain identity exchange. No cleartext cross-chain addresses ever appear on-chain — only the SUI address (already public) and a Walrus blob ID.
How it works:
- User proves SUIAMI ownership (signed message + SuiNS NFT verification)
- Cross-chain addresses (BTC/ETH/SOL) are AES-GCM encrypted and uploaded to Walrus as a blob
- Only the blob ID is written to the on-chain roster — no cleartext addresses on-chain
- Decryption is Storm-gated via Seal policy (
seal_approve_roster_reader): you must hold a valid SUIAMI proof to decrypt anyone's addresses - Reciprocal: reading someone's roster entry requires your own SUIAMI proof, which auto-writes your entry if it doesn't exist yet
- Viral: every lookup adds a new roster entry, growing the network organically
Contracts:
- Roster Package:
0x2c1d63b3b314f9b6e96c33e9a3bca4faaa79a69a5729e5d2e8ac09d70e1052fa - Roster Object:
0x30b45c51a34b20b5ab99e8c493a82c332e9502e5f4380d1be6cc79e712eaab1d - Seal Policy:
seal_approve_roster_reader
npm: suiami@0.2.0
Key files:
contracts/suiami/sources/roster.move— on-chain roster contractcontracts/suiami/sources/seal_roster.move— Seal decryption policysrc/client/roster.ts— Walrus blob upload/fetch with AES-GCM encryptionsrc/suins.ts—readRosterByAddress,maybeAppendRosterscripts/deploy-suiami-storm.ts— one-time global Storm deployment
Mega Sableye — Private Interaction Set (#148)
Roster chips render with a black diamond glyph for names brando has privately interacted with (Thunder send, value transfer, cross-chain credit). The set lives as AES-GCM ciphertext in the user's Chronicom Durable Object — the operator only ever sees the opaque blob, and the wrapping key is a non-extractable CryptoKey persisted in browser IndexedDB so raw key material never leaves the device.
Client — src/client/sableye.ts:
warmSableye(addr)— fetch ciphertext from Chronicom, AES-GCM decrypt into in-memorySet<string>noteCounterparty(name, chain)— add + debounce 2s persist back to ChronicomhasSableye(name)— synchronous lookup for render loops (_renderRosterChipcalls this)drainXchainLog()— pulls any server-side webhook touches and processes them throughreverseLookupNameflushSableye()/resetSableye()— lifecycle
Chronicom DO slice — src/server/agents/chronicom.ts:
sableye: { cipher?: string; updatedAt?: number; xchainLog?: [...] }- Rejects non-string cipher at the write boundary; DO inspection yields only ciphertext
- Worker routes
GET/POST /api/chronicom/sableye?addr=<address>
Event hooks (minimal resource impact):
- Thunder —
sendThunderinthunder-stack.tsdispatchesski:thunder-sentwith the recipient name; ui records the counterparty on every send - Cross-chain — Helius + Alchemy webhook handlers append to
sableye.xchainLogvia an internal/sableye-xchain-appendDO route (rides nursery PR #132 — depends on webhook handlers not yet on master) - Roster render —
_renderRosterChipconsultshasSableye(bareName)synchronously; black diamond on hit, blue square on miss
See issue #145, PR #148.
Shade
Privacy-preserving SuiNS grace-period domain sniping. Commitment-reveal hides domain/target/timing on-chain until execution. Seal encryption for payload privacy.
- ShadeExecutorAgent — Cloudflare DO auto-executes at grace expiry via alarms
execute()— permissionless; anyone with the preimage can call- Three routes: SUI→NS, SUI→USDC→NS, SUI direct fallback
Contract: 0xfcd0b2b4f69758cd3ed0d35a55335417cac6304017c3c5d9a5aaff75c367aaff
See SHIELD.md for the security model.
iUSD — Yield-Bearing Stable
Dollar-pegged stable backed by diversified reserves (gold, silver, equities, energy, dollar instruments) custodied natively across BTC, ETH, SOL, and SUI via IKA dWallet threshold signatures.
Reserve Composition
| Tranche | Assets | Target |
|---|---|---|
| Senior (60%) | USDC, BUIDL (T-bills), staked SUI/SOL | ≥100% of supply |
| Junior (40%) | XAUM, XAGM, TSLAx/NVDAx/SPYx, BTC, crude | Absorbs losses first |
150% minimum collateral ratio. 9-decimal steganographic encoding fingerprints every mint.
v2 Package: 0x2c5653668edefe2a782bf755e02bda56149e7b65b56f6245fb75b718941d2ec9
OpenCLOB — Cross-Chain Order Book
Phase 3a is live: the thunder_openclob::bundle Move package is published and the treasury-agents scanner watches bundles over GraphQL. Sub-cent steganographic tags act as order-matching keys. Phase 3b adds a client-side bundle builder (merged) and a keeper settlement path (in-flight).
Package: 0xdcbabe3d80cd9b421113f66f2a1287daa8259f5c02861c33e7cc92fc542af0d7
See docs/superpowers/specs/2026-04-11-openclob-bundle-tags.md.
Pokemon Swarm
.SKI runs a Pokedex coordinator Durable Object that watches GitHub issues, branches, and PRs as a live swarm. Per the naming convention: legendary Pokemon are releases, regular Pokemon with level tags are commits and issues, merged PRs are evolutions (canon forms first — Mega, Gigantamax — otherwise Pokemon Infinite Fusion cross-species forms). Recent evolutions include:
- Silvally RKS (#192) — IKA dWallet + Move policy for delegated subname issuance. Load-bearing for SuiNS Crowds.
- Machamp (#193) — Fighting trainer driving the Silvally de-risking spike. Focus Punch → Bulk Up → Cross Chop → Agility → Close Combat (9/9 Move tests passing).
- Klinklang Gear Grind (#191) — Steel Jacket shipped, first jacket composing on Silvally base. Auto-prune-on-expiry via Mysten #356.
- Mega Sableye (#148) — Seal-encrypted private interaction set; black-diamond roster glyphs; Chronicom ciphertext slice
- Regizapdos (#147, Zapdos × Registeel fusion) — Thunder attachment hardening; cache hydration of attachment refs; SDK-aligned size limits (2 MB/file, 4 files, 5 MB total)
- Raichu Lv.40 — ultron-sponsored thunder gas
- Mr. Mime Lv.42 — shielded Pedersen transfers
- Alakazam Lv.36 — forward secrecy via DEK rotation
- Psyduck Lv.22 — collected-pill fix
- Diglett Lv.18 — dust gate
- Dugtrio Lv.36 — batched shielded deposits
gitcatch — the full commit → evolve → deploy cycle. gitcatch Pokemon commits outstanding moves as Pokemon-named commits, lands the PR as an evolution (canon Mega / Gigantamax first, then Infinite Fusion cross-species naming), and deploys to mainnet. Memory: feedback_gitcatch.md.
The Pokedex DO is bound as PokedexAgent and exposes /api/pokedex/* routes. See docs/superpowers/specs/2026-04-11-pokemon-swarm-agents.md.
SuiNS Crowds — Silvally + Jackets (Vercel Buenos Aires, 2026-04-24)
Crowds is SKI's delegated-subname primitive — what SuiNS Communities, ENS subnames, DNS, and Unstoppable Domains collectively failed to ship. A single SuiNS name becomes a chartered on-chain body whose members hold bounded, time-locked, revocable caps to mint subnames under it. Built for the Vercel Buenos Aires hackathon on 2026-04-24 and landing as a son PR atop MystenLabs/suins-contracts#364.
Silvally RKS — IKA dWallet with subname-creation policy
The load-bearing primitive. An IKA dWallet owns the SuinsRegistration NFT via a Move policy object (ski::dwallet_subname_policy::SubnamePolicy). The policy's typed entry functions are the only path to coordinator::approve_message, and IKA's request_sign refuses to sign without a MessageApproval. That makes the DWalletCap held inside a shared Move object the canonical signing authority — content-aware signing via the Move object graph, not via an IKA protocol feature.
Owner retains all rights through the OwnerCap path. Delegates get a quota- and expiration-bounded delegate_approve_spike path. First Commandment holds: no private keys anywhere, no user-wallet custody transfer.
Status: scaffold in contracts/silvally/, 9/9 Move unit tests passing, real-IKA signatures pulled from @ika.xyz/sdk@0.3.1 generated BCS. Runtime-spike on mainnet is the one remaining unknown — publish + Rumble + delegate_approve_spike → request_sign runbook at contracts/silvally/PRESS_GO.md. See scripts/silvally-press-go.ts for the one-shot helper (--publish / --rumble / --spike).
Jackets — composable variants over the base
Jackets are SKI's composition primitive for extending SubnamePolicy. The base module exposes public(package) hooks like reclaim_quota that only sibling jacket modules in the ski package can call, so external callers can't forge policy-side state changes. Each jacket attaches via the policy's OwnerCap and gates its own admin ops through a jacket-specific capability.
| Jacket | Pokemon | Behavior |
|---|---|---|
| Steel | Klinklang Gear Grind (#191) | Auto-prune-on-expiry via MystenLabs/suins-contracts#356. Records prune events, reclaims quota slots. Shipped in ski::steel_jacket. |
| Fire | Garchomp Dragon Rush (#175) | Hackathon-burst issuance, rate-limited |
| Ghost | Lunala Moongeist (#173) | Seal-gated issuance, opaque roster |
| Electric | Magnezone Magnet Rise (#189) | Cross-crowd alliance issuance via getAgentByName |
| Water | Suicune Aurora Beam (#174) | Auto-Roster cross-chain registration on each issue |
| Psychic | Cresselia Lunar Ballot (#180) | Issuance gated by Seal-encrypted member quorum |
Upstream status
- suins-contracts#356 — Prune expired subdomains by parent authority. Merged 2026-04-17. Enables every timelocked-ticket pattern in the Crowds arc.
- suins-contracts#364 — SubnameCap delegation. Open. Silvally decouples Crowds from its merge — our
dwallet_subname_policymodule doesn't wait on upstream review. When #364 lands, jackets migrate to mint nativeSubnameCapobjects.
Pokemon evolution line for the arc
Parent pitches: #172 Solgaleo (flagship daylight) · #173 Lunala (sealed shadow) · #174 Suicune (cross-chain flow) · #175 Garchomp (5-min stage demo) · #176 Metagross (four-brain architecture). 14 move sub-issues (#177–#191). #192 Silvally RKS is the unlock; #193 Machamp is the Fighting trainer driving the spike through Focus Punch → Bulk Up → Cross Chop → Agility → Close Combat.
Upcoming — Ghost Line for Colosseum Frontier
Active in-flight work for the Ika + Encrypt side track of Colosseum Frontier. Submission deadline approximately 2026-05-11; side-track prize pool $15K USDC via Superteam Earn, main track $2.5M+.
Thesis: native Ika dWallets on Solana plus Encrypt FHE claim logic equals bridgeless and encrypted capital markets on Solana, extending the existing Thunder and Storm UX to cross-chain. We keep the same storm → thunder → claim shell users already know, and swap the substrate to Ika pre-alpha on Solana (solana-pre-alpha.ika.xyz) and Encrypt (docs.encrypt.xyz).
Ghost line issues:
- #101 Gastly Lv.20 — Solana redeem UI scaffold (stage 1)
- #102 Haunter Lv.40 — Sui-side claim + swap + burn + poltergeist keeper pickup (stage 2)
- #103 Gengar Lv.55 — feature-complete Solana redeem for encrypt.xyz Colosseum (stage 3)
- #104 Shelgon Lv.45 — shadow-DKG provisioning; keeper runs DKG alone, user share encrypted to recipient pubkey
- #105 Salamence Lv.65 — user reclaims shadow dWallet on first login
Demo target: a judge opens a phone at the Colosseum stage, receives a live $5 thunder, claims it as native USDC-SPL on sol@name, and sees it land in Phantom within 30 seconds. Zero bridges. The amount is never visible on-chain until claim execution inside an Encrypt FHE function. The Solana-side dWallet is provisioned on-demand via Ika.
Sibyl — The Predictor
Custom oracle. Timestreams flow price through time. Pythia (ultron.sui) channels visions. Offerings flow to the iUSD cache. Sibyl's Court: Anthropologists (research), Hunters (iUSD yield), Rogues (IKA squid breeding).
ultron.sui — Autonomous Agent
Address: 0xa84cebfde3f0522cd893263d5208a633cd226a1585249b32f02d77438094b3c3
Keeper wallet for all server-side signing: iUSD minting, Shade execution, Thunder relay, dust sweeps, fee collection.
Deployed Contracts
| Contract | Package / Object |
|---|---|
| iUSD v2 | 0x2c5653668edefe2a782bf755e02bda56149e7b65b56f6245fb75b718941d2ec9 |
| SUIAMI Roster v3 (reciprocal) | 0x2c1d63b3b314f9b6e96c33e9a3bca4faaa79a69a5729e5d2e8ac09d70e1052fa |
| SUIAMI Roster object | 0x30b45c51a34b20b5ab99e8c493a82c332e9502e5f4380d1be6cc79e712eaab1d |
| Global SUIAMI Storm | 0xfe23aad02ff15935b09249b4c5369bcd85f02ce157f54f94a3e7cc6dfa10a6e8 |
| Shade | 0xfcd0b2b4f69758cd3ed0d35a55335417cac6304017c3c5d9a5aaff75c367aaff |
| Ignite | 0x66a44a869fe8ea7354620f7c356514efc30490679aa5cb24b453480e97790677 |
| Thunder IOU | 0x5a80b9753d6ccce11dc1f9a5039d9430d3e43a216f82f957ef11df9cb5c4dc79 |
| Thunder IOU Shielded | 0x3b1dcced3f585157f48afd14a84f42e65ee57dd38be9dd73d7d94a0a1b690782 |
| Thunder OpenCLOB (bundle) | 0xdcbabe3d80cd9b421113f66f2a1287daa8259f5c02861c33e7cc92fc542af0d7 |
Thunder uses the upstream @mysten/sui-stack-messaging Move package; no custom Thunder or Storm contract. An earlier hybrid-stack package (0xa3ed4fdf...cdf942) was published but never wired into the client and has been stripped from the source tree.
What's Next — Live Pokedex
The authoritative roadmap is the GitHub issue tracker, watched by the Pokedex DO and surfaced via /api/pokedex/*. Major in-flight lines:
- Ghost (#101-105) — Gastly / Haunter / Gengar Solana redeem for Colosseum Frontier; Shelgon / Salamence shadow-DKG provisioning
- Dragon (#78-79) — Garchomp multi-token
Iou<T>, Metagross IKA cross-chain activate - Electric (#76, #80) — Ampharos iUSD gas, Electivire decentralized activity feed via IOU events
- Fire (#75) — Typhlosion iUSD yield on escrowed IOU balances
- Psychic (#77, #94) — Magnezone Seal-encrypted
sealed_memo, Mr. Rime aggregate shielded vault - Thunder v4 (#63, #68-71) — migration to Sui Stack Messaging SDK, compose-preview UX, composable PTB alongside signal
- Security (#54-58) — session cookie hardening, innerHTML XSS sweep, rate limiting, localStorage TTL
Closed recently: Raichu Lv.40 (ultron-sponsored thunder gas), Mr. Mime Lv.42 (shielded Pedersen transfers), Alakazam Lv.36 (DEK rotation forward secrecy), Jolteon Lv.25 (WebSocket thunder subscribe), Diglett Lv.18 (dust gate), and Psyduck Lv.22 (collected pill).
Install
npm install sui.ski
# or
bun add sui.skiEmbed via script tag
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sui.ski/public/styles.css">
<script type="module" src="https://cdn.jsdelivr.net/npm/sui.ski/public/dist/ski.js"></script>Add the widget markup:
<div class="ski-header">
<div class="ski-wallet" id="ski-wallet">
<button class="ski-btn ski-dot" id="ski-dot" style="display:none"></button>
<div id="ski-profile"></div>
<button class="ski-btn" id="ski-btn" style="display:none"></button>
<div id="ski-menu"></div>
</div>
</div>
<div id="ski-modal"></div>Auto-initializes on load.
Embed via bundler
import 'sui.ski';Same DOM markup required.
Events
window.addEventListener('ski:wallet-connected', (e: CustomEvent) => {
const { address, walletName } = e.detail;
});
window.addEventListener('ski:wallet-disconnected', () => {});
window.dispatchEvent(new CustomEvent('ski:request-signin'));Requesting a transaction
import { Transaction } from '@mysten/sui/transactions';
const tx = new Transaction();
// ... build your transaction
window.dispatchEvent(new CustomEvent('ski:sign-and-execute-transaction', {
detail: { transaction: tx, requestId: 'my-req-1' }
}));
window.addEventListener('ski:transaction-result', (e: CustomEvent) => {
const { requestId, success, digest, error } = e.detail;
});Splash sponsorship is applied automatically when active.
Self-Hosting
bun install
npx wrangler login
bun run build && npx wrangler deployNever skip the deploy step. Never use bun run deploy — only npx wrangler deploy. Two workers back the app: dotski (agents, treasury, messaging DOs) and sui-ski (subnames, auth).
Durable Objects
| Binding | Purpose |
|---|---|
SessionAgent |
Signed session verification |
SponsorAgent |
Splash sponsor state |
SplashDeviceAgent |
Per-device Splash activation |
ShadeExecutorAgent |
Auto-executes Shade orders at grace expiry |
TreasuryAgents |
ultron.sui — iUSD minting, collateral, NS acquisition, Thunder relay |
Chronicom |
Per-wallet thunder signal watcher with cached counts |
TimestreamAgent |
Per-group Thunder message storage (Seal-encrypted, one DO per groupId) |
API Routes
| Route | Purpose |
|---|---|
/agents/* |
WebSocket upgrade for DO agents |
/api/health |
Health check |
/api/shade/* |
Shade order management |
/api/suiami/verify |
SUIAMI proof verification (GraphQL-backed) |
/api/timestream/:groupId/:action |
Thunder transport — Seal-encrypted message DO (send/fetch/fetch-one/update/delete/add-participant) |
/api/thunder/chronicom |
Per-wallet signal count cache |
/api/tradeport/listing/:label |
Tradeport listing proxy |
Stack
@mysten/sui^2.13.0,@mysten/suins^1.0.2,@human.tech/waap-sdk1.3.0,@ika.xyz/sdk0.3.1- Messaging:
@mysten/sui-stack-messaging^0.0.2,@mysten/sui-groups^0.0.1 (Thunder) - Encryption:
@mysten/seal^1.1.1 (2-of-3 threshold — Overclock, Studio Mirai, H2O Nodes) - Storage:
@mysten/walrus^1.1.0 (blobs + quilted batch writes) - Solana: Helius (RPC + webhook deposit watchers), Jupiter (routing), Kamino (lending)
- DEX:
aftermath-ts-sdk(aggregation), DeepBook v3, Bluefin CLMM, Cetus CLMM - Marketplace: Tradeport (SuiNS listing proxy)
- Transport:
SuiGrpcClientprimary,SuiGraphQLClientfallback — no JSON-RPC (sunsets April 2026). Cloudflare Workers and DOs cannot speak gRPC (no HTTP/2 bidi streaming), so server code uses GraphQL. GraphQL is read-only, sosui_executeTransactionBlocksubmission falls back through PublicNode → BlockVision → Ankr. - Build:
bun build src/ski.ts --outdir public/dist --target browserwith JSON import for version injection - Deploy: Cloudflare Workers + Durable Objects (
dotski+sui-ski)
Local Development
bun install
bun run dev # watches src/ski.ts
bun run dev:wrangler # wrangler dev with hot reloadLicense
MIT