Two keys show up in a SohoPay payment, and they are not interchangeable. The borrower key authorizes the relationship. The agent key authorizes a single voucher. SohoPay’s hardware-backed attestation key signs settlement batches and is not a key you manage. See Settlement attestation.

Borrower EOA

The borrower signs three EIP-712 payloads in their own wallet:
  • Wallet proof, during onboarding.
  • AgentAuthorizationGrant, on the consent page, which sets the agent’s limits.
  • Repayment authorization, when they pay the facility down. See ERC-3009.
Stop and get explicit consent before asking the borrower to sign. Never ask them to paste a seed phrase, a private key, or a raw signature JSON into chat.

Agent workload key

Install @sohopay/agent-signer. Call generateWorkloadKey() once per terminal and persist the private key on the host. Register the public key with register_agent_workload_key using signPoP. On VOUCHER_ISSUED, call signVoucher with the unsigned voucher and the signing block from the prepare response, then buildPaymentSignatureHeader. The library checks the payment id and the key thumbprint before it signs. It rejects a JWK that contains private material.
The workload key can spend up to the active grant. Protect it like a payment credential. It cannot sign a wallet proof, a grant, or a repayment.

Rotation and revoke

rotate_agent_key needs the agent:key:register scope. revoke_agent needs agent:revoke and an EOA signature from the borrower. Revoke when a host is lost. A revoked agent cannot spend until the borrower authorizes a replacement.

What SohoPay does not do

SohoPay does not generate an agent wallet inside an MPC ceremony, and it does not co-sign the voucher. If a prepare response says signing is disabled or custodial signing is unavailable, stop. There is no fallback where SohoPay signs for the agent.

Next steps

Agent signer

The functions you call.

EIP-712

What the borrower signs.