SDK Reference

One script tag. Two functions. The entire ZPK protocol — shatter, settle, and reassemble ISO 20022 messages — without exposing any plaintext to the server.

Engine boundary. The ShatterEngine is proprietary and server-side only. zpk.js scrambles your payload locally before it leaves the browser. The server processes noise, not plaintext. Ever.

Quick start

Drop one script tag into your page. That's the install.

<script src="https://zpkpay.com/zpk.js"></script>

Then use two functions for the entire protocol lifecycle:

// Sender — shatter and get a DNA anchor const dna = await zpk.shatter(isoMessage, senderWalletAddress); // Receiver — materialize the original payload const iso = await zpk.materialize(dna, receiverWalletAddress);

The DNA anchor is a 24-character hex string. Pass it to Xahau as the HookParameterValue to enforce settlement before reassembly. The receiver's wallet must match the identity stored at shatter time — any other address gets IDENTITY_MISMATCH.

zpk.shatter()

zpk.shatter(payload, walletAddress, [options]) → Promise<string>

Scrambles payload locally using a key derived from walletAddress, then sends the scrambled noise to the ShatterEngine. Returns a DNA anchor — a 24-character hex string used for settlement and reassembly.

Parameters

ParameterTypeRequiredDescription
payload string required ISO 20022 XML or any string payload. Scrambled in the browser before transmission.
walletAddress string required Sender's XRPL/Xahau wallet address. Used as the entropy source for local scrambling.
options.receiverAddress string optional Receiver's wallet address. If omitted, defaults to the sender address.
options.allowSenderReassembly boolean optional If false, only the receiver may materialize. Default: true.

Returns

A Promise that resolves to a 24-character uppercase hex DNA anchor string (e.g. "A3F8B2C91D4E7F60A1B2C3D4"). Throws on network error or engine rejection.

Example

const isoXml = `<?xml version="1.0"?> <Document> <CdtTrfInitn> <PmtInf>...</PmtInf> </CdtTrfInitn> </Document>`; const dna = await zpk.shatter(isoXml, 'rSenderWallet...', { receiverAddress: 'rReceiverWallet...', allowSenderReassembly: true }); console.log(dna); // "A3F8B2C91D4E7F60A1B2C3D4" // Pass `dna` to Xahau as the HookParameterValue

zpk.materialize()

zpk.materialize(dna, walletAddress, [options]) → Promise<string>

Fetches the scrambled noise for a DNA anchor, then unscrambles it locally using the key derived from walletAddress. The server returns noise — never plaintext. Unscrambling happens in the browser.

Parameters

ParameterTypeRequiredDescription
dna string required DNA anchor returned by zpk.shatter().
walletAddress string required Authorized wallet address (sender or receiver). Must match the identity stored at shatter time.
options.authType string optional "wallet" or "xaman". Default: "wallet".
options.xamanUuid string optional Xaman session UUID. Required when authType is "xaman".

Returns

A Promise that resolves to the original plaintext payload — the same string passed to zpk.shatter(). Throws if the wallet is not authorized or the DNA anchor is not found.

Example

// Receiver materializes using their wallet try { const iso = await zpk.materialize(dna, 'rReceiverWallet...'); console.log(iso); // original ISO 20022 XML } catch (err) { if (err.message === 'Wallet not authorized for this record.') { // identity mismatch } } // With Xaman auth const iso = await zpk.materialize(dna, 'rReceiverWallet...', { authType: 'xaman', xamanUuid: xamanSession.uuid });

Error messages

MessageCause
Wallet not authorized for this record.The wallet address does not match the sender or receiver stored for this DNA anchor.
Only the receiver can materialize this record.allowSenderReassembly was false at shatter time and the sender address was provided.

zpk.verify()

zpk.verify(dna) → boolean

Validates the format of a DNA anchor. Checks that dna is a 24-character uppercase hex string. Does not hit the API.

zpk.verify('A3F8B2C91D4E7F60A1B2C3D4'); // true zpk.verify('invalid'); // false zpk.verify('a3f8b2c91d4e7f60a1b2c3d4'); // false (lowercase)

Use this as a client-side guard before submitting a DNA anchor to Xahau as a HookParameter.

Advanced — Raw API

The sections below document the raw HTTP endpoints that zpk.js calls internally. Use these directly only if you need server-side integration (Node.js, Python, etc.) or a language without a native SDK.

Note on field names. The raw API uses manifest for the payload field (not metadata). If you use zpk.js, this is handled for you automatically.

Base URL

https://api.aifs.dev/api/v1

All requests must use HTTPS. Production pilots use an issued API key passed as the X-AIFS-KEY header.

POST /liquify

POSThttps://api.aifs.dev/api/v1/liquify

Shatters a scrambled payload into 1,024 entropic particles and returns a DNA anchor. Submit a pre-scrambled manifest — never raw plaintext.

Request body

ParameterTypeRequiredDescription
manifeststringrequiredThe pre-scrambled payload (base64). Never submit raw plaintext.
originAddressstringrequiredSender's wallet address.
receiverAddressstringrequiredReceiver's wallet address. Stored as a SHA-256 hash — never as a raw address.
allowSenderReassemblybooleanoptionalIf true, the sender may also reassemble. Default: true.

Response

FieldTypeDescription
successbooleantrue on success.
dnastring24-character uppercase hex DNA anchor. Pass to Xahau as the HookParameterValue.
// Request fetch('https://api.aifs.dev/api/v1/liquify', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-AIFS-KEY': 'your-key' }, body: JSON.stringify({ manifest: scrambledBase64, originAddress: 'rSenderWallet...', receiverAddress: 'rReceiverWallet...', allowSenderReassembly: true }) }); // Response { "success": true, "dna": "A3F8B2C91D4E7F60A1B2C3D4" }

POST /materialize/:dna

POSThttps://api.aifs.dev/api/v1/materialize/:dna

Returns the scrambled noise for an authorized wallet. Unscrambling must be performed client-side — the server never returns plaintext.

Request body

ParameterTypeRequiredDescription
addressstringrequiredThe requesting party's wallet address. Must match sender or receiver.
authTypestringoptional"wallet" or "xaman". Default: "wallet".
xamanUuidstringoptionalXaman session UUID when authType is "xaman".
timestampnumberoptionalUnix ms timestamp for replay protection.

Response

FieldTypeDescription
successbooleantrue on success.
datastringThe scrambled manifest (base64). Unscramble locally to get plaintext.
fetch(`https://api.aifs.dev/api/v1/materialize/${dna}`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-AIFS-KEY': 'your-key' }, body: JSON.stringify({ address: 'rReceiverWallet...', authType: 'wallet', timestamp: Date.now() }) });

POST /anchor-status

POSThttps://api.aifs.dev/api/v1/anchor-status

Checks whether a DNA anchor has been settled on Xahau and confirmed by the Hook. Use this to gate reassembly on confirmed settlement.

Request body

ParameterTypeRequiredDescription
dnastringrequiredThe DNA anchor to check.
// Response (settled) { "settled": true, "txid": "AB12CD34...", "ledger": 1234567 } // Response (pending) { "settled": false, "txid": null }

ZPK-Enforcer Hook

The ZPK-Enforcer Hook is deployed on Xahau Mainnet. Install it on any Xahau receiving address to enforce that only payments carrying a valid ZPK DNA anchor are accepted.

Hook live on Xahau Mainnet. SetHook transaction: 39249C41. The Hook hash is publicly installable — any Xahau address can use it.

Hook installation

Install the Hook on your receiving address using the Xahau Hooks Builder or any Xahau-compatible SDK.

Hook hash

9D35CFCE2ACF4C59E15063AD09119AC4269EA1E11766F6A412D2B1443BDBBF6A

SetHook transaction (xrpl.js)

{ TransactionType: 'SetHook', Account: 'rYourReceivingAddress...', Hooks: [{ Hook: { HookHash: '9D35CFCE2ACF4C59E15063AD09119AC4269EA1E11766F6A412D2B1443BDBBF6A', HookOn: '0000000000000000', HookApiVersion: 0, CreateCode: '', Flags: 1 } }] }

HookParameter format

Every payment to a ZPK-enforced address must include the DNA anchor as a HookParameter.

FieldValue
HookParameterName444E41 (hex encoding of "DNA")
HookParameterValueDNA anchor hex-encoded to ASCII hex. Example: anchor A3F8... becomes 413346382E2E2E
// Build the HookParameter from a DNA anchor const dna = 'A3F8B2C91D4E7F60A1B2C3D4'; const hookParamValue = Buffer.from(dna, 'utf8').toString('hex').toUpperCase(); const hookParameters = [{ HookParameter: { HookParameterName: '444E41', HookParameterValue: hookParamValue } }];

Error codes

CodeHTTPDescription
ZPK_ANCHOR_INVALID400The DNA anchor failed engine signature verification. Rejected before Hook submission.
IDENTITY_MISMATCH403The wallet address does not match the sender or receiver stored for this anchor.
SENDER_REASSEMBLY_DISABLED403allowSenderReassembly was false — only the receiver may materialize.
ZPK_NOT_FOUND404No particle set found for the provided DNA anchor.
ZPK_ALREADY_SETTLED409This anchor has already been settled. Single-use replay protection enforced.
ZPK_ENGINE_ERROR500Internal engine error. Retry with exponential backoff.

DNA anchor format

Every DNA anchor is exactly 24 uppercase hex characters (96 bits).

A 3 F 8 B 2 C 9 1 D 4 E 7 F 6 0 A 1 B 2 | C 3 D 4 <─────────── 20 chars ───────────────────> <─ 4 ─> SHA-256 particle hash engine (truncated) signature (HMAC-SHA256)

The last 4 characters are an HMAC-SHA256 engine signature. Any anchor that does not carry a valid engine signature is rejected with ZPK_ANCHOR_INVALID before it reaches the Hook.

Use zpk.verify(dna) to validate format client-side before submitting to Xahau.