Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 12 additions & 43 deletions modules/express/src/typedRoutes/api/v2/walletSweep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { SendManyResponse } from './sendmany';
* Request path parameters for sweeping a wallet
*/
export const WalletSweepParams = {
/** The coin type */
/** A cryptocurrency or token ticker symbol */
coin: t.string,
/** The wallet ID */
id: t.string,
Expand All @@ -21,70 +21,39 @@ export const WalletSweepParams = {
* For account-based coins, it calculates the maximum spendable amount and uses sendMany.
*/
export const WalletSweepBody = {
/** The destination address to send all funds to - REQUIRED */
/** The destination address for the sweep transaction */
address: t.string,

/** The wallet passphrase to decrypt the user key */
/** Passphrase to decrypt the user key on the wallet */
walletPassphrase: optional(t.string),

/** The extended private key (alternative to walletPassphrase) */
/** Private key in string form, if walletPassphrase is not available */
xprv: optional(t.string),

/** One-time password for 2FA */
/** Two factor auth code to enable sending the transaction */
otp: optional(t.string),

/** The desired fee rate for the transaction in satoshis/kB (UTXO coins) */
/** Custom fee rate (in base units) per kilobyte (or virtual kilobyte). For example, satoshis per kvByte */
feeRate: optional(t.number),

/** Upper limit for fee rate in satoshis/kB (UTXO coins) */
/** (BTC only) The maximum fee rate (in base units) per kilobyte (or virtual kilobyte). For example, satoshis per kvByte. The `maxFeeRate` limits the fee rate generated by both `feeMultiplier` and `numBlocks` */
maxFeeRate: optional(t.number),

/** Estimate fees to aim for confirmation within this number of blocks (UTXO coins) */
/** Number of blocks to wait to confirm the transaction */
feeTxConfirmTarget: optional(t.number),

/** Allows sweeping 200 unspents when wallet has more than that (UTXO coins) */
/** Use `allowPartialSweep: true` to sweep part of a wallet when there are too many unspents to empty the wallet in a single transaction. While the expected outcome of a single sweep call would usually be an empty wallet, using the allowPartialSweep option may leave some funds in the wallet. Making repeated calls with the allowPartialSweep option allows emptying wallets with many unspents without consolidating first */
allowPartialSweep: optional(t.boolean),

/** Transaction format: 'legacy', 'psbt', or 'psbt-lite' (UTXO coins) */
/** [UTXO only] Format of the returned transaction hex serialization. `legacy` for serialized transaction in custom bitcoinjs-lib format. `psbt` for BIP174 serialized transaction */
txFormat: optional(t.union([t.literal('legacy'), t.literal('psbt'), t.literal('psbt-lite')])),
} as const;

/**
* Sweep all funds from a wallet to a specified address
* The sweep call spends the full balance of the wallet to the provided address. On UTXO coins, the sweep call will fail if the wallet has any unconfirmed funds, or if there are more unspents than can be sent with a single transaction.
*
* This endpoint sweeps (sends) all available funds from a wallet to a single destination address.
*
* **Behavior by coin type:**
* - **UTXO coins (BTC, LTC, etc.)**: Uses the native /sweepWallet endpoint that:
* - Collects all unspents in the wallet
* - Builds a transaction sending everything (minus fees) to the destination
* - Signs and broadcasts the transaction
* - Validates that all funds go to the specified destination address
*
* - **Account-based coins (ETH, etc.)**:
* - Checks for unconfirmed funds (fails if any exist)
* - Queries the maximumSpendable amount
* - Creates a sendMany transaction with that amount to the destination
*
* **Implementation Note:**
* Both execution paths (UTXO and account-based) ultimately call the same underlying
* transaction sending mechanisms as sendMany, resulting in identical response structures.
*
* **Authentication:**
* - Requires either `walletPassphrase` (to decrypt the encrypted user key) or `xprv` (raw private key)
* - Optional `otp` for 2FA
*
* **Fee control (UTXO coins):**
* - `feeRate`: Desired fee rate in satoshis/kB
* - `maxFeeRate`: Upper limit for fee rate
* - `feeTxConfirmTarget`: Target number of blocks for confirmation
*
* **Special options:**
* - `allowPartialSweep`: For UTXO wallets with >200 unspents, allows sweeping just 200
* - `txFormat`: Choose between 'legacy', 'psbt', or 'psbt-lite' format
*
* @tag express
* @operationId express.v2.wallet.sweep
* @tag Express
*/
export const PostWalletSweep = httpRoute({
path: '/api/v2/{coin}/wallet/{id}/sweep',
Expand Down
Loading