Documentation Index
Fetch the complete documentation index at: https://docs.ryvo.network/llms.txt
Use this file to discover all available pages before exploring further.
Ryvo settlement consumes two signed message types, ryvo-cmt-v5 (unilateral commitment) and cooperative round messages, and verifies them on-chain. The SDK gives you:
- Builders that produce the exact byte layout the program expects.
- Pre-instruction helpers that wrap one or more signatures into
Ed25519Program instructions, ready to be attached to the same transaction as the settlement call.
The wire format is documented in detail at Reference → Messages. This page is the SDK-level view.
Amountish
Most builders accept Amountish for any unsigned integer (participant IDs, token amounts). Four types are supported:
| Type | Example |
|---|
bigint | 1_000_000n |
number | 1_000_000 |
string | "1000000" |
{ toString(): string } | new BN(1_000_000) |
Values are coerced through toBigIntAmount(); negative numbers throw. For Anchor instruction arguments, use toAnchorBn() (also exported) to convert to anchor.BN.
createCommitmentMessage(params)
Builds a raw ryvo-cmt-v5 message body. You then feed it to one of the Ed25519 helpers below.
import {
createCommitmentMessage,
deriveMessageDomain,
RYVO_CHAIN_IDS,
} from "@ryvonetwork/sdk";
const messageDomain = deriveMessageDomain(client.programId, RYVO_CHAIN_IDS.devnet);
const message = createCommitmentMessage({
messageDomain,
payerId: 1,
payeeId: 2,
tokenId: 2,
committedAmount: 1_250_000n,
});
| Param | Type | Required | Notes |
|---|
messageDomain | Buffer | Uint8Array (16 bytes) | yes | From deriveMessageDomain. |
payerId | Amountish | yes | Payer’s participant_id. |
payeeId | Amountish | yes | Payee’s participant_id. |
tokenId | number | yes | 0–65535, registered in TokenRegistry. |
committedAmount | Amountish | yes | Cumulative amount, not a delta. |
The resulting Buffer starts with [0x01, 0x05] (kind + version) so you can visually confirm a message is a v5 commitment. See on-chain layout.
The SDK also exports nextCommitmentAmount(channelData, delta) (from Account helpers) so you never have to hand-track the cumulative total yourself.
createClearingRoundMessage(params)
Builds a raw cooperative-round message body for clearing rounds.
import { createClearingRoundMessage } from "@ryvonetwork/sdk";
const message = createClearingRoundMessage({
messageDomain,
tokenId: 2,
blocks: [
{
participantId: 1,
entries: [{ payeeRef: 0, targetCumulative: 1_000_000n }],
},
{
participantId: 2,
entries: [{ payeeRef: 1, targetCumulative: 250_000n }],
},
],
});
| Param | Type | Required | Notes |
|---|
messageDomain | Buffer | Uint8Array | yes | Same domain as commitments. |
tokenId | number | yes | The token the whole round settles. |
blocks | ClearingRoundBlock[] | yes | One block per signer, in canonical order. |
Each ClearingRoundBlock is:
type ClearingRoundBlock = {
participantId: number;
entries: {
payeeRef: number; // 0-based index into the round's participant list
targetCumulative: Amountish; // new cumulative obligation toward that payee
}[];
};
The block layout and payeeRef semantics match Reference -> Messages -> Ryvo-round.
Ed25519 helpers
Ryvo’s on-chain verification reads the Ed25519 native program’s instruction data directly. The SDK ships four builders covering the common shapes.
All four return a standard TransactionInstruction targeting Ed25519Program.programId, ready to drop into .preInstructions([ix]) on any Anchor methods builder.
createEd25519Instruction(signer, message)
Simple single-signer Ed25519 instruction. Use this for direct settlement of a single commitment.
import { createEd25519Instruction } from "@ryvonetwork/sdk";
const ed25519Ix = createEd25519Instruction(payerKeypair, message);
await client
.settleIndividual({ payerAccount, payeeAccount, channelState, submitter })
.preInstructions([ed25519Ix])
.signers([submitterKeypair])
.rpc();
| Arg | Type | Notes |
|---|
signer | Keypair | The payer’s keypair (or their authorized_signer). |
message | Buffer | Output of createCommitmentMessage or createClearingRoundMessage. |
Under the hood this uses Ed25519Program.createInstructionWithPrivateKey, so it is compatible with any existing web3.js tooling.
createMultiSigEd25519Instruction(signers, message)
One Ed25519 instruction that carries multiple signatures over the same message.
import { createMultiSigEd25519Instruction } from "@ryvonetwork/sdk";
const roundIx = createMultiSigEd25519Instruction(
[participantA, participantB, participantC],
clearingRoundMessage,
);
await client
.settleClearingRound({ submitter })
.preInstructions([roundIx])
.signers([submitterKeypair])
.rpc();
The SDK lays out the Ed25519 signature blocks in the order of the signers array. That order is observable on-chain and must match the order the program expects for that round.
createMultiMessageEd25519Instruction(entries)
One Ed25519 instruction that carries N signatures over N different messages. Used by bundle settlement, where the payee is settling multiple commitments from the same (or different) payer(s) in one transaction.
import { createMultiMessageEd25519Instruction } from "@ryvonetwork/sdk";
const bundleIx = createMultiMessageEd25519Instruction([
{ signer: payerA, message: commitmentA },
{ signer: payerA, message: commitmentA2 },
{ signer: payerB, message: commitmentB },
]);
await client
.settleCommitmentBundle({ count: 3, payeeAccount, submitter })
.preInstructions([bundleIx])
.signers([submitterKeypair])
.rpc();
count passed to settleCommitmentBundle must match the number of entries in the pre-instruction.
createCrossInstructionMessageEd25519Instruction(signer, message, messageInstructionIndex)
Rare, advanced layout where the Ed25519 instruction references the message bytes stored in another instruction within the same transaction (instead of inlining them). messageInstructionIndex is the zero-based index of that other instruction.
This is used when you want to deduplicate a large message across multiple verifications or place it in a CPI instruction. Most integrations don’t need this.
Low-level encoding helpers
Two functions are exported for rare cases where you want to hand-build a message:
encodeCompactU64(value)
import { encodeCompactU64 } from "@ryvonetwork/sdk";
encodeCompactU64(1_000_000); // => [192, 132, 61]
Seven data bits per byte, continuation bit in the MSB. Matches the encoding used inside ryvo-cmt-v5 and clearing-round messages. Returns a number[].
sha256Bytes(data)
import { sha256Bytes } from "@ryvonetwork/sdk";
const digest = sha256Bytes(Buffer.from("hello"));
Returns a number[] of length 32. Uses Node’s built-in crypto.createHash, so it works in any Node-compatible runtime (Node ≥ 18, Bun, Deno with the Node compat layer, or Next.js server components). Bundlers targeting the browser will need to shim node:crypto.
Putting it together
import {
RyvoClient,
createCommitmentMessage,
createEd25519Instruction,
deriveMessageDomain,
RYVO_CHAIN_IDS,
} from "@ryvonetwork/sdk";
const client = new RyvoClient({ provider });
const messageDomain = deriveMessageDomain(client.programId, RYVO_CHAIN_IDS.devnet);
const message = createCommitmentMessage({
messageDomain,
payerId,
payeeId,
tokenId: 2,
committedAmount: 1_000_000n,
});
const ed25519Ix = createEd25519Instruction(payerKeypair, message);
await client
.settleIndividual({
payerAccount: client.participantAddress(payerKeypair.publicKey),
payeeAccount: client.participantAddress(payeeKeypair.publicKey),
channelState: client.channelAddress(payerId, payeeId, 2),
submitter: payeeKeypair.publicKey,
})
.preInstructions([ed25519Ix])
.signers([payeeKeypair])
.rpc();
This is the minimum viable settlement transaction in @ryvonetwork/sdk. See Recipes for the full lifecycle including participant registration, channel creation, and withdrawals.