Skip to main content
The TypeScript package is @loyal-labs/loyal-smart-accounts.

What It Exposes

The public surface is split by feature namespace instead of one flat API:
  • programConfig
  • smartAccounts
  • proposals
  • transactions
  • batches
  • policies
  • spendingLimits
  • execution
It also exports lower-level protocol helpers:
  • generated
  • accounts
  • pda
  • codecs
  • errors
  • PROGRAM_ID

Install

bun add @loyal-labs/loyal-smart-accounts @solana/web3.js
# or
npm install @loyal-labs/loyal-smart-accounts @solana/web3.js

Create A Client

import {
  createLoyalSmartAccountsClient,
  pda,
} from "@loyal-labs/loyal-smart-accounts";
import { Connection } from "@solana/web3.js";

const connection = new Connection("https://api.devnet.solana.com");
const client = createLoyalSmartAccountsClient({ connection });

const [settingsPda] = pda.getSettingsPda({
  accountIndex: 1n,
});

Three Ways To Work

This is the most important pattern in the SDK:
  1. Build a raw instruction
  2. Build a prepared operation
  3. Use the client send flow

1. Raw Instruction

Use smartAccounts.instructions.create(...) when you want full transaction assembly control.
import {
  codecs,
  smartAccounts,
} from "@loyal-labs/loyal-smart-accounts";
import { Keypair } from "@solana/web3.js";

const creator = Keypair.generate();

const instruction = smartAccounts.instructions.create({
  treasury: creator.publicKey,
  creator: creator.publicKey,
  settings: settingsPda,
  settingsAuthority: null,
  threshold: 1,
  signers: [
    {
      key: creator.publicKey,
      permissions: codecs.Permissions.all(),
    },
  ],
  timeLock: 0,
  rentCollector: null,
});

2. Prepared Operation

Use smartAccounts.prepare.create(...) when you want the SDK to package the operation cleanly before sending it yourself.
const prepared = await smartAccounts.prepare.create({
  treasury: creator.publicKey,
  creator: creator.publicKey,
  settings: settingsPda,
  settingsAuthority: null,
  threshold: 1,
  signers: [
    {
      key: creator.publicKey,
      permissions: codecs.Permissions.all(),
    },
  ],
  timeLock: 0,
  rentCollector: null,
});

await client.send(prepared, {
  signers: [creator],
});

3. Client Send Flow

Use client.smartAccounts.create(...) when you want the highest-level path.
await client.smartAccounts.create({
  treasury: creator.publicKey,
  creator,
  settings: settingsPda,
  settingsAuthority: null,
  threshold: 1,
  signers: [
    {
      key: creator.publicKey,
      permissions: codecs.Permissions.all(),
    },
  ],
  timeLock: 0,
  rentCollector: null,
});

Choosing The Right Level

Use thisWhen you want
instructions.*Full control over transaction composition
prepare.*A reusable prepared operation before send
client.*The shortest path from request to signature
Every feature namespace follows the same model: raw account classes, optional raw instruction builders, prepared-operation builders, account queries, and bound client methods. For example, proposals expose create/approve/reject/cancel operations, transactions expose create/buffer/log-event operations, and execution exposes async, synchronous, settings, batch, and policy execution helpers.
The low-level SDK exposes both current policy APIs and legacy spending-limit instructions. For new Loyal product flows, prefer policy-based spending limits through the vault adapter described below.

PDA Helpers You Will Use Early

Two helpers matter immediately:
  • pda.getSettingsPda({ accountIndex })
  • pda.getSmartAccountPda({ settingsPda, accountIndex })
The first derives the configuration root. The second derives a sub-account that can actually hold assets and execute.
Do not send funds to the settings PDA by accident. In most integrations, the sub-account or vault PDA is the address users should treat as the asset-holding account.

App-Facing Vault Adapter

Most Loyal frontend flows use @loyal-labs/smart-account-vaults on top of this SDK. That package turns the lower-level Squads account model into app-ready APIs for:
  • vault portfolio and activity reads
  • proposal summaries and approval actions
  • policy signer connect/disconnect flows
  • spending-limit policy create, update, delete, and top-up actions
  • wallet-adapter sending for prepared operations
import {
  createSmartAccountVaultsClient,
  sendPreparedWithWallet,
} from "@loyal-labs/smart-account-vaults";

const vaults = createSmartAccountVaultsClient({
  connection,
  programId,
  walletDataClient,
});

const overview = await vaults.fetchOverview({ settingsPda });
Read Frontend and Vault APIs for the full frontend integration layer.
The TS SDK already exposes the broader feature namespaces listed above. This page stays centered on the create flow and the main integration pattern so it remains useful instead of turning into a dump of every operation.