Skip to content

Commit e4732d8

Browse files
authored
Merge pull request #562 from opentensor/fix/thewhaleking/transfer-all
fix transfer all
2 parents 97961e6 + be18986 commit e4732d8

File tree

4 files changed

+46
-18
lines changed

4 files changed

+46
-18
lines changed

bittensor_cli/cli.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1892,6 +1892,12 @@ def wallet_transfer(
18921892
transfer_all: bool = typer.Option(
18931893
False, "--all", prompt=False, help="Transfer all available balance."
18941894
),
1895+
allow_death: bool = typer.Option(
1896+
False,
1897+
"--allow-death",
1898+
prompt=False,
1899+
help="Transfer balance even if the resulting balance falls below the existential deposit.",
1900+
),
18951901
period: int = Options.period,
18961902
wallet_name: str = Options.wallet_name,
18971903
wallet_path: str = Options.wallet_path,
@@ -1935,7 +1941,7 @@ def wallet_transfer(
19351941
subtensor = self.initialize_chain(network)
19361942
if transfer_all and amount:
19371943
print_error("Cannot specify an amount and '--all' flag.")
1938-
raise typer.Exit()
1944+
return False
19391945
elif transfer_all:
19401946
amount = 0
19411947
elif not amount:
@@ -1947,6 +1953,7 @@ def wallet_transfer(
19471953
destination=destination_ss58_address,
19481954
amount=amount,
19491955
transfer_all=transfer_all,
1956+
allow_death=allow_death,
19501957
era=period,
19511958
prompt=prompt,
19521959
json_output=json_output,

bittensor_cli/src/bittensor/extrinsics/transfer.py

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ async def transfer_extrinsic(
2626
amount: Balance,
2727
era: int = 3,
2828
transfer_all: bool = False,
29+
allow_death: bool = False,
2930
wait_for_inclusion: bool = True,
3031
wait_for_finalization: bool = False,
31-
keep_alive: bool = True,
3232
prompt: bool = False,
3333
) -> bool:
3434
"""Transfers funds from this wallet to the destination public key address.
@@ -39,11 +39,11 @@ async def transfer_extrinsic(
3939
:param amount: Amount to stake as Bittensor balance.
4040
:param era: Length (in blocks) for which the transaction should be valid.
4141
:param transfer_all: Whether to transfer all funds from this wallet to the destination address.
42+
:param allow_death: Whether to allow for falling below the existential deposit when performing this transfer.
4243
:param wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning `True`,
4344
or returns `False` if the extrinsic fails to enter the block within the timeout.
4445
:param wait_for_finalization: If set, waits for the extrinsic to be finalized on the chain before returning
4546
`True`, or returns `False` if the extrinsic fails to be finalized within the timeout.
46-
:param keep_alive: If set, keeps the account alive by keeping the balance above the existential deposit.
4747
:param prompt: If `True`, the call waits for confirmation from the user before proceeding.
4848
:return: success: Flag is `True` if extrinsic was finalized or included in the block. If we did not wait for
4949
finalization / inclusion, the response is `True`, regardless of its inclusion.
@@ -57,8 +57,8 @@ async def get_transfer_fee() -> Balance:
5757
"""
5858
call = await subtensor.substrate.compose_call(
5959
call_module="Balances",
60-
call_function="transfer_keep_alive",
61-
call_params={"dest": destination, "value": amount.rao},
60+
call_function=call_function,
61+
call_params=call_params,
6262
)
6363

6464
try:
@@ -82,8 +82,8 @@ async def do_transfer() -> tuple[bool, str, str]:
8282
"""
8383
call = await subtensor.substrate.compose_call(
8484
call_module="Balances",
85-
call_function="transfer_keep_alive",
86-
call_params={"dest": destination, "value": amount.rao},
85+
call_function=call_function,
86+
call_params=call_params,
8787
)
8888
extrinsic = await subtensor.substrate.create_signed_extrinsic(
8989
call=call, keypair=wallet.coldkey, era={"period": era}
@@ -115,6 +115,20 @@ async def do_transfer() -> tuple[bool, str, str]:
115115
if not unlock_key(wallet).success:
116116
return False
117117

118+
call_params = {"dest": destination}
119+
if transfer_all:
120+
call_function = "transfer_all"
121+
if allow_death:
122+
call_params["keep_alive"] = False
123+
else:
124+
call_params["keep_alive"] = True
125+
else:
126+
call_params["value"] = amount.rao
127+
if allow_death:
128+
call_function = "transfer_allow_death"
129+
else:
130+
call_function = "transfer_keep_alive"
131+
118132
# Check balance.
119133
with console.status(
120134
f":satellite: Checking balance and fees on chain [white]{subtensor.network}[/white]",
@@ -131,23 +145,26 @@ async def do_transfer() -> tuple[bool, str, str]:
131145
)
132146
fee = await get_transfer_fee()
133147

134-
if not keep_alive:
135-
# Check if the transfer should keep_alive the account
148+
if allow_death:
149+
# Check if the transfer should keep alive the account
136150
existential_deposit = Balance(0)
137151

138-
# Check if we have enough balance.
139-
if transfer_all is True:
140-
amount = account_balance - fee - existential_deposit
141-
if amount < Balance(0):
142-
print_error("Not enough balance to transfer")
143-
return False
144-
145-
if account_balance < (amount + fee + existential_deposit):
152+
if account_balance < (amount + fee + existential_deposit) and not allow_death:
146153
err_console.print(
147154
":cross_mark: [bold red]Not enough balance[/bold red]:\n\n"
148155
f" balance: [bright_cyan]{account_balance}[/bright_cyan]\n"
149156
f" amount: [bright_cyan]{amount}[/bright_cyan]\n"
150-
f" for fee: [bright_cyan]{fee}[/bright_cyan]"
157+
f" for fee: [bright_cyan]{fee}[/bright_cyan]\n"
158+
f" would bring you under the existential deposit: [bright_cyan]{existential_deposit}[/bright_cyan].\n"
159+
f"You can try again with `--allow-death`."
160+
)
161+
return False
162+
elif account_balance < (amount + fee) and allow_death:
163+
print_error(
164+
":cross_mark: [bold red]Not enough balance[/bold red]:\n\n"
165+
f" balance: [bright_red]{account_balance}[/bright_red]\n"
166+
f" amount: [bright_red]{amount}[/bright_red]\n"
167+
f" for fee: [bright_red]{fee}[/bright_red]"
151168
)
152169
return False
153170

bittensor_cli/src/bittensor/subtensor_interface.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,6 +1457,8 @@ async def subnet(
14571457
),
14581458
self.get_subnet_price(netuid=netuid, block_hash=block_hash),
14591459
)
1460+
if not result:
1461+
raise ValueError(f"Subnet {netuid} not found")
14601462
subnet_ = DynamicInfo.from_any(result)
14611463
subnet_.price = price
14621464
return subnet_

bittensor_cli/src/commands/wallets.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,6 +1408,7 @@ async def transfer(
14081408
destination: str,
14091409
amount: float,
14101410
transfer_all: bool,
1411+
allow_death: bool,
14111412
era: int,
14121413
prompt: bool,
14131414
json_output: bool,
@@ -1419,6 +1420,7 @@ async def transfer(
14191420
destination=destination,
14201421
amount=Balance.from_tao(amount),
14211422
transfer_all=transfer_all,
1423+
allow_death=allow_death,
14221424
era=era,
14231425
prompt=prompt,
14241426
)

0 commit comments

Comments
 (0)