External signing lets the holder of a custody account sign a write on an EVM network with a key the platform never holds, and still have the platform record that write in its transaction lifecycle. It works through a transaction preparation, a record that binds one write, its signer and its network for ten minutes. A retry of the same prepare or finalise call records one write, and a new preparation is a new write.
The preparation covers custody accounts linked through Privy, Dynamic or a browser wallet, the three providers that leave signing to the holder. The key sits with the holder's wallet or wallet provider. The alternative is the regular API route, where the platform asks a managed custody provider to sign for the account.
Keeping keys in your own HSM or custody system
Choose one of two setups.
- Connect it as a managed custody provider. The platform connects to IBM Digital Asset Haven, DFNS, Fireblocks, Luna HSM, Ripple custody and Utila as managed providers, and its own platform key store is managed too. The key stays in the HSM or the provider's system, the provider's policy or quorum decides whether to sign, and the platform asks for each signature. This is managed signing, and the preparation routes on this page refuse these accounts. The custody provider page describes the providers, and the custody approval page describes how their policy holds a signature.
- Hold the key as a self-custody account and sign through preparations. The account's EVM address is linked to a self-custody provider configuration. You sign each prepared write yourself, and the platform checks the result against the preparation. An HSM the platform has no managed connector for can take this route when a wallet that speaks EIP-1193 fronts its EVM key and is linked as a browser wallet. That wallet signs the challenge that links the address, then signs each prepared write.
On the second route the platform never receives the signed transaction bytes. For a plain transaction, your wallet or service sends the transaction to the network and then reports the sender, the nonce, which is the sending address's sequence number, and the transaction hash. The platform checks what you report against the frozen write and follows the nonce on the network. It does not check which device produced the signature, so the evidence that a key sits in an HSM comes from your own key management.
Linking the address starts with POST /api/, which returns a challenge for one enabled self-custody provider configuration and one EVM address. Choose investor custody walks through the linking calls.
Signing setups the preparation accepts
The preparation records its signing method in signingMethod. Two values are possible on these routes, and the user-operation method has two ways to reach the network.
A smart wallet is a contract account that acts through user operations, signed instructions an EntryPoint contract validates and executes. User operations covers the bundler that sends them.
The platform picks the method when you prepare. You ask for executionMode prefer-aa, which uses the smart wallet, through account abstraction, when it can, or direct. With prefer-aa the preparation is an owner-signed user operation, and the smart wallet is the executor, when two conditions hold: the provider supports account abstraction, and the participant has a smart wallet on that network whose owner is the custody account's address. In every other case, and with direct, the preparation is a browser wallet transaction from the custody account's own address. The user-operation path needs a smart wallet with a single owner key. A smart wallet that uses weighted signers is refused with a binding conflict.
The preparation routes refuse managed signing. A custody account whose provider holds the key gets DALP-14032 on the prepare call, and a finalise call that carries a managed authorisation gets DALP-14033. For that account, send the write through its regular API route.
Who can prepare and sign
The three preparation routes accept a signed-in session or an API key, and they require no organisation role. The custody account decides eligibility. It must be active, belong to the participant the request acts as, and hold an eligible organisation context on an enabled EVM network. Its provider configuration must serve that network, and its executor wallet must not be archived. A request that fails any of these gets DALP-14032.
A preparation belongs to the user and organisation that created it. Any other user or organisation that reads or advances it gets DALP-14031, the same answer as for a preparation that does not exist.
What a preparation binds
The prepare call fixes these facts and stores a digest over them: the calling user, the participant, the organisation, the custody account, its provider configuration, the network, the executor and the source address, the operation's kind and its digest, the summary, the signing method and the expiry. Each later claim, attachment and finalise call is checked against the stored facts it touches.
Send an Idempotency-Key header on the prepare call. The key belongs to the calling user. A repeat with the same key and the same binding returns the stored preparation. The same key with a different binding is refused with DALP-14033. Without the header, each call creates a new preparation.
The preparation expires ten minutes after it is created. A preparation that nobody has claimed cannot be claimed or finalised after that time.
Steps from prepare to transaction request
Prepare the write
Call
POST /api/withv2/ transaction- preparations custodyAccountId,executionMode, asummaryand theoperation: itskind,contractAddress,callDataand an optionalvalue. The response is the preparation in stateprepared. It names thesigningMethod, theexecutor, theexpiresAttime and, for a user operation,preparedUserOperationwith theuserOperationHashand thepreviewDataof the operation.For a user operation the platform builds a preview before you sign. When the organisation's gas payer on that network is Paymaster-paid, the preview carries the paymaster's sponsorship, so the smart wallet pays no gas. Otherwise a smart wallet that cannot cover the gas and the native currency the operation sends gets
DALP-14034, withsmartWalletAddress,heldWeiand the missingshortfallWei. A smart wallet can hold one open owner-signed operation per network. A second one is refused withDALP-14033until the first finishes or expires.Read the preparation
GET /api/returns the bound write and its progress: the signing method, the expiry, the submission claim, the attached handle or artifact and, once finalised,v2/ transaction- preparations/ {preparation Id} transactionRequestId.Claim the submission before anything is sent
Call
POST /api/withv2/ transaction- preparations/ {preparation Id}/ transitions actionset toclaim. A claim reserves one submission attempt. Repeating a claim with the sameclaimKeysucceeds, so choose a key you can regenerate.- Browser wallet transaction. The claim has
submissionKindeip-1193, aclaimKey, and thesender,chainId,nonce,to,valueanddatayou are about to send. They must match the prepared sender, network, destination, value and call data. The claim reserves that sender, network and nonce against every other preparation. The body also requires astartBlock, but the platform ignores its value and records the network's current block as the start of its search for the transaction. - Provider-submitted user operation. The claim has
submissionKindprovider-handleand aclaimKey. It applies only to a user-operation preparation, and the key cannot belong to another preparation under the same provider configuration. - Owner-signed user operation sent by the platform. Make no claim. Go to finalise.
- Browser wallet transaction. The claim has
Sign the write, and send it from your wallet
For a browser wallet transaction, the wallet signs and sends the claimed transaction. Once it is sent, the nonce is used and the claim can no longer be abandoned.
For a user operation, sign the
userOperationHashthe preparation returned. The platform recovers the signer from that hash with no prefix added. A personal-message signature adds a prefix, so it does not recover to the account. A typed-data signature works when its hash equalsuserOperationHash.On the provider path, record the provider's handle with
actionattachand anattachmentofclaimKeyandproviderHandle. The handle must name the active claim. A repeat of the same handle succeeds, and a different handle is refused withDALP-14240.Finalise
Finalising cannot be undone: a consumed preparation stays linked to its transaction request. It links the preparation to a request and does not prove the chain executed the call, so follow the request to a terminal status.
Call the transitions route with
actionfinalizeand anartifactwhosekindmatches the prepared signing method. The artifact also carries a_tag:Eip1193for a browser wallet transaction andTransaction Authorization Eip4337for a user operation.User Operation Authorization - Browser wallet transaction. The artifact carries
sender,chainId,nonceandtransactionHash, which isnullwhen the wallet returned no hash. It must match the persisted claim. - Owner-signed user operation. The artifact carries
userOperationHashandsignature. The platform checks that the hash is the prepared one, recomputes it from the operation's own fields, requires a canonical signature and verifies that it recovers to the custody account's address. The request enters the queue and the platform starts execution. - Provider-submitted user operation. The same artifact, finalised against the claim that holds the handle. The platform checks the hash against the prepared one. It does not recompute the hash or verify the signature on this path, because the provider submitted the operation. The EntryPoint verifies the signature when it executes the operation, so a bad signature fails on chain.
The response is the preparation in state
consumed, withtransactionRequestId. A repeat with the same artifact returns the same request, and a different artifact is refused withDALP-14033.- Browser wallet transaction. The artifact carries
Follow the transaction request
Read
GET /api/, or itsv2/ transaction- requests/ {transaction Id} /stream, untilstatusisCOMPLETED,FAILED,DEAD_LETTERorCANCELLED. Keep reading aDEAD_LETTERrequest, one the platform stopped retrying, while itsmayStillLandistrue, because its call can still land. A write that your wallet already sent enters asBROADCASTING, and confirmation tracking follows a request that carries a transaction hash. An owner-signed user operation enters asQUEUEDand runs the platform's execution from there.
To release a provider claim that has no handle, call the transitions route with action abandon. The preparation returns to prepared. Claim again with a new key, because the preparation refuses every key it has abandoned. A browser wallet claim cannot be abandoned, because its nonce may already have reached the network. A claim that holds a provider handle cannot be abandoned either.
Preparation states
Your calls move a preparation through prepared, submission-claimed and consumed, and time or reconciliation moves it to expired or consumed.
A preparation has four states, and the read returns the current one in state.
prepared: the write is bound and nothing is claimed. A claim moves it tosubmission-claimed. Finalising an owner-signed user operation moves it straight toconsumed, and the platform submits the operation.submission-claimed: one submission attempt is reserved. Finalise moves it toconsumed. An abandon moves a provider claim without a handle back toprepared.consumed: the preparation is permanently linked to its transaction request.expired: the write can no longer be claimed or finalised, and no transaction request exists for it. Prepare the write again.
An unclaimed preparation expires ten minutes after it is created. A claim or finalise call after that time is refused with DALP-12012. The platform records the expired state when it refuses a claim or a finalise. Until then, the read can still show prepared with an expiresAt time in the past.
A claimed provider submission does not expire on its own. Finalise it, or abandon it while it has no handle.
When a browser wallet claim outlives its preparation
A browser wallet claim whose ten minutes have passed is checked by the platform's background reconciliation, which reads the sender's nonce on the network.
- When the pending nonce equals the reserved nonce and the confirmed nonce has not passed it, nothing was sent. The preparation expires and the claim key is retired.
- When the pending nonce has moved past the reservation but the confirmed nonce has not, the wallet sent something that the network has not mined. The platform consumes the preparation and records a
BROADCASTINGrequest with the claimed sender, network, nonce and start block, and no transaction hash. It starts no new execution. - When the confirmed nonce has moved past the reservation, the platform looks for the transaction that used the nonce in a finalised block. When that transaction has the claimed destination, value and call data, the platform consumes the preparation and records a
BROADCASTINGrequest with that transaction hash, so confirmation tracking follows it. When it finds no such transaction, or the transaction carries another call, it leaves the preparation as it is. - A nonce slot that is blocked, or that the network does not answer for, leaves the preparation as it is.
A request recorded without a transaction hash shows only that the wallet sent some transaction at that nonce. It does not prove that the intended call succeeded, and confirmation tracking skips a request without a transaction hash. Check the network for the wallet's transaction at that nonce before you send anything again.
Writes that need more than one step
Some Console and Investor portal flows need several writes in order, such as an approval followed by a purchase. The public prepare route prepares one operation. A platform flow prepares the sequence itself. For a smart wallet it prepares one user operation that carries the extra calls, with the final write last. For a plain wallet it prepares one linked preparation per step, and the read names the earlier step a preparation waits on.
A linked step can be claimed only after the earlier step's transaction request is COMPLETED. Until then, its claim is refused as pending, even when the earlier step is only claimed. When the earlier request failed, was cancelled, or was dead-lettered with mayStillLand reading false, the claim is refused as failed and the whole sequence must be prepared again. While a dead-lettered earlier request may still land, the claim stays refused as pending. A step whose own time ran out, or whose earlier step expired, is refused as expired.
Refusals and what the caller does
When the preview of an owner-signed write reverts, the call answers 422 with the contract's own error, such as DALP-1009 for a compliance refusal, or DALP-0447 with revertData when the catalogue does not know the revert. No preparation is stored. A token write that a browser smart wallet signs answers the same way, with the contract's error instead of a generic queue refusal. A preview that the platform refuses without revert bytes stays a binding conflict, DALP-14033.
The Platform API error reference lists each code with its full text.
In the Console and the Investor portal
The Console's token transfer sheet and the Investor portal use the browser wallet path for a custody account linked to a browser wallet. Both need writable browser storage and the browser's lock API. They store each submission attempt, so a reload resumes a matching recorded attempt and does not send it again. When a submission stops, the Console names the reason with messages such as these:
- “The transaction expired before the wallet sent it, so the platform can no longer record it. Start the transaction again.”
- “Another session holds the wallet submission for this transaction. Finish it there.”
- “Another transaction from this wallet holds its next nonce until it is sent or expires. Finish that transaction, or start this one again in ten minutes.”
- “The wallet may have sent the transaction, but the platform could not record it. Check the wallet's activity before sending anything again.”
Terms that sound similar
Three other pages use a similar term for something different.
- The custody approval page describes an external custody provider or HSM whose policy decides whether to release a signature the platform asked for. That is managed signing, which these routes refuse.
- Multisig describes an external seat: a signer address on a weighted smart wallet with no platform identity behind it. A weighted smart wallet cannot use the owner-signed path on this page.
- Single sign-on describes external sign-in to the Console through an OpenID Connect identity provider. It decides who signs in, and it signs no transaction.
Related pages
Read custody provider for the managed and self-custody providers, smart wallet for the account an owner-signed operation spends from, Embed a Privy wallet for a worked user-operation example, and Transaction lifecycle for the path a request follows once it is recorded.