CONFIDENTIAL & PROPRIETARY © 2026 Inkwell Finance, Inc. All Rights Reserved. This document is for informational purposes only and does not constitute legal, tax, or investment advice, nor an offer to sell or a solicitation to buy any security or other financial instrument. Any examples, structures, or flows described here are design intent only and may change.This walks through one month of payroll with a Squads v4 (or Altitude) multisig, adapted from
sdks/payroll/examples/squads-payroll.ts.
What you need
@solana/web3.jsand@sqds/multisig(the SDK’s dependencies).- Encrypt’s gRPC client,
@encrypt.xyz/pre-alpha-solana-client. The SDK takes it as a structuralEncryptInputClientand does not pin a build. - Encrypt’s network encryption key (hex).
- A Squads v4 multisig, and a member key with Initiate permission for HR.
- For anyone who cranks, withdraws or creates the company: SOL and an
Encrypt fee deposit (
["encrypt_deposit", payer], created with Encrypt’screate_deposit). Multisig authority instructions never need one.
1 · Set up
squads.authority is the Squads vault PDA (vault index 0 by default).
2 · Create the company (once)
Any payer creates the company. The multisig does not sign.payroll.authority.updatePolicy(...) (auditor,
salary cap, paused) and optionally payroll.authority.setOperator(...) in
the multisig’s first proposal.
3 · Encrypt salaries
encryptAmounts returns one ciphertext handle per amount, authorized to
the payroll program. Amounts are u64 in the mint’s base units. The
handles are all that goes into the proposal.
4 · Propose one vault transaction
Hires first, then the run. The vault is both authority and rent payer.squads.approveIx(member, transactionIndex) and
squads.executeIx(connection, member, transactionIndex).
To fund the vault, add an SPL transfer from the Squads vault to c.vault
in the same proposal.
5 · Crank the run
After the proposal executes, anyone can crank. If anoperator is set,
payments must come from that key.
runPayroll syncs the treasury, prepares the run, creates any missing
wage ledgers, pays every eligible employee and approved bonus, and closes
the run once the headcount is covered.
6 · Withdraw wages (employee)
settleWithdrawal waits for the debit to commit, requests decryption of
the 0-or-amount result, waits for the decryptor, then completes. If the
balance didn’t cover amount, no tokens move and the debit is re-credited
inside FHE. If the payout account gets frozen or closed,
payroll.employee.retarget(...) swaps it.
7 · Grant a view
An employee proves their balance to a lender:ReadCiphertext, re-encrypted
to their key. That read uses Encrypt’s client, not this SDK.
Other multisigs
- Clearsig:
clearsigIntents()returns the 12 custom-intent templates to register on the Clearsig wallet. From the SDK directory:bun examples/clearsig-intents.ts > dagon-payroll-intents.json. - Realms / raw-instruction tools:
serializeInstructions(ixs)turns the authority instructions into JSON to paste as custom instructions.deserializeInstructionsreverses it.