Reference

RPC method surface

Everything a dApp can call on window.loroco (and the opt-in window.chia mirror). Each method is in exactly one approval class. Reads return immediately; writes pop a per-call approval dialog.

read — no approval, requires a prior connection   write — pops an approval popup every call   stub — returns empty/graceful until full impl lands

Calling conventions

One canonical name, many aliases

The router canonicalises before gating, so the same method answers to every namespace dApps use in the wild:

chia_*
Goby-legacy + Sage WC2 prefixed — chia_connect, chia_send, chia_getNFTs
chip0002_*
WalletConnect2 topic-style CHIP-0002 — chip0002_signMessage
snake_case
Sage WC2 raw — get_address, sign_message_by_address
camelCase
The canonical names listed below — signCoinSpends, createOffer
Gating rule
Aliases in METHOD_ALIASES map to a canonical that must be present in NO_APPROVAL_METHODS or ALWAYS_APPROVAL_METHODS. Adding a new canonical without registering its approval class makes it silently mutating-without-approval.
CHIP-0002

Connection & account

MethodClassParamsResult
connectwrite{ eager?: boolean }boolean — the only entry point; grants read access
chainIdreadChainId (mainnet / testnet)
requestAccountswritestring[] — connect + accounts in one round-trip (prompts if not connected)
accountsreadstring[] — addresses without prompting; throws 4900 if unconnected
getAddressread{ address }
walletSwitchChainwrite{ chainId }null
walletWatchAssetwrite{ options: { assetId, symbol, logo? } }boolean — popup shows the assetId verbatim
Read surface

Coins, balances & chain data

Served straight from the JS coin-store (chrome.storage.local["coins.<fp>"]) so any dApp hitting the namespaces above gets WC-compatible reads without a new WASM build.

MethodClassParamsResult
getPublicKeysread{ limit?, offset?, hardened? }Hex[]
getAssetCoinsread{ type, assetId, … }SpendableCoin[]
getAssetBalanceread{ type, assetId }AssetBalance
filterUnlockedCoinsread{ coinNames: Hex[] }Hex[]
getCoinsread{ limit?, offset?, … }CoinView[]
getCoinsByIdsread{ coinIds: Hex[] }CoinView[]
isAssetOwnedread{ type: "cat"|"did"|"nft", assetId }boolean
getDerivationsread{ limit?, offset? }Derivation[]
getTransactionsread{ limit?, offset?, pendingOnly? }TransactionView[]
getPendingTransactionsreadTransactionView[]
Read surface

Tokens, NFTs & offers

MethodClassParamsResult
getCatsread{ limit?, offset? }CatAssetView[] — enriched with Dexie name/symbol/icon
getAllCatsread{ limit?, offset? }CatAssetView[]
getTokenread{ assetId }CatAssetView | null
getNFTsread{ … }NftInfo[] | { nfts }
getNFTInforead{ coinId?, launcherId? }NftInfo | null
getNftCollectionsstub{ limit?, offset? }NftCollectionInfo[]
getNftCollectionstub{ collectionId }NftCollectionInfo | null
getMinterDidIdsstub{ limit?, offset? }Hex[]
getDidsread{ limit?, offset? }DidInfo[] — from the local dids.<fp> store
getOffersread{ limit?, offset?, includeCancelled? }OfferView[]
getOfferread{ id }OfferView | null
Mutating surface

Signing & spending

Every method here pops an approval dialog whose body must show the actual recipient, amount, fee and asset id — never a bare count.

MethodClassParamsResult
signMessagewrite{ message: Hex, publicKey: Hex }Hex
signMessageByAddresswrite{ message, address }{ publicKey, signature }
signCoinSpendswrite{ coinSpends, partialSign? }Hex — BLS aggregated sig; popup decodes the bundle
transfer (chia_send)write{ to/address, amount, assetId?, fee? }{ id } | {}
sendTransactionwrite{ spendBundle }TransactionResp[]
bulkSendXchwrite{ outputs[], fee? }{ id } | {}
bulkSendCatwrite{ assetId, outputs[], fee? }{ id } | {}
multiSendwrite{ outputs[], fee? }{ id } | {}
combinewrite{ maxInputs?, fee? }{ id } | {}
splitwrite{ parts, fee? }{ id } | {}
Mutating surface

Offers, tokens, NFTs & DIDs

MethodClassParamsResult
createOfferwrite{ offerAssets, requestAssets, fee? }{ id, offer } — persists input coins + origin
takeOfferwrite{ offer, fee? }{ id } — popup shows engine-verified royalty amount + on-chain puzzle hash
cancelOfferwrite{ id, fee?, secure? }{ id, cancelled } | {} — filtered by origin stamp
issueCatwrite{ amount, fee?, … }{ id, assetId }
addNftUriwrite{ launcherId, uri, kind, fee? }{ id, launcherId }
bulkMintNftswrite{ didCoinId, didDerivationIndex, mints[], … }{ nftIds[] }
createDidwrite{ fee?, … }{ id, didId, didCoinId, didDerivationIndex }
transferDidwrite{ launcherId, address, fee? }{ id, launcherId }
normalizeDidswrite{ … }{ id }
Hardened + unhardened
Every engine endpoint that signs accepts a derivation_kind. Coins imported from Sage on the hardened path would otherwise fail to sign against a handler hardcoded to unhardened.
Errors

CHIP-0002 error codes

Thrown as a ChiaProviderError with { code, message, data }.

CodeNameMeaning
4000InvalidParamsParams failed validation.
4001UnauthorizedOrigin not connected — thrown before any work, and before any approval popup.
4002UserRejectedThe user declined the approval dialog.
4003SpendableBalanceExceededNot enough spendable balance for the requested spend.
4004MethodNotFoundUnknown or not-yet-implemented method.
4005NoSecretKeyWallet doesn't own a secret key the request needs.
4029LimitExceededPayload exceeded the 4 MiB cap (DoS guard) or a rate limit.