Add sweepAll to Electrum wallet RPC client.

Consolidate payto, deserialize, and broadcast into a single sweep helper for max-payment withdrawals.
This commit is contained in:
2026-09-06 23:28:47 +02:00
parent 8d9054b119
commit 3a72d0521a
3 changed files with 162 additions and 24 deletions
@@ -17,6 +17,7 @@ describe('ElectrumWalletRpcClient', () => {
rpcUrl: 'http://electrum.test:7777',
username: 'electrum',
password: 'secret',
walletPassword: 'wallet-secret',
rpcTimeoutMs: 5000
})
} as unknown as ConfigService);
@@ -74,10 +75,10 @@ describe('ElectrumWalletRpcClient', () => {
});
});
describe('sumIncomingOutputValueAtomic', () => {
describe('sumOutputValueAtomic', () => {
it('sums outputs paying to the target address', () => {
expect(
clientTest.sumIncomingOutputValueAtomic(
clientTest.sumOutputValueAtomic(
{
outputs: [
{ address: 'bc1qother', value_sats: 10_000 },
@@ -92,7 +93,7 @@ describe('ElectrumWalletRpcClient', () => {
it('returns zero when no outputs match the address', () => {
expect(
clientTest.sumIncomingOutputValueAtomic(
clientTest.sumOutputValueAtomic(
{
outputs: [{ address: 'bc1qother', value_sats: 10_000 }]
},
@@ -208,4 +209,80 @@ describe('ElectrumWalletRpcClient', () => {
});
});
});
describe('sweepAll', () => {
it('creates, signs, and broadcasts a max-payment transaction', async () => {
mockedAxios.post
.mockResolvedValueOnce({
data: {
jsonrpc: '2.0',
id: 'nullcart',
result: 'signed-tx'
}
})
.mockResolvedValueOnce({
data: {
jsonrpc: '2.0',
id: 'nullcart',
result: {
outputs: [{ address: 'bc1qtest', value_sats: 140_000 }]
}
}
})
.mockResolvedValueOnce({
data: {
jsonrpc: '2.0',
id: 'nullcart',
result: 'tx-hash-1'
}
});
await expect(client.sweepAll('bc1qtest', 10)).resolves.toEqual({
txHash: 'tx-hash-1',
amountAtomic: '140000'
});
expect(mockedAxios.post).toHaveBeenNthCalledWith(
1,
'http://electrum.test:7777',
{
jsonrpc: '2.0',
id: 'nullcart',
method: 'payto',
params: {
destination: 'bc1qtest',
amount: '!',
feerate: '10',
password: 'wallet-secret'
}
},
expect.objectContaining({
timeout: 120_000
})
);
expect(mockedAxios.post).toHaveBeenNthCalledWith(
2,
'http://electrum.test:7777',
{
jsonrpc: '2.0',
id: 'nullcart',
method: 'deserialize',
params: { tx: 'signed-tx' }
},
expect.any(Object)
);
expect(mockedAxios.post).toHaveBeenNthCalledWith(
3,
'http://electrum.test:7777',
{
jsonrpc: '2.0',
id: 'nullcart',
method: 'broadcast',
params: { tx: 'signed-tx' }
},
expect.any(Object)
);
});
});
});