Approvals
Get, list, approve and reject — without duplicating action creation.
Status and boundary
Proposed target SDK domain based on the verified public activity/decision surface. “Approval” is the application-facing name for authorization progress on one protected business action. It is not a smart wallet, blockchain multisignature transaction, account-abstraction object or delegation mechanism.
The underlying protected business call creates the durable action and, when review is required, its approval record. There is no redundant createApproval: creation through both paths could duplicate or detach authorization from the action it controls.
Public methods#
| TypeScript browser | TypeScript server | React adapter | Python server | Go server |
|---|---|---|---|---|
| Scoped review actions only | Proposed target | Calls the TypeScript core in a client component; no approval hook is implied | Proposed server target | Proposed server target |
sdk.approvals.get({ approvalId }, options?)
sdk.approvals.list({ states?, actionKinds?, cursor? }, options?)
sdk.approvals.approve({ approvalId, response }, options?)
sdk.approvals.reject({ approvalId, response, reason? }, options?)
await sdk.approvals.get(approval_id=approval_id)
await sdk.approvals.list(states=states, action_kinds=action_kinds, cursor=cursor)
await sdk.approvals.approve(approval_id=approval_id, response=response)
await sdk.approvals.reject(approval_id=approval_id, response=response, reason=reason)
approval, err := sdk.Approvals.Get(ctx, getInput)
page, err := sdk.Approvals.List(ctx, listInput)
approval, err := sdk.Approvals.Approve(ctx, approveInput)
approval, err := sdk.Approvals.Reject(ctx, rejectInput)
Every call is organization/account scoped by authenticated context. get requires one approval ID. list supports bounded pagination plus state/action filters. approve and reject require fresh response evidence from an allowed participant, bound to the approval fingerprint. A free-form reason is metadata only and never authorization.
Approval object#
| Field | Meaning |
|---|---|
approvalId |
stable approval identity |
requestId |
caller-stable identity of the underlying business action |
actionKind |
wallet, policy, user, organization, signing, sending, treasury funding, export or recovery action class |
resource |
exact resource kind and identifier |
actor |
safe initiating requester/service identity and wallet control mode |
payloadFingerprint |
canonical identity of immutable protected material |
state |
actionRequired, awaitingApprovals, approved, denied, expired, executing, succeeded, failed or unknown |
requiredApprovals / receivedApprovals |
threshold and distinct accepted participants when multi-party review applies |
canApprove / canReject |
current caller capability after server-side policy evaluation |
createdAt / expiresAt |
issuance and expiry boundaries |
The response never exposes signing secrets, raw session credentials or reusable authorization material. Participant detail is limited to safe references needed by the caller's granted scope.
Lifecycle and correlation#
business call -> action recorded -> approval not required | awaiting approvals
awaiting approvals -> approved | denied | expired
approved -> executing -> succeeded | failed | unknown
An action may complete immediately under valid grants, so not every operation waits. Embedded approvals use owner-authorized participants; server-wallet approvals use its named service/admin participants, policies and limits. End-user login cannot count as treasury service authority. Thresholds count distinct approvals over one fingerprint. This off-chain logic changes no wallet bytecode or signing format.
Three states remain distinct:
- Approval state answers whether the required actors authorized the protected action.
- Operation state answers whether the backend action executed and what durable result it produced.
getOperation(requestId)remains the restart and unknown-outcome facade. - Chain transaction status answers whether a submitted transaction was broadcast, included, executed or finalized.
An approved send may still fail before submission or on chain. A chain hash does not prove approval, execution success or finality.
Continuation and duplicate safety#
The existing authorization handler and getOperation({ requestId, authorization }) continuation submit response evidence to the same backend record represented here. They are not an independent vote store. Automatic handler submission and explicit sdk.approvals.approve or getOperation continuation cannot both submit the same response.
Every response binds approval ID, request ID, original action kind/resource/requester, authorized approving actor, payload fingerprint and expiry. The initiating actor and approving actor remain distinct and need not be the same person. Exact replay of the same approver response returns the recorded vote without adding another approval. A second response from the same participant cannot count twice. Changed response proof, changed action material, unauthorized participant, expiry, stale policy/resource version or foreign scope fails without advancing the action.
No actor may approve a membership, policy or ownership change using authority obtained only from that pending change. Root or owner changes are authorized by the current valid authority at the effect boundary. Approval never bypasses the underlying wallet, policy, user or organization rules.
Denial, expiry and failures#
Denial, expiry and insufficient approvals are explicit terminal authorization outcomes and produce no protected effect. A read is effect-free. Transport timeout after an approve/reject submission makes the response outcome unknown; recover the same approval or operation identity. Do not create a replacement action, blind-repeat a decision or rebroadcast a transaction.
Acceptance#
- Positive: get/list expose bounded approval progress, and each valid distinct participant advances only the matching immutable action.
- Positive: approval, operation and chain status remain separately observable but correlated by stable IDs.
- Negative: self-elevation, duplicate votes, changed payloads, foreign resources, expired proof or approval under a stale policy cannot authorize an effect.
- Negative: approval cannot be presented as smart-wallet functionality or as a guarantee of chain success.
See getOperation, Policies, Transactions, Users, and Organizations.