Developer guide
App records
Use signed records from an existing website, a mobile app or a service running on Xity Keep assets, users and application data connected without handing over a wallet key
1 Connect an application
Create a Xity Connect application and add the callback addresses used by your website or mobile app Create a record namespace from its workspace The namespace has a permanent name, an owner wallet and a client_id linking it to the application Namespace metadata, signing keys and usage are public
Choose public values or encrypted values at creation You can also allow user areas Each active wallet then writes only inside users/its wallet address/ unless it is the owner or a delegated writer These settings are permanent
2 Choose how to authorise changes
For a user facing app, request records:read and records:write during the OAuth consent flow A token never signs a transaction Use requestRecordApproval to ask the user to review and sign inside Xity Connect Open approval_path on Xity Connect and poll approval(request_id) Approval requests expire after five minutes
For a backend service, generate a separate Ed25519 key on your server and add its public key under Namespace settings, Access A writer can save and remove records A reader can fetch encrypted envelopes Neither can change ownership, keys or settings Removing the key stops new access immediately
Download the client and keep xity.mjs alongside your integration code
import { XityClient } from './xity.mjs';
export async function requestRecordSave(config, namespace, key, value, version, spaceId) {
const client = new XityClient(config);
await client.capabilities();
return client.requestRecordApproval(namespace, key, value, {
expectedVersion: version,
spaceId
});
}Supply apiUrl, appId and getToken from your own app configuration and OAuth session Keep tokens out of source control Backend signing uses buildAppTransaction and submitAppTransaction Save the built transaction before submitting so a retry can send the exact same signed content
3 Write and read records
Use a record name of up to 128 characters Folder prefixes help organise content Values support JSON objects, lists, strings, booleans, null and safe integers Store decimals as strings Each record has a version expected_version: 0 creates a new name Later saves use the current version A conflicting save is refused so another writer cannot silently replace it
APP_RECORD_PUT accepts app_id, key, value, optional space_id and optional expected_version APP_RECORD_DELETE accepts app_id, key and optional expected_version APP_RECORD_BATCH accepts app_id and up to 32 distinct operations in ops Every operation either succeeds together or the entire batch is refused
Private namespaces accept version 1 authenticated encryption envelopes using AES 256 GCM or ChaCha20 Poly1305 The browser client supports AES 256 GCM The associated data binds the ciphertext to chain_id, genesis_hash, app_id and key Keep content keys outside Xity and deliver them only to intended readers API access does not grant decryption
Deletion creates a new version It retains all earlier transactions and does not free the name allowance Do not place unencrypted personal data, passwords or secret keys on the chain
4 Link a Space NFT
Set space_id when saving a record The asset must exist and must have been created by the namespace’s connected application Use null to clear the reference The link grants no permission to transfer, list or update the asset NFT actions retain their own wallet signatures, ownership checks and royalty rules
Read an app’s assets with GET /v1/spaces?app_id=client_id Filter records with space_id Keep your application in control of how its content, receipts, access rights or marketplace entries refer to that asset
5 Plan for limits and recovery
A wallet can own five namespaces Each namespace starts with 10,000 record names, 16 KB per value, 32 MB of live values and 512 MB of lifetime writes The operator can adjust allowances within chain limits Tombstones count as record names and all writes count toward lifetime usage
Read the error before retrying app_cas_conflict means fetch the latest version and compare your draft app_nonce_conflict means another wallet action changed the nonce app_suspended requires an operator review A network timeout does not mean failure Check the transaction ID and retry its exact signed content before creating a replacement
Ownership uses an offer and acceptance Acceptance removes delegated keys The recipient reconnects a Xity Connect application they own and receives any content keys separately Deleting an OAuth application stops linked writes through the platform The namespace owner can reconnect from settings
Verify what was recorded
After a block is sealed, export a record version proof It contains the signed transaction, operation position, Merkle path and block header Private proof access follows record permissions A user cannot export a multiuser batch that would expose another user’s envelope
The Python node client includes verify_proof Pin the chain ID, genesis hash and operator sealer public key independently, or supply a separately trusted block hash for older blocks without a seal A proof verifies inclusion and the transaction signature When expected_version is present, it also binds the claimed version Without that field, the result is inclusion only The proof does not establish present ownership, current access rights or who was authorised historically without the earlier chain state
API reference
https://api.xityconnect.org
GET /v1/apps?owner=address&client_id=client_id
GET /v1/apps/namespace
GET /v1/apps/namespace/record?key=name
GET /v1/apps/namespace/records?prefix=folder/&limit=50
GET /v1/apps/namespace/record/history?key=name
GET /v1/apps/namespace/record/proof?key=name&version=1
POST /v1/transactions/prepare
POST /v1/wallet-requests
POST /v1/app-transactions/submit
Authenticated reads use a session or a scoped OAuth token Backend keys sign reads with X-Xity-App-Key-Id, X-Xity-App-Read-Ts, X-Xity-App-Read-Nonce and X-Xity-App-Read-Sig Signatures use the xity.app.read.v1 domain, a fresh nonce, chain ID and genesis hash Each signature can be used once within two minutes The SDK constructs these headers for you
Application writes use xity.app.tx.v1 with the chain ID and a body containing genesis_hash and tx Reconstruct signing bytes locally before signing a prepared transaction Existing coin and NFT signing formats remain unchanged