-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathbase_transactions_controller.py
86 lines (72 loc) · 3.47 KB
/
base_transactions_controller.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
from typing import Optional, Union
from multiversx_sdk import LedgerAccount, Transaction, TransactionComputer
from multiversx_sdk_cli.constants import (
EXTRA_GAS_LIMIT_FOR_GUARDED_TRANSACTIONS,
EXTRA_GAS_LIMIT_FOR_RELAYED_TRANSACTIONS,
)
from multiversx_sdk_cli.cosign_transaction import cosign_transaction
from multiversx_sdk_cli.interfaces import IAccount
class BaseTransactionsController:
def __init__(self) -> None:
pass
def sign_transaction(
self,
transaction: Transaction,
sender: Optional[IAccount] = None,
guardian: Optional[IAccount] = None,
relayer: Optional[IAccount] = None,
guardian_service_url: Optional[str] = None,
guardian_2fa_code: Optional[str] = None,
):
"""Signs the transaction using the sender's account and, if required, additionally signs with the guardian's and relayer's accounts. Ensures the appropriate transaction options are set as needed."""
self._set_options_for_guarded_transaction_if_needed(transaction)
self._set_options_for_hash_signing_if_needed(transaction, sender, guardian, relayer)
if sender:
transaction.signature = sender.sign_transaction(transaction)
self._sign_guarded_transaction_if_guardian(
transaction,
guardian,
guardian_service_url,
guardian_2fa_code,
)
self._sign_relayed_transaction_if_relayer(transaction, relayer)
def add_extra_gas_limit_if_required(self, transaction: Transaction):
"""In case of guarded or relayed transactions, extra gas limit is added."""
if transaction.guardian:
transaction.gas_limit += EXTRA_GAS_LIMIT_FOR_GUARDED_TRANSACTIONS
if transaction.relayer:
transaction.gas_limit += EXTRA_GAS_LIMIT_FOR_RELAYED_TRANSACTIONS
def _set_options_for_guarded_transaction_if_needed(self, transaction: Transaction):
if transaction.guardian:
transaction_computer = TransactionComputer()
transaction_computer.apply_guardian(transaction, transaction.guardian)
def _set_options_for_hash_signing_if_needed(
self,
transaction: Transaction,
sender: Union[IAccount, None],
guardian: Union[IAccount, None],
relayer: Union[IAccount, None],
):
if (
isinstance(sender, LedgerAccount)
or isinstance(guardian, LedgerAccount)
or isinstance(relayer, LedgerAccount)
):
transaction_computer = TransactionComputer()
transaction_computer.apply_options_for_hash_signing(transaction)
def _sign_guarded_transaction_if_guardian(
self,
transaction: Transaction,
guardian: Union[IAccount, None],
guardian_service_url: Union[str, None],
guardian_2fa_code: Union[str, None],
) -> Transaction:
# If the guardian account is provided, we sign locally. Otherwise, we reach for the trusted cosign service.
if guardian:
transaction.guardian_signature = guardian.sign_transaction(transaction)
elif transaction.guardian and guardian_service_url and guardian_2fa_code:
cosign_transaction(transaction, guardian_service_url, guardian_2fa_code)
return transaction
def _sign_relayed_transaction_if_relayer(self, transaction: Transaction, relayer: Union[IAccount, None]):
if relayer and transaction.relayer:
transaction.relayer_signature = relayer.sign_transaction(transaction)