TypeScript SDK
The TypeScript client lives in sdks/typescript/ and publishes as @the-ruby-group/teton. Layouts match the Rust builders byte for byte. Slot and lamport values use bigint.
cd sdks/typescriptbun installbun run buildimport { TETON_PROGRAM_ID, PACKET_DATA_SIZE, PacketTooLargeError, buildRegisterSignerIx, buildSessionActionTx, buildAtomicAttestationTx, buildVerifyNitroAttestationTx, deriveSignerPda,} from "@the-ruby-group/teton";TETON_PROGRAM_ID is EKfHCTnsbRQfURsdmzkmuoxUx7DVt8WsQ5X7t49ZZZh.
Packet MTU ceiling
Section titled “Packet MTU ceiling”Legacy cluster UDP caps a serialized transaction at 1,232 bytes (PACKET_DATA_SIZE). A raw 1,184-byte SNP report does not fit that envelope once signatures and keys are included.
Standard builders call assertPacketFits / probePacket and throw PacketTooLargeError. Submit SNP Mode A / Mode B on Solana v1 (4,096-byte MTU). Test harnesses import the quarantined *Oversized packers. Do not send those to a live cluster.
try { const ix = buildRegisterSignerIx(payer, signer, report, expiresSlot, nonceSlot);} catch (err) { if (err instanceof PacketTooLargeError) { // Use a v1 transaction, or switch to Nitro whose COSE document can fit. } throw err;}Mode A
Section titled “Mode A”buildRegisterSignerIx packs verify_and_register: discriminator + nonce_slot (u64 LE) + 1,184-byte report.
expiresSlot is caller bookkeeping. On-chain TTL is clock.slot + 216_000n (ATTESTATION_TTL_SLOTS).
const ix = buildRegisterSignerIx( payer, workloadSigner, snpReport, // Uint8Array length 1184 0n, // expiresSlot bookkeeping nonceSlot, // bigint);
const tx = buildSessionActionTx( payer, workloadKeypair, consumerIx, recentBlockhash,);PDA helpers: deriveSignerPda, deriveUsedNoncePda, derivePolicyRegistryPda, deriveVcekPda. All use PublicKey.findProgramAddressSync.
Mode B
Section titled “Mode B”buildAtomicAttestationTx always packs VERIFY_ATOMIC_WITH_NONCE_DISCRIMINATOR at index 0 and the consumer at index 1 (@spec TETON-SEC-005). requireNonce is true.
const tx = buildAtomicAttestationTx( payer, consumerProgramId, actionHash, // 32 bytes measurement, // 48 bytes snpReport, // 1184 bytes consumerIx, recentBlockhash, nonceSlot,);Expectation type:
interface AtomicAttestationExpectation { actionHash: Uint8Array; expectedMeasurement: Uint8Array; expectedSigner: Uint8Array | null; requireNonce: boolean; // default true tetonIxIndex: number | null;}Nitro (Mode A and Mode B)
Section titled “Nitro (Mode A and Mode B)”buildVerifyNitroAttestationTx packs verify_nitro_attestation.
| Field | Layout |
|---|---|
| Discriminator | [107, 76, 178, 169, 215, 146, 23, 95] |
mode |
0 Mode A, 1 Mode B |
nonce_slot |
u64 LE |
expected_action_hash |
32 bytes |
doc_len |
u32 LE |
| document | COSE Sign1, doc_len ≤ 4096 |
Mode A uses attested-signer PDA ["attested_signer", workload_signer]. Mode B uses a dummy attested-signer and a nonce PDA seeded with the action commitment SHA-256(slotHash ‖ actionHash ‖ consumerProgramId). Mode B requires a consumer instruction at index 1.
const tx = buildVerifyNitroAttestationTx( payer, workloadSigner, 1, // Mode B nonceSlot, actionHash, coseDocument, nonce, // 32-byte commitment recentBlockhash, consumerIx,);CU telemetry ceiling for these paths is 550,000 (@spec TETON-PERF-001).