GuardSigner is a Polyester-managed secondary signer that provides an additional authorization for specific on-chain Funding Account actions. Polyester releases its approval only after the authorization checks described on this page. GuardSigner does not protect every account or wallet action, and it is not an independently user-held factor.
Protection applies only when both conditions are true:
- GuardSigner is initialized for the selected account, meaning the signer stored by Polyester matches the signer registered on-chain.
- The contract action requires a GuardSigner approval.
For those actions, the selected account's smart account authorizes and submits the contract call, while GuardSigner authorizes the exact protected action. Both authorizations are required for the call to succeed.
Protected actions
The current approval API supports these Funding Account actions:
PROTECTED_ACTION_FUNDING_ADD_EXTERNAL_WHITELIST· Add external whitelist destinations
Adds destinations for an external Network.PROTECTED_ACTION_FUNDING_REMOVE_EXTERNAL_WHITELIST· Remove external whitelist destinations
Removes destinations for an external Network.PROTECTED_ACTION_FUNDING_ADD_INTERNAL_WHITELIST· Add internal whitelist accounts
Adds Polyester account addresses.PROTECTED_ACTION_FUNDING_REMOVE_INTERNAL_WHITELIST· Remove internal whitelist accounts
Removes Polyester account addresses.PROTECTED_ACTION_FUNDING_SET_EXTERNAL_WHITELIST_REQUIRED· Disable external whitelist requirement
Setsrequiredtofalse.PROTECTED_ACTION_FUNDING_SET_INTERNAL_WHITELIST_REQUIRED· Disable internal whitelist requirement
Setsrequiredtofalse.
Enabling either whitelist requirement does not use a GuardSigner approval. Disabling a requirement does.
Authentication and authorization
GuardSigner methods do not run a generic account-policy evaluation. They use authenticated account identity, optional Subaccount selection, Subaccount role checks where applicable, and method-specific MFA checks.
Each workflow lists the accepted caller, then what it needs for a Main Account target and for a Subaccount target.
- Create a signer wallet · JWT only
Main Account: the authenticated caller. Subaccount: the owner role. - Read signer status · authenticated JWT or API key
Main Account: the authenticated caller. Subaccount: any granted role. - Request one or more approvals · JWT only
Main Account: the authenticated caller and a fresh step-up. Subaccount: the owner role and a fresh step-up. - Rotate the managed signer · JWT only
Main Account: active MFA and a fresh step-up. Subaccount: the owner role, active Main Account MFA, and a fresh step-up. - Export the signer private key · JWT only
Main Account: active MFA and a fresh step-up. Subaccount: the owner role, active Main Account MFA, and a fresh step-up.
Wallet creation, approval signing, rotation, and export are interactive owner workflows. API-key callers are rejected for these methods with HTTP 403 and AUTH_SESSION_KIND_NOT_ALLOWED. Reading the signer status is the only GuardSigner method that accepts an API key.
When subaccountId is omitted, JWT and Main Account API-key callers target the Main Account. A
Subaccount-scoped API key, which can only read status, instead targets its bound Subaccount. To select another permitted
Subaccount explicitly, provide its public subaccountId; Polyester verifies access, the required
role, and any API-key scope binding.
Fresh step-up behavior
Send the fresh step-up JWT in the X-Auth-Step-Up header. The approval API validates:
- the token signature and expiry
- fresh-step-up token use
- the presence of a step-up identifier
- binding to the authenticated account
- binding to the current session when the session has an identifier
The API claims and consumes the server-backed proof before it decrypts managed key material, creates a signature, stores a pending rotation, or returns an exported private key. If claim or consumption cannot be confirmed, the protected operation fails without returning protected output.
Single approvals bind the proof to the selected account and exact prepared action. Batch approvals also bind the ordered action list, so changing an action, target, selector, arguments, or batch order requires another proof. Rotation and export use separate bindings and cannot reuse a proof claimed for approval signing.
All currently supported protected actions require fresh step-up. A batch requires step-up if any item is a protected high-risk action, which is currently every supported batch item. A successfully consumed proof is single-use and reuse is rejected.
See Multi-factor authentication for how interactive clients obtain fresh step-up proof.
Setup and status
- Create a GuardSigner wallet for the Main Account or selected Subaccount with
CreateGuardSignerWallet. - Read
status.signerAddressfromGetGuardSignerStatus. - Submit the on-chain signer initialization call through the selected account's smart account with that address.
- Wait for confirmation, then read status until
initializedistrue.
GetGuardSignerStatus returns a status object; the API reference
lists its fields. Compare signerAddress, the signer Polyester stores, with onchainSignerAddress, the signer registered for the account on-chain. initialized is true only
when the two match. nonce is a decimal string for the default nonce space, and nonceSpace is
currently 0.
If the on-chain signer is missing or differs from the stored signer, approval requests fail. A missing signer is reported as not found. A mismatch is reported as a failed precondition.
This distinction is important during setup and rotation. A stored wallet can exist while the on-chain account still has no signer, or while it still points to a previous signer.
Requesting an approval
- Build the protected business action and its arguments.
- Authenticate with the owner's JWT session.
- Complete fresh MFA step-up and send the proof in
X-Auth-Step-Up. - Request the GuardSigner approval with
SignProtectedAction, orBatchSignProtectedActionsfor several actions. - Submit the matching contract call with the returned approval through the selected account's smart account.
- Wait for the on-chain transaction result.
Clients send:
- the protected action identifier
- the action-specific business arguments
- an optional public
subaccountId
Polyester derives the account address, target contract, function selector, parameter hash, current nonce, nonce space, chain context, and deadline. Clients do not provide these as trusted approval inputs.
The approval is bound to the selected account, contract action, encoded arguments, nonce, and deadline. Changing the destination list, destination order, action, or encoded arguments makes the approval invalid for that call.
Action arguments
| Whitelist type | Argument shape |
|---|---|
| External whitelist | polychainChainId from 1 to 65,535 and 1 to 100 unique destination payloads |
| Internal whitelist | 1 to 100 unique, nonzero EVM account addresses |
| Requirement change | required: false |
External destinations are non-empty 0x-prefixed byte payloads for the selected external Network.
For EVM destinations, lowercase the complete 0x... address string, UTF-8 encode it, and then hex
encode those bytes. For example, the string prefix 0xab begins 0x30786162 after encoding. Do not
send the raw 20-byte EVM address.
Internal whitelist values are ordinary 0x-prefixed EVM account addresses. Duplicate values and the
zero address are rejected.
Approval payload and batching
A single-action response contains { "approval": { ... } }. A batch response contains { "approvals": [{ ... }] } and preserves request order. In Connect and protobuf JSON, an
approval's nonceSpace is the decimal string "0", deadlineUnix is a decimal Unix-seconds
string derived from chain time, and signature is the 65-byte EIP-712 signature in standard padded
Base64.
A batch can contain 1 to 20 actions. The response preserves request order, and nonces increase in that order from the current on-chain nonce. Submit each approval with its corresponding action in the same batched transaction.
Issuing an approval does not reserve its nonce. Another transaction can consume that nonce first, which invalidates the approval or the remaining approvals in a batch.
Do not reuse an approval after its nonce has been consumed or its deadline has passed.
Rotating the signer
Rotation is an interactive owner-only JWT flow. The account must have an active MFA factor, and the request must include valid fresh step-up proof.
- Request signer rotation with
RotateGuardSignerWallet. - Receive the replacement signer address and rotation approval.
- Submit the on-chain rotation call with that approval.
- Wait for confirmation.
- Poll status until
signerAddressandonchainSignerAddressmatch andinitializedistrue.
The replacement remains pending until the on-chain rotation is confirmed. Repeating the rotation request while that rotation is pending returns the same replacement signer rather than generating a different pending key. Approval signing continues to require an exact match between the active stored signer and the on-chain signer.
Exporting the private key
Export is an interactive owner-only JWT flow. It requires an active MFA factor and valid fresh
step-up proof. Call ExportGuardSignerWallet; the response field privateKey contains a 0x-prefixed, 32-byte private key encoded
as 64 hexadecimal characters.
If you export:
- move the key directly into secure custody, such as a hardware security module or dedicated signing service
- never place it in source control, logs, chat, analytics, browser storage, or unencrypted backups
- restrict who and what can request signatures
- treat any suspected exposure as a signer compromise
Export does not automatically remove or replace the registered signer. To restore exclusive managed protection after export or suspected compromise, rotate to a newly managed signer, submit the rotation on-chain, and wait for status to show an exact match. For a new account with no signer registered on-chain, create and initialize a new managed signer instead.
While rotation is pending, export returns the currently active signer key. The replacement key becomes active only after the on-chain rotation is confirmed and status reflects the new signer.
See Withdrawals and Transfers Security for the broader transfer authorization model.