Skip to content

Commit

Permalink
Add sign with ledger
Browse files Browse the repository at this point in the history
  • Loading branch information
moisses89 committed Feb 11, 2023
1 parent 1cf9a8f commit 7f598e8
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 7 deletions.
2 changes: 1 addition & 1 deletion safe_cli/operators/hw_accounts/ledger_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def encrypt(self, password, kdf=None, iterations=None):
# TODO with ledger
pass

def signHash(self, message_hash, domain_hash: bytes):
def signHash(self, domain_hash: bytes, message_hash: bytes):
signed = sign_typed_data_draft(domain_hash, message_hash, dongle=self.dongle)
return (signed.v, signed.r, signed.s)

Expand Down
38 changes: 32 additions & 6 deletions safe_cli/operators/safe_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from eth_account import Account
from eth_account.signers.local import LocalAccount
from eth_utils import ValidationError
from gnosis.eth.eip712 import eip712_encode_hash, eip712_encode
from gnosis.safe.signatures import signature_to_bytes
from hexbytes import HexBytes
from ledgereth import get_account_by_path
from ledgereth.comms import init_dongle
Expand Down Expand Up @@ -299,13 +301,10 @@ def load_ledger_cli_owners(self):
HTML(
f"Loaded account <b>{account.address}</b> "
f'with balance={Web3.fromWei(balance, "ether")} ether'
f'Ledger account cannot be defined as sender'
)
)
if not self.default_sender and balance > 0:
print_formatted_text(
HTML(f"Set account <b>{account.address}</b> as default sender of txs")
)
self.default_sender = sender
# TODO add ledger as sender
break

def unload_cli_owners(self, owners: List[str]):
Expand Down Expand Up @@ -845,6 +844,30 @@ def batch_safe_txs(
else:
return safe_tx

def ledger_sign(self,safe_tx:SafeTx, account: LedgerAccount) -> bytes:
"""
{bytes32 r}{bytes32 s}{uint8 v}
:param private_key:
:return: Signature
"""
encode_hash = eip712_encode(safe_tx.eip712_structured_data)
v,r,s = account.signHash(encode_hash[1], encode_hash[2])
signature = signature_to_bytes(
v , r , s
)
# Insert signature sorted
if account.address not in safe_tx.signers:
new_owners = safe_tx.signers + [account.address]
new_owner_pos = sorted(new_owners, key=lambda x: int(x, 16)).index(
account.address
)
safe_tx.signatures = (
safe_tx.signatures[: 65 * new_owner_pos]
+ signature
+ safe_tx.signatures[65 * new_owner_pos :]
)
return safe_tx

# TODO Set sender so we can save gas in that signature
def sign_transaction(self, safe_tx: SafeTx) -> SafeTx:
permitted_signers = self.get_permitted_signers()
Expand All @@ -863,7 +886,10 @@ def sign_transaction(self, safe_tx: SafeTx) -> SafeTx:
raise NotEnoughSignatures(threshold)

for selected_account in selected_accounts:
safe_tx.sign(selected_account.key)
if selected_account.key:
safe_tx.sign(selected_account.key)
else:
safe_tx = self.ledger_sign(safe_tx, selected_account)

return safe_tx

Expand Down

0 comments on commit 7f598e8

Please sign in to comment.