Skip to main content
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.
Not on npm. @dagon/payroll-sdk (version 0.1.0, BUSL-1.1) is marked private and has not been published. It lives in the Dagon monorepo at sdks/payroll and ships as TypeScript source (src/index.ts); the examples run with bun. The program it targets is not deployed.Pre-alpha encryption. encryptAmounts currently sends Encrypt’s dev executor a 17-byte “mock ciphertext” that contains the plaintext value. It will be replaced with real client-side encryption and a proof when Encrypt ships them. Until Encrypt Alpha 1, salaries are not confidential.
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.js and @sqds/multisig (the SDK’s dependencies).
  • Encrypt’s gRPC client, @encrypt.xyz/pre-alpha-solana-client. The SDK takes it as a structural EncryptInputClient and 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’s create_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.
Policy starts empty. Put 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.
Members approve and execute in the Squads app, or build the instructions with 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 an operator 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:
The lender reads the copy through Encrypt 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. deserializeInstructions reverses it.
See Multisig integration.

SDK surface