Skip to content

Commit 1fbf2d6

Browse files
authored
Merge pull request #86 from inaie-makerx/fix-rekey-transfer
fix: Fix problem with transfer from rekeyed account in wallet
2 parents 5ee3a3b + 1504b00 commit 1fbf2d6

File tree

4 files changed

+106
-14
lines changed

4 files changed

+106
-14
lines changed

docs/html/searchindex.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

poetry.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/algokit_utils/_transfer.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def transfer(client: "AlgodClient", parameters: TransferParameters) -> PaymentTx
8686
params = parameters
8787
params.suggested_params = parameters.suggested_params or client.suggested_params()
8888
from_account = params.from_account
89-
sender = address_from_private_key(from_account.private_key) # type: ignore[no-untyped-call]
89+
sender = _get_address(from_account)
9090
transaction = PaymentTxn(
9191
sender=sender,
9292
receiver=params.to_address,
@@ -105,7 +105,7 @@ def transfer_asset(client: "AlgodClient", parameters: TransferAssetParameters) -
105105

106106
params = parameters
107107
params.suggested_params = parameters.suggested_params or client.suggested_params()
108-
sender = address_from_private_key(parameters.from_account.private_key) # type: ignore[no-untyped-call]
108+
sender = _get_address(parameters.from_account)
109109
suggested_params = parameters.suggested_params or client.suggested_params()
110110
xfer_txn = AssetTransferTxn(
111111
sp=suggested_params,
@@ -139,9 +139,14 @@ def _send_transaction(
139139
client.send_transaction(signed_transaction)
140140

141141
txid = transaction.get_txid() # type: ignore[no-untyped-call]
142-
logger.debug(
143-
f"Sent transaction {txid} type={transaction.type} from "
144-
f"{address_from_private_key(parameters.from_account.private_key)}" # type: ignore[no-untyped-call]
145-
)
142+
logger.debug(f"Sent transaction {txid} type={transaction.type} from {_get_address(parameters.from_account)}")
146143

147144
return transaction
145+
146+
147+
def _get_address(account: Account | AccountTransactionSigner) -> str:
148+
if type(account) is Account:
149+
return account.address
150+
else:
151+
address = address_from_private_key(account.private_key) # type: ignore[no-untyped-call]
152+
return str(address)

tests/test_transfer.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
)
2020
from algokit_utils.dispenser_api import DispenserApiConfig
2121
from algokit_utils.network_clients import get_algod_client, get_algonode_config
22+
from algosdk.atomic_transaction_composer import AccountTransactionSigner
23+
from algosdk.transaction import PaymentTxn
2224
from algosdk.util import algos_to_microalgos
2325
from pytest_httpx import HTTPXMock
2426

@@ -38,6 +40,53 @@ def to_account(kmd_client: "KMDClient") -> Account:
3840
return create_kmd_wallet_account(kmd_client, get_unique_name())
3941

4042

43+
@pytest.fixture()
44+
def rekeyed_from_account(algod_client: "AlgodClient", kmd_client: "KMDClient") -> Account:
45+
account = create_kmd_wallet_account(kmd_client, get_unique_name())
46+
rekey_account = create_kmd_wallet_account(kmd_client, get_unique_name())
47+
48+
ensure_funded(
49+
algod_client,
50+
EnsureBalanceParameters(
51+
account_to_fund=account,
52+
min_spending_balance_micro_algos=300000,
53+
min_funding_increment_micro_algos=1,
54+
),
55+
)
56+
57+
rekey_txn = PaymentTxn(
58+
sender=account.address,
59+
receiver=account.address,
60+
amt=0,
61+
note="rekey account",
62+
rekey_to=rekey_account.address,
63+
sp=algod_client.suggested_params(),
64+
) # type: ignore[no-untyped-call]
65+
signed_rekey_txn = rekey_txn.sign(account.private_key) # type: ignore[no-untyped-call]
66+
algod_client.send_transaction(signed_rekey_txn)
67+
68+
return Account(address=account.address, private_key=rekey_account.private_key)
69+
70+
71+
@pytest.fixture()
72+
def transaction_signer_from_account(
73+
kmd_client: "KMDClient",
74+
algod_client: "AlgodClient",
75+
) -> AccountTransactionSigner:
76+
account = create_kmd_wallet_account(kmd_client, get_unique_name())
77+
78+
ensure_funded(
79+
algod_client,
80+
EnsureBalanceParameters(
81+
account_to_fund=account,
82+
min_spending_balance_micro_algos=300000,
83+
min_funding_increment_micro_algos=1,
84+
),
85+
)
86+
87+
return AccountTransactionSigner(private_key=account.private_key)
88+
89+
4190
@pytest.fixture()
4291
def clawback_account(kmd_client: "KMDClient") -> Account:
4392
return create_kmd_wallet_account(kmd_client, get_unique_name())
@@ -60,6 +109,44 @@ def test_transfer_algo(algod_client: "AlgodClient", to_account: Account, funded_
60109
assert actual_amount == requested_amount
61110

62111

112+
def test_transfer_algo_rekey_account(
113+
algod_client: "AlgodClient", to_account: Account, rekeyed_from_account: Account
114+
) -> None:
115+
requested_amount = 100_000
116+
transfer(
117+
algod_client,
118+
TransferParameters(
119+
from_account=rekeyed_from_account,
120+
to_address=to_account.address,
121+
micro_algos=requested_amount,
122+
),
123+
)
124+
125+
to_account_info = algod_client.account_info(to_account.address)
126+
assert isinstance(to_account_info, dict)
127+
actual_amount = to_account_info.get("amount")
128+
assert actual_amount == requested_amount
129+
130+
131+
def test_transfer_algo_transaction_signer_account(
132+
algod_client: "AlgodClient", to_account: Account, transaction_signer_from_account: AccountTransactionSigner
133+
) -> None:
134+
requested_amount = 100_000
135+
transfer(
136+
algod_client,
137+
TransferParameters(
138+
from_account=transaction_signer_from_account,
139+
to_address=to_account.address,
140+
micro_algos=requested_amount,
141+
),
142+
)
143+
144+
to_account_info = algod_client.account_info(to_account.address)
145+
assert isinstance(to_account_info, dict)
146+
actual_amount = to_account_info.get("amount")
147+
assert actual_amount == requested_amount
148+
149+
63150
def test_transfer_algo_max_fee_fails(algod_client: "AlgodClient", to_account: Account, funded_account: Account) -> None:
64151
requested_amount = 100_000
65152
max_fee = 123

0 commit comments

Comments
 (0)