Procurement · Access

Put the right person at each decision.

Organization membership connects wallet identity to a business role. Use it to separate request creation, approval, and administration without sharing keys.

Six roles cover the v1 workflow

RoleScope
OwnerFull organization control, including Owner membership changes.
AdminManages members and operations but cannot grant, demote, or revoke Owner.
ApproverReviews frozen mandates and can approve or reject eligible spend.
RequesterCreates and follows procurement work without membership administration.
FinanceReviews spend, receipts, and recoveries without changing provider selection.
AuditorReads policy, approval, audit, and receipt evidence without mutation rights.

Add a wallet through the app or SDK

Owners and Admins can open Team in the organization app. Enter the member's exact Solana wallet and choose the narrowest role that fits the job.

TypeScript
const organization = procurement.forOrganization("org_acme");

const member = await organization.addOrganizationMember({
  actorId: approverWallet,
  role: "Approver",
}, { idempotencyKey: crypto.randomUUID() });

const members = await organization.listOrganizationMembers();

A valid wallet becomes active immediately. Repeating the same add request with the same role is safe. Use the update method when the role must change.

Approval is tied to a different authenticated actor

The requester freezes the selected provider, price, evaluator, work reference, and budget in a mandate. An eligible Owner, Admin, or Approver reviews that exact mandate from their own wallet session.

TypeScript
const pending = await approverClient
  .forOrganization("org_acme")
  .listPendingApprovals({ workspaceId: "ws_research" });

await approverClient
  .forOrganization("org_acme")
  .decideExecutionApproval(
    pending.items[0].executionId,
    { decision: "approved", reason: "Within delegated research budget." },
    { idempotencyKey: crypto.randomUUID() },
  );

The API rejects self-approval. In the product app, each wallet session is held in an HTTP-only cookie and can be revoked without deleting its prior decisions. A change to the frozen terms creates a new decision subject.

Revoke access without erasing history

TypeScript
await organization.updateOrganizationMember(
  approverWallet,
  { status: "revoked" },
  { idempotencyKey: crypto.randomUUID() },
);

Revocation blocks organization access on the next API request. Prior approvals and audit records keep the original actor wallet so the transaction history remains attributable.

  • Use one wallet per human or service identity.
  • Keep Owner membership limited and use Approver for routine review.
  • Revoke departed members before rotating operational credentials.
  • Review the audit ledger after every role or status change.