Solora

SDK · v0.3.0 · reference

@soloraaa/sdk

Thin TypeScript client over the Soloraa relayer. Submit transfer cycles, verify signatures locally with real Ed25519, ship a bot in 5 lines.

Quickstart

installbash
npm install @soloraaa/sdk @solana/web3.js
my-agent.tsts
import { Keypair } from "@solana/web3.js";
import { SoloraaClient } from "@soloraaa/sdk";

// Zero-config: hits the hosted relayer at relayer.soloraa.tech (devnet).
const client = new SoloraaClient();

const result = await client.executeTransfer({
    destination: Keypair.generate().publicKey.toBase58(),
    amountLamports: 2_000_000, // ≥ rent-exempt minimum
});

console.log(result.signature);    // confirmed devnet tx
console.log(result.explorerUrl);  // ready-to-open explorer link
console.log(result.nonceBefore);  // wallet nonce pre-bump

Client

SoloraaClient talks to a relayer URL. The relayer forwards to the enclave, which holds the sealed Ed25519 key. The client never holds any signing authority over funds.

constructorts
new SoloraaClient(config?: {
    relayerUrl?: string,            // default: https://relayer.soloraa.tech
    walletAuthority?: string,       // pubkey owning the wallet PDA
    agentId?: string,               // logged on the relayer
    fetchImpl?: typeof fetch,       // inject custom fetch
});

Pass walletAuthority when running against your own relayer. Leave it unset for the hosted single-tenant demo — the relayer uses its configured default.

executeTransfer()

Submit a transfer cycle: the relayer asks the enclave to sign a 169-byte SOLORA_INTENT_V2 message, then submitsexecute_transfer on chain. Blocks until Solana reaches confirmed commitment.

signaturets
client.executeTransfer(req: TransferRequest): Promise<ExecutionResult>

type TransferRequest = {
    destination: string | PublicKey;
    amountLamports: bigint | number;
    cycle?: number;
};

type ExecutionResult = {
    signature: string;     // confirmed tx
    explorerUrl: string;   // pre-built explorer link
    nonceBefore: string;   // wallet nonce as of the signing
    cycle?: number;        // echoed from the request
};

Amount minimum: Solana requires receiving accounts to maintain a rent-exempt balance (~890,880 lamports). Send ≥ 2,000,000 lamports to a fresh destination, or reuse one that already holds SOL.

verifyIntent()

Locally re-verify a (message, signature, pubkey) triple. Runs a real Ed25519 check via @noble/ed25519 — never trusts the enclave's word on its own signature. Useful for replay tooling, audit logs, observer pipelines.

signaturets
client.verifyIntent(input: {
    message: Uint8Array;    // 169 bytes
    signature: Uint8Array;  // 64 bytes
    enclavePubkey: string;  // base58
}): Promise<VerifyResult>

type VerifyResult =
  | { ok: true; fields: IntentFields }
  | { ok: false; reason: "wrong_length" | "wrong_domain" | "bad_signature" };

health() & keys()

Two lightweight calls for liveness checks and key discovery.

diagnosticsts
await client.health();
// → { status: "ok", programId: "8tkBct...", cluster: "devnet" }

await client.keys();
// → { authority: "B4D6y...", enclavePubkey: "CNBCY3..." }

keys().enclavePubkey is fetched live from the relayer — handy if you've redeployed the enclave and need the new pubkey before re-registering it on the wallet PDA.

Errors

On-chain rejections throw SoloraaExecutionError with code, errorName, and a docUrl that points at the right error page.

catchts
import { SoloraaExecutionError } from "@soloraaa/sdk";

try {
    await client.executeTransfer({ destination, amountLamports: 2_000_000n });
} catch (err) {
    if (err instanceof SoloraaExecutionError) {
        console.error(err.code, err.errorName, err.docUrl);
        // 6018  IntentNonceMismatch  https://docs.soloraa.dev/errors/intent-nonce-mismatch
    }
}
CodeNameMeaning
6000WalletPausedWallet authority has paused execution.
6017EnclaveSignerMismatchEd25519 ix signer ≠ wallet.enclave_signer.
6018IntentNonceMismatchReplay rejected — nonce stale.
6019IntentExpiredSigned intent expiry passed.
6021IntentPayloadMismatchDestination, amount, or accounts altered.
6027TargetProgramNotAllowedCPI target not in allowlist.
6033BlockhashMismatchSlot/hash not in SlotHashes.
6037MeasurementRevokedEnclave measurement revoked by governance.
6045AttestationMeasurementMismatchAttestation cites unknown measurement.
6046AttestationGovernorMismatchAttestation signed by non-governor key.

Deployment

By default the SDK uses the hosted relayer at relayer.soloraa.tech (devnet, single-tenant shared wallet). For real production, run your own relayer + enclave and point the SDK at it. The repo's PRODUCTION_CUTOVER.md walks the four phases with exact commands.

Back to the developers overview →