SDK reference

The browser SDK lives at web/src/lib/saferoomTx.ts. It is a thin TypeScript layer that builds the raw Solana instructions and (for Pyth triggers) wraps the Pyth Solana Receiver flow.

The SDK has no dependency on the Anchor client. Discriminators are computed locally with sha256, so the SDK runs in the browser without any IDL JSON.

Install

git clone https://github.com/deadmans-zone/deadmans.git
cd deadmans/web
npm install

The SDK file is web/src/lib/saferoomTx.ts. Import the functions you need directly from there. There is no published npm package yet.

Core imports

import {
  SAFEROOM_PROGRAM_ID,
  PYTH_FEEDS,
  TriggerKind,
  OracleKind,
  ActionKind,
  RoomStatus,
  deriveRegistry,
  deriveRoom,
  deriveVault,
  deriveAta,
  buildCreateSafeRoomIx,
  buildTriggerSafeRoomIx,
  buildDisarmSafeRoomIx,
  buildPythTriggerTransactions,
  feedIdHexToBytes,
  NATIVE_MINT,
} from "@/lib/saferoomTx";

buildCreateSafeRoomIx

const { ix, room, vault } = buildCreateSafeRoomIx({
  owner: walletPubkey,
  roomId: new BN(Date.now()),
  expirySlot: new BN(currentSlot + 216_000),

  triggerKind: TriggerKind.PriceBelow,
  triggerOracleKind: OracleKind.Pyth,
  triggerOracle: new PublicKey("11111111111111111111111111111111"),
  triggerFeedId: feedIdHexToBytes(PYTH_FEEDS["SOL/USD"]),
  triggerThreshold: new BN(244 * 1e8),

  actionKind: ActionKind.TokenTransfer,
  actionAmount: new BN(0.01 * 1e9),
  actionMinReceived: new BN(0),

  actionMint: NATIVE_MINT,
  ownerSource: deriveAta(walletPubkey, NATIVE_MINT),
  actionDestination: deriveAta(walletPubkey, NATIVE_MINT),
});

Returns the instruction and the derived room + vault pubkeys so you can store them client-side.

buildPythTriggerTransactions

Used when the room's trigger kind is PRICE_BELOW or PRICE_ABOVE. Returns one or more VersionedTransaction instances ready to be signed.

const txs = await buildPythTriggerTransactions({
  connection,
  wallet: anchorWallet,
  feedIdHex: PYTH_FEEDS["SOL/USD"],
  responder: walletPubkey,
  room,
  vault,
  actionMint: NATIVE_MINT,
  destination: ownerWsolAta,
});

const signed = await wallet.signAllTransactions(txs.map((t) => t.tx));
for (const tx of signed) {
  const sig = await connection.sendTransaction(tx);
  await connection.confirmTransaction(sig, "confirmed");
}

Internally this:

  1. Calls Hermes (https://hermes.pyth.network/) for the latest price update.
  2. Posts the update to the Pyth Solana Receiver, creating an ephemeral PriceUpdateV2.
  3. Appends our trigger_safe_room instruction in the same bundle, consuming the just-posted account.

buildTriggerSafeRoomIx

Used only for TIME_AFTER triggers (the Pyth flow above already wraps the price case). A single instruction in a single transaction.

const ix = buildTriggerSafeRoomIx({
  responder: walletPubkey,
  room,
  vault,
  actionMint: NATIVE_MINT,
  destination: ownerWsolAta,
  oracle: new PublicKey("11111111111111111111111111111111"), // ignored for time triggers
});

buildDisarmSafeRoomIx

Owner-only. Refunds the vault and flips status to DISARMED.

const ix = buildDisarmSafeRoomIx({
  owner: walletPubkey,
  room,
  vault,
  ownerToken: ownerWsolAta,
});

Account decoding

const account = await connection.getAccountInfo(room);
const decoded = decodeRoom(account.data);
console.log(decoded.status, decoded.triggerThreshold.toString());

decodeRoom parses the full SafeRoom account by offset. No IDL required.

Constants

constvalue
SAFEROOM_PROGRAM_ID4Tkkn3mPZELX1dFWVUVnqiCeD3P9z76GSzmFBsmNZ527
PYTH_RECEIVER_PROGRAM_IDrec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ
REGISTRY_SEED"saferoom_registry"
ROOM_SEED"safe_room"
VAULT_SEED"vault"