Skip to main content
An embedded wallet is a wallet we create and run for a signer key you register. You use it like any other payment account: you quote and order with its id. You never hold gas for it or set it up on the chain. When an order needs to move the wallet’s funds, the holder of the signer key approves it with a signature. We can never move the funds without that approval. It takes three steps:
  1. Register a signer key. We create the wallet.
  2. Quote and order with the wallet’s payment account id, as with any account.
  3. Approve when an order needs the key holder’s approval: sign the order’s authorization and send us the signature.
Every endpoint takes your API key in the Authorization header with no Bearer prefix. See Authentication.
In sandbox, embedded wallets are off by default. Ask your Etherfuse contact to turn them on for your organization. Until then, registering an embeddedWallet in sandbox, or reading its requirements, returns 403 forbidden.

Supported chains

Each chain has a few rules of its own. See Chain details.

1. Register the wallet

The key holder generates a P-256 key pair and keeps the private key. You register the public key with POST /organization/{organizationId}/payment_account, under the organization that owns the wallet. That is your own organization (its id comes from GET /me) or a customer’s. See Organizations in the route.
  • chain is one of the supported chains.
  • signerPublicKey is the P-256 public key in hex SEC1 form, compressed (33 bytes) or uncompressed (65 bytes).
  • Idempotency-Key makes a retry safe. Each registration creates a new wallet, so generate one key per wallet, such as a UUID, and reuse it when you retry. A retry with the same key and body returns the first wallet with 200. See Idempotency.
  • The account holder’s name is stored with the wallet. We fill it from the organization’s verified identity or business. If we have no verified name, the request fails with 422 registration-info-required. Send registrationInfo.accountHolderName and retry.
The response is 201 with the account pending. When the wallet exists, the account changes to ready and we send paymentAccountUpdated. Keep the account’s id to quote with. You decide who holds the key. You can hold it for your program, or your customer can hold it so only they can approve their orders. One key can control many wallets, such as one wallet per customer, because each registration creates a new wallet.
Whether holding the key makes you a custodian or money transmitter depends on your facts, activities and jurisdiction. This is not legal advice. Check your obligations with your legal and compliance advisors.

2. Quote and order

Quote and order the wallet like any other payment account. Pass its id as destination to buy into the wallet (onramp), or as source to sell or swap out of it (offramp or swap).
Then create the order with POST /organization/{organizationId}/order and the quoteId. Onramps, Offramps and Swaps cover the rest of each direction.

3. Approve the authorization

When an order needs to move the wallet’s funds, the order’s authorization field holds the request for the key holder. We send orderUpdated when it appears.
Sign the UTF-8 bytes of method.message exactly as we return them, with ECDSA over P-256 and SHA-256. Hex-encode the signature, either as DER or as the 64-byte r||s that WebCrypto produces:
Submit the authorization’s id and the signature with POST /organization/{organizationId}/order/{id}/authorization. We return the order and move the funds. If you send an id we already accepted, we return 200 with the order.
An authorization expires at expiresAt. We can also replace it before then, for example when another transaction from the wallet lands first. A replacement has a new id and message, and we send orderUpdated. Sign the authorization you read most recently.

Claims

On some chains, a wallet can’t receive an asset until the wallet is set up for that asset. When an onramp pays a wallet that isn’t set up yet, we hold the payout for the wallet to claim, and the order changes to claimable. Chain details lists when this happens on each chain. To claim, call POST /organization/{organizationId}/order/{id}/claim with no body. It returns 202 with no body. A few seconds later the order’s authorization has reason claim, and we send orderUpdated. Sign and submit it as above. We set up the wallet and claim the payout in one transaction, and the order changes to completed.
A claim authorization lasts up to an hour and never past the claim deadline. We do not replace an expired claim authorization. Call /claim again to get a new one. Each call replaces a claim authorization that is still open, so sign the one you read most recently.

Fees and billing

An embedded wallet order has the same quote fees as any other order. When a new wallet needs setup on the chain to receive an asset, the onramp’s quote adds a walletSponsor line for that setup. We also charge two fees for each transaction we send for the wallet: We add these lines to the order’s fees when the transaction is final, and we send orderUpdated. We invoice them separately. We don’t take them from the order’s funds, and they are not part of destinationAmount or feeAmount. If a transaction never reaches the chain, the order gets a walletSigning line and no networkFee line.

Track the order

Subscribe to orderUpdated with POST /webhook_subscription. Each delivery has the full order, so you see each authorization, the change to claimable, the fee lines, and the change to completed. If you miss a delivery, read the order with GET /organization/{organizationId}/order/{id}.

Chain details

Stellar

  • Setup. A Stellar wallet needs an account and a trustline for each asset it holds. Both lock up some XLM as a reserve. An onramp to a wallet that doesn’t have them yet is quoted with a walletSponsor line, and its payout arrives as a claim.
  • Claims. The order’s claimInstructions stays null, because the claim is the order’s authorization with reason claim. The claim transaction adds the trustline, if the wallet doesn’t have it, and claims the balance.
  • Network fee. networkFee lines are in XLM (native). The wallet’s XLM only covers its reserves.
See the Stellar guide for assets and trustlines.