@ryvonetwork/sdk
v0.6.0
Published
TypeScript SDK for the decentralized Ryvo Protocol on Solana
Maintainers
Readme
Ryvo Protocol SDK
TypeScript SDK for interacting with Ryvo Protocol on Solana.
This package exposes:
- the generated Anchor IDL and TypeScript program type
- bucket-aware PDA derivation and raw account decoders
- message-domain and signed-message builders
- Ed25519 pre-instruction helpers for unilateral and cooperative settlement
- a
RyvoClientthat works against the deployed v6+ bucket-model program - gateway-grade commitment envelope verification (signature + on-chain headroom checks)
Install
npm install @ryvonetwork/sdkv0.6.0 — Bucket-model rewrite (BREAKING)
0.6.0 realigns the SDK with the v6 bucket-model program (live on devnet at
BGSG6gUuUa6SDVfbWB7VdQ2Sw1fBmyQwNX2ERQsk6iXS). The legacy per-account PDAs
no longer exist on-chain, so the corresponding helpers were removed:
| Removed (0.5.x) | Replacement (0.6.x) |
| ------------------------------------- | ------------------------------------------------------------- |
| findParticipantPda(programId, owner)| findOwnerIndexBucketPda + findParticipantBucketPda* |
| findChannelPda(programId, payerId, payeeId, tokenId) | findChannelBucketPdaForPair(...) |
| RyvoClient.fetchParticipant(owner) | client.findParticipantByOwner(owner) |
| RyvoClient.fetchChannel({ channelState }) | client.fetchChannelByOwners(payer, payee, tokenId) |
| participantData.tokenBalances | decodeParticipantBucket(data).slots[…].tokenBalances |
RyvoClient now accepts an AnchorProvider or a plain Connection
(RyvoClient.fromConnection) — fetchers work in both modes; instruction
builders require the provider.
Read-only client (server / facilitator)
import { Connection, PublicKey } from "@solana/web3.js";
import { RyvoClient, USDC_TOKEN_ID } from "@ryvonetwork/sdk";
const client = RyvoClient.fromConnection(new Connection(rpcUrl));
const payer = await client.findParticipantByOwner(new PublicKey(payerOwner));
const lane = await client.fetchChannelByOwners(
new PublicKey(payerOwner),
new PublicKey(payeeOwner),
USDC_TOKEN_ID,
);
if (!lane) throw new Error("Channel not initialised");
console.log({
settledCumulative: lane.lane.settledCumulative.toString(),
lockedBalance: lane.lane.lockedBalance.toString(),
authorizedSigner: lane.lane.authorizedSigner.toBase58(),
});Build a commitment + settle it
import {
buildGatewayCommitmentPayload,
createGatewayCommitmentMessage,
encodeGatewayCommitmentEnvelope,
RyvoClient,
} from "@ryvonetwork/sdk";
import { ed25519 } from "@noble/curves/ed25519";
const payload = buildGatewayCommitmentPayload({
programId: client.programId,
cluster: "devnet",
payerId,
payeeId,
tokenId: USDC_TOKEN_ID,
committedAmount: 5_000n,
authorizedSettler: facilitator.publicKey,
signer: payerOwner.publicKey,
});
const message = createGatewayCommitmentMessage(payload);
const signature = ed25519.sign(message, payerOwner.secretKey.slice(0, 32));
const envelope = encodeGatewayCommitmentEnvelope({
...payload,
signature: Buffer.from(signature).toString("base64"),
});
// Submit settlement (later, batched, etc.)
const tx = await client.buildSettleIndividualTx({
payerParticipantId: payerId,
payeeParticipantId: payeeId,
tokenId: USDC_TOKEN_ID,
submitter: facilitator.publicKey,
signature,
signerPubkey: payerOwner.publicKey,
messageBytes: message,
});Strict envelope verification (gateway hot path)
verifyGatewayCommitmentEnvelopeFull performs the lightweight signature
verification plus the structural and business checks the on-chain handler
would otherwise reject the transaction for. Each failure carries a
failureReason so the gateway can return an actionable HTTP status:
| Reason | HTTP |
| ---------------------------------- | --------------------- |
| signatureInvalid, unsupportedVersion, messageDomainMismatch, programIdMismatch, chainIdMismatch, tokenMismatch, payerPayeeMismatch, signerNotAuthorized, authorizedSettlerMismatch | 422 |
| committedAmountNotMonotonic | 409 Conflict |
| insufficientHeadroom | 402 Payment Required |
const result = verifyGatewayCommitmentEnvelopeFull(envelope, {
programId: client.programId,
chainId: 1,
tokenId: USDC_TOKEN_ID,
payerParticipantId: payerId,
payeeParticipantId: payeeId,
authorizedSigner: lane.lane.authorizedSigner,
expectedAuthorizedSettler: facilitator.publicKey,
laneState: lane.lane,
previousAcceptedCommitted: redisLatestAcceptedCommitted,
});
if (!result.ok) {
return mapToHttp(result.failureReason);
}Notes
- By default the SDK uses the live program id embedded in the generated IDL
(
BGSG6gUuUa6SDVfbWB7VdQ2Sw1fBmyQwNX2ERQsk6iXS). Override vianew RyvoClient({ provider, programId }). ParticipantBucketandChannelBucketare intentionally absent from the IDL because the program initialises them via CPI. The SDK shipsdecodeParticipantBucket/decodeChannelBucketto read them from raw account data.- The package name is
@ryvonetwork/sdkand the released line is0.6.x.
