Skip to content

Commit 05a681b

Browse files
authored
feat: add withdrawal to external wallets (#1042)
1 parent 418f949 commit 05a681b

5 files changed

Lines changed: 128 additions & 6 deletions

File tree

src/bee.ts

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ import { fileArrayBuffer, isFile } from './utils/file'
9999
import { ResourceLocator } from './utils/resource-locator'
100100
import { Size } from './utils/size'
101101
import { getAmountForDuration, getDepthForSize, getStampCost } from './utils/stamps'
102-
import { BZZ } from './utils/tokens'
102+
import { BZZ, DAI } from './utils/tokens'
103103
import {
104104
asNumberString,
105105
assertData,
@@ -1437,16 +1437,32 @@ export class Bee {
14371437
}
14381438

14391439
/**
1440-
* Deposit tokens from overlay address into chequebook
1440+
* Deposit tokens from node wallet into chequebook
14411441
*
14421442
* @param amount Amount of tokens to deposit (must be positive integer)
14431443
* @param gasPrice Gas Price in WEI for the transaction call
14441444
* @return string Hash of the transaction
1445+
* @deprecated Use `depositBZZToChequebook` instead.
14451446
*/
14461447
async depositTokens(
14471448
amount: BZZ | NumberString | string | bigint,
14481449
gasPrice?: NumberString | string | bigint,
14491450
options?: BeeRequestOptions,
1451+
): Promise<TransactionId> {
1452+
return this.depositBZZToChequebook(amount, gasPrice, options)
1453+
}
1454+
1455+
/**
1456+
* Deposit tokens from node wallet into chequebook
1457+
*
1458+
* @param amount Amount of tokens to deposit (must be positive integer)
1459+
* @param gasPrice Gas Price in WEI for the transaction call
1460+
* @return string Hash of the transaction
1461+
*/
1462+
async depositBZZToChequebook(
1463+
amount: BZZ | NumberString | string | bigint,
1464+
gasPrice?: NumberString | string | bigint,
1465+
options?: BeeRequestOptions,
14501466
): Promise<TransactionId> {
14511467
const amountString =
14521468
amount instanceof BZZ ? amount.toPLURString() : asNumberString(amount, { min: 1n, name: 'amount' })
@@ -1461,16 +1477,32 @@ export class Bee {
14611477
}
14621478

14631479
/**
1464-
* Withdraw tokens from the chequebook to the overlay address
1480+
* Withdraw tokens from the chequebook to the node wallet
14651481
*
14661482
* @param amount Amount of tokens to withdraw (must be positive integer)
14671483
* @param gasPrice Gas Price in WEI for the transaction call
14681484
* @return string Hash of the transaction
1485+
* @deprecated Use `withdrawBZZFromChequebook` instead.
14691486
*/
14701487
async withdrawTokens(
14711488
amount: BZZ | NumberString | string | bigint,
14721489
gasPrice?: NumberString | string | bigint,
14731490
options?: BeeRequestOptions,
1491+
): Promise<TransactionId> {
1492+
return this.withdrawBZZFromChequebook(amount, gasPrice, options)
1493+
}
1494+
1495+
/**
1496+
* Withdraw tokens from the chequebook to the node wallet
1497+
*
1498+
* @param amount Amount of tokens to withdraw (must be positive integer)
1499+
* @param gasPrice Gas Price in WEI for the transaction call
1500+
* @return string Hash of the transaction
1501+
*/
1502+
async withdrawBZZFromChequebook(
1503+
amount: BZZ | NumberString | string | bigint,
1504+
gasPrice?: NumberString | string | bigint,
1505+
options?: BeeRequestOptions,
14741506
): Promise<TransactionId> {
14751507
// TODO: check BZZ in tests
14761508
const amountString =
@@ -1485,6 +1517,28 @@ export class Bee {
14851517
return chequebook.withdrawTokens(this.getRequestOptionsForCall(options), amountString, gasPriceString)
14861518
}
14871519

1520+
async withdrawBZZToExternalWallet(
1521+
amount: BZZ | NumberString | string | bigint,
1522+
address: EthAddress | Uint8Array | string,
1523+
options?: BeeRequestOptions,
1524+
): Promise<TransactionId> {
1525+
amount = amount instanceof BZZ ? amount : BZZ.fromPLUR(amount)
1526+
address = new EthAddress(address)
1527+
1528+
return states.withdrawBZZ(this.getRequestOptionsForCall(options), amount, address)
1529+
}
1530+
1531+
async withdrawDAIToExternalWallet(
1532+
amount: DAI | NumberString | string | bigint,
1533+
address: EthAddress | Uint8Array | string,
1534+
options?: BeeRequestOptions,
1535+
): Promise<TransactionId> {
1536+
amount = amount instanceof DAI ? amount : DAI.fromWei(amount)
1537+
address = new EthAddress(address)
1538+
1539+
return states.withdrawDAI(this.getRequestOptionsForCall(options), amount, address)
1540+
}
1541+
14881542
/*
14891543
* Settlements endpoint
14901544
*/
@@ -1581,7 +1635,7 @@ export class Bee {
15811635
}
15821636

15831637
/**
1584-
* Get wallet balances for xDai and BZZ of the Bee node
1638+
* Get wallet balances for DAI and BZZ of the Bee node
15851639
*
15861640
* @param options
15871641
*/

src/modules/debug/states.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { BeeRequestOptions, ChainState, ReserveState, WalletBalance } from '../.
33
import { http } from '../../utils/http'
44
import { BZZ, DAI } from '../../utils/tokens'
55
import { asNumberString } from '../../utils/type'
6+
import { EthAddress, TransactionId } from '../../utils/typed-bytes'
67
import { normalizeCurrentPrice } from '../../utils/workaround'
78

89
const RESERVE_STATE_ENDPOINT = 'reservestate'
@@ -74,3 +75,37 @@ export async function getWalletBalance(requestOptions: BeeRequestOptions): Promi
7475
walletAddress: Types.asString(body.walletAddress, { name: 'walletAddress' }),
7576
}
7677
}
78+
79+
export async function withdrawBZZ(
80+
requestOptions: BeeRequestOptions,
81+
amount: BZZ,
82+
address: EthAddress,
83+
): Promise<TransactionId> {
84+
const response = await http<unknown>(requestOptions, {
85+
method: 'post',
86+
url: `${WALLET_ENDPOINT}/withdraw/bzz`,
87+
responseType: 'json',
88+
params: { amount: amount.toPLURString(), address: address.toHex() },
89+
})
90+
91+
const body = Types.asObject(response.data, { name: 'response.data' })
92+
93+
return new TransactionId(Types.asString(body.transactionHash, { name: 'transactionHash' }))
94+
}
95+
96+
export async function withdrawDAI(
97+
requestOptions: BeeRequestOptions,
98+
amount: DAI,
99+
address: EthAddress,
100+
): Promise<TransactionId> {
101+
const response = await http<unknown>(requestOptions, {
102+
method: 'post',
103+
url: `${WALLET_ENDPOINT}/withdraw/nativetoken`,
104+
responseType: 'json',
105+
params: { amount: amount.toWeiString(), address: address.toHex() },
106+
})
107+
108+
const body = Types.asObject(response.data, { name: 'response.data' })
109+
110+
return new TransactionId(Types.asString(body.transactionHash, { name: 'transactionHash' }))
111+
}

test/integration/status.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ test('GET wallet', async () => {
6969
}
7070

7171
const wallet = await bee.getWalletBalance()
72-
expect(parseFloat(wallet.bzzBalance.toDecimalString())).toBeGreaterThan(50)
72+
expect(parseFloat(wallet.bzzBalance.toDecimalString())).toBeGreaterThan(20)
7373
expect(parseFloat(wallet.bzzBalance.toDecimalString())).toBeLessThan(200)
7474
expect(parseFloat(wallet.nativeTokenBalance.toDecimalString())).toBeGreaterThan(4)
7575
expect(parseFloat(wallet.nativeTokenBalance.toDecimalString())).toBeLessThan(5)

test/integration/withdraw.spec.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Dates, System } from 'cafe-utility'
2+
import { makeBee } from '../utils'
3+
4+
const bee = makeBee()
5+
6+
test('withdraw to external wallet', async () => {
7+
const walletBefore = await bee.getWalletBalance()
8+
9+
await bee.withdrawBZZToExternalWallet('1', process.env.JEST_WITHDRAW_ADDRESS!)
10+
await System.waitFor(
11+
async () => {
12+
const pendingTransactions = await bee.getAllPendingTransactions()
13+
return pendingTransactions.length === 0
14+
},
15+
Dates.seconds(1),
16+
60,
17+
)
18+
19+
await bee.withdrawDAIToExternalWallet('1', process.env.JEST_WITHDRAW_ADDRESS!)
20+
await System.waitFor(
21+
async () => {
22+
const pendingTransactions = await bee.getAllPendingTransactions()
23+
return pendingTransactions.length === 0
24+
},
25+
Dates.seconds(1),
26+
60,
27+
)
28+
29+
const walletAfter = await bee.getWalletBalance()
30+
31+
expect(walletAfter.bzzBalance.toPLURBigInt()).toBeLessThan(walletBefore.bzzBalance.toPLURBigInt())
32+
expect(walletAfter.nativeTokenBalance.toWeiBigInt()).toBeLessThan(walletBefore.nativeTokenBalance.toWeiBigInt())
33+
})

test/regression/bee-js-986.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ test('bee-js/986 - Headers not merging properly', async () => {
3232
host: 'localhost:11633',
3333
'swarm-act': 'true',
3434
'swarm-encrypt': 'true',
35-
'swarm-postage-batch-id': 'f8b2ad296d64824a8fe51a33ff15fe8668df13a20ad3d4eea4bb97ca600029aa',
35+
'swarm-postage-batch-id': 'b961413232c96eedae48947a71c99e454e51c4b5bf93a77c59f958af1229a932',
3636
'swarm-tag': '1337',
3737
'user-agent': 'axios/0.30.0',
3838
},

0 commit comments

Comments
 (0)