Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
81f11f1
Add 7702 documentation
btchip Feb 23, 2025
ace6b61
7702 Authorization phase 1 implementation
btchip Feb 23, 2025
2ccabbb
7702 authorization test CLI
btchip Feb 23, 2025
a59c2ca
7702 Ragger tests
btchip Feb 23, 2025
7827355
Add 7702 and test whitelist to Makefile
btchip Feb 23, 2025
24010d9
Add signature of TX Type 4 without displaying authorization lists
btchip Feb 23, 2025
f26b2ce
TX type 4 Ragger tests
btchip Feb 23, 2025
a54890f
Fix merge
btchip Mar 24, 2025
2e9e5a6
Fix merge
btchip Mar 24, 2025
38bf1af
Reorganize 7702 setting, add missing test change
btchip Mar 24, 2025
a213740
Implements Phase 1 specification changes
btchip Mar 24, 2025
08b90c8
Update tests
btchip Mar 24, 2025
b1fe602
Remove 7702 ragger snapshots to avoid conflicts with previous run
btchip Mar 25, 2025
4819c96
Minor UX adjustments
btchip Mar 25, 2025
bf1d069
Add clean updated ragger snapshots
btchip Mar 25, 2025
4dbb656
Adjust Nano S+ error message
btchip Mar 25, 2025
77e3035
Fix copypasta
btchip Mar 25, 2025
1f94188
Add Nano X tests
btchip Mar 25, 2025
6834451
Fix feature on Nano S
btchip Mar 25, 2025
7b3b597
Remove feature on Nano S
btchip Mar 25, 2025
42e3f16
Fix Nano S build
btchip Mar 25, 2025
484d9b4
Fix flake8 warnings
btchip Mar 25, 2025
ab52eb8
Fix Python typing
btchip Mar 25, 2025
88c27fa
Run clang-format
btchip Mar 25, 2025
83e3378
Remove unused parameters
btchip Mar 25, 2025
61608ab
Remove unnecessary ui_idle()
btchip Mar 25, 2025
a84c307
Merge branch 'LedgerHQ:develop' into 7702-phase1
btchip Apr 11, 2025
33287d6
Remove Nano S support
btchip Apr 13, 2025
471c0cd
Apply review comments, TLV format for APDU data
btchip Apr 13, 2025
4aad18f
Fix type
btchip Apr 13, 2025
f3753ab
Fix lint
btchip Apr 13, 2025
49d5e9f
Skip 7702 TX signing test on Nano S
btchip Apr 13, 2025
d3db76d
Fix import
btchip Apr 13, 2025
adc2401
Add 4337 SimpleAccount7702 to the whitelist
btchip Apr 13, 2025
7bb0eea
Now handles unlimited datetimes
apaillier-ledger Apr 14, 2025
4203fd8
Merge pull request #768 from LedgerHQ/feat/apa/unlimited_datetimes
apaillier-ledger Apr 17, 2025
41e7a41
Explicitely name parameters in sign_tx_common calls (Ragger tests)
apaillier-ledger Apr 17, 2025
0488d4b
Merge pull request #769 from LedgerHQ/feat/apa/explicit_named_parameters
apaillier-ledger Apr 17, 2025
db66e81
Explicitely name parameters in sign_tx_common calls (clone Ragger test)
apaillier-ledger Apr 18, 2025
415ad29
Merge pull request #770 from LedgerHQ/feat/apa/explicit_named_parameters
apaillier-ledger Apr 18, 2025
9530d02
Merge branch 'LedgerHQ:develop' into 7702-phase1
btchip Apr 18, 2025
1d11b83
Update tests
btchip Apr 18, 2025
4e5f9b3
Disable EIP 7702 features when not activated
btchip Apr 18, 2025
bd1bb2c
Rewrite mini example
btchip Apr 19, 2025
7618495
Merge pull request #739 from btchip/7702-phase1
apaillier-ledger Apr 22, 2025
b141589
Now use default version of the reusable lint workflow
apaillier-ledger Apr 22, 2025
b5db163
Merge pull request #771 from LedgerHQ/ci/apa/use_default_lint_version
apaillier-ledger Apr 22, 2025
bdd40f9
Fix potential memory leak with incorrect TLV structs
apaillier-ledger Apr 22, 2025
c513790
Merge pull request #773 from LedgerHQ/fix/apa/potential_memory_leak_t…
apaillier-ledger Apr 22, 2025
54b3731
Updated APDU doc for EIP-7702
apaillier-ledger Apr 22, 2025
2bd7d59
Removed the derivation path from the 7702 TLV struct
apaillier-ledger Apr 22, 2025
1990f9f
Now supports shrunk TLV data for EIP-7702
apaillier-ledger Apr 22, 2025
f647236
Fix EIP-7702 flake8 / mypy warnings
apaillier-ledger Apr 22, 2025
7488e5a
Fix potential memory leak with incorrect EIP-7702 TLV struct
apaillier-ledger Apr 22, 2025
d906218
EIP-7702 error handling cleanup
apaillier-ledger Apr 22, 2025
6fa9e4a
Updated example 7702 script
apaillier-ledger Apr 23, 2025
d6b2648
Moved the 7702 struct version check to the verify struct function
apaillier-ledger Apr 23, 2025
3f9583f
Test EIP-7702 whitelist not compiled by default anymore
apaillier-ledger Apr 23, 2025
be53fee
Merge pull request #772 from LedgerHQ/feat/apa/7702_changes
apaillier-ledger Apr 23, 2025
eea02f8
Fixed Python warnings in test_sign
apaillier-ledger Apr 23, 2025
3a2b474
Update Python client to web3 v7
apaillier-ledger Apr 23, 2025
6e952d8
vrs now stored as integers in Python client
apaillier-ledger Apr 24, 2025
4b40bc2
Move away from typing.Tuple to tuple in Python client
apaillier-ledger Apr 24, 2025
941aae8
Improve EIP-7702 tests with web3 v7
apaillier-ledger Apr 24, 2025
7e3a15d
Merge pull request #775 from LedgerHQ/feat/apa/web3_v7
apaillier-ledger Apr 24, 2025
ed7060a
Fix version compare in trusted name
apaillier-ledger Apr 28, 2025
98055ba
Merge pull request #777 from LedgerHQ/feat/apa/trusted_name_expiratio…
apaillier-ledger Apr 28, 2025
329a627
Split check_tx_simulation_params to separate checks for 'hash' and 'f…
cedelavergne-ledger Apr 28, 2025
fb9b9cd
Adapt streaming Tx check to new functions
cedelavergne-ledger Apr 28, 2025
0633b7a
Merge pull request #779 from LedgerHQ/cev/hotfix_tx_check_eip712
cedelavergne-ledger Apr 28, 2025
f299bf1
Merge remote-tracking branch 'origin/master' into version_bump
apaillier-ledger Apr 29, 2025
4c32120
Version bump to 1.17.0-dev
apaillier-ledger Apr 29, 2025
116e31f
Merge pull request #780 from LedgerHQ/version_bump
apaillier-ledger Apr 29, 2025
72539ae
Add specific sounds to Transaction Check
cedelavergne-ledger Apr 29, 2025
a991f96
Add new test 'test_blind_sign_nonce'
cedelavergne-ledger Apr 30, 2025
2b6946b
Adapt tests
cedelavergne-ledger Apr 30, 2025
91c2192
Update snapshots
cedelavergne-ledger Apr 29, 2025
b2fab25
Merge pull request #781 from LedgerHQ/cev/tx_check_improve
cedelavergne-ledger Apr 30, 2025
65bb9e1
Fix potential double dealloc with tlv_from_apdu
apaillier-ledger Apr 30, 2025
a40bd4e
Merge pull request #782 from LedgerHQ/fix/apa/double_dealloc
apaillier-ledger Apr 30, 2025
e634980
Removed hardcoded newlines in NBGL 7702 autorization flow
apaillier-ledger Apr 30, 2025
f122c6b
Removed extra unused NBGL pair in 7702 auth flow
apaillier-ledger May 2, 2025
48e67ce
Fixed linting in 7702 bagl code
apaillier-ledger May 2, 2025
67a3708
Added support for 7702 revocation
apaillier-ledger May 2, 2025
a62b6c3
Removed Zero from EIP7702 test whitelist (conflicts with revocation)
apaillier-ledger May 2, 2025
e739740
Added a new 7702 revocation test
apaillier-ledger May 2, 2025
9c136c0
Merge pull request #783 from LedgerHQ/feat/apa/7702_revoke
apaillier-ledger May 5, 2025
d9f5c77
Increased 7702 whitelist name to 30 characters
apaillier-ledger May 5, 2025
e5c47f8
Added Metamask's Delegation Manager contract to the 7702 whitelist
apaillier-ledger May 5, 2025
77a23ba
Added an extra check before decompressing the calldata chunk
apaillier-ledger May 5, 2025
246a7e9
Merge pull request #784 from LedgerHQ/fix/apa/calldata_chunk_bug
apaillier-ledger May 5, 2025
bb11634
Merge pull request #785 from LedgerHQ/feat/apa/whitelist_mm_7702
apaillier-ledger May 5, 2025
ce3648b
Removed Nano S from manifest
apaillier-ledger May 5, 2025
ca413fa
Removed Nano S from CodeQL workflow
apaillier-ledger May 5, 2025
5b4523a
Removed Nano S tests snapshots
apaillier-ledger May 5, 2025
90bff3d
Merge pull request #787 from LedgerHQ/rem/apa/nanos_support
apaillier-ledger May 5, 2025
b742994
Metamask 7702 whitelisted contract address fix
apaillier-ledger May 5, 2025
fc7bafd
Merge pull request #788 from LedgerHQ/fix/apa/whitelist_mm_7702
apaillier-ledger May 5, 2025
74fe81e
Updated changelog
apaillier-ledger May 5, 2025
b5605cf
Removed -dev version number suffix
apaillier-ledger May 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/workflows/build_and_functional_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_build.yml@v1
with:
upload_app_binaries_artifact: "ragger_elfs"
flags: "CAL_TEST_KEY=1 TRUSTED_NAME_TEST_KEY=1 SET_PLUGIN_TEST_KEY=1 NFT_TEST_KEY=1"
flags: "CAL_TEST_KEY=1 TRUSTED_NAME_TEST_KEY=1 SET_PLUGIN_TEST_KEY=1 NFT_TEST_KEY=1 EIP7702_TEST_WHITELIST=1"

ragger_tests:
name: Run ragger tests using the reusable workflow
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql_checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
strategy:
fail-fast: false
matrix:
sdk: ["$NANOS_SDK", "$NANOX_SDK", "$NANOSP_SDK", "$STAX_SDK", "$FLEX_SDK"]
sdk: ["$NANOX_SDK", "$NANOSP_SDK", "$STAX_SDK", "$FLEX_SDK"]
# 'cpp' covers C and C++
language: ['cpp']
runs-on: ubuntu-latest
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/lint-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ jobs:
with:
source: './'
extensions: 'h,c'
version: 12

yamllint:
name: Check yaml files
Expand Down
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [1.17.0](../../compare/1.16.0...1.17.0) - 2025-05-05

### Added

- EIP-7702 authorization signing
- Type 4 transaction signing

### Changed

- Datetime formatter now supports `Unlimited` (for things that are not meant to expire)
- Some TX check screens now play a sound (Flex / Stax)

### Removed

- Nano S support

## [1.16.0](../../compare/1.15.0...1.16.0) - 2025-04-28

### Added
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ endif
include ./makefile_conf/chain/$(CHAIN).mk

APPVERSION_M = 1
APPVERSION_N = 16
APPVERSION_N = 17
APPVERSION_P = 0
APPVERSION = $(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)

Expand Down
9 changes: 5 additions & 4 deletions client/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,20 @@ readme = { file = "README.md", content-type = "text/markdown" }
# license = { file = "LICENSE" }
classifiers = [
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Operating System :: POSIX :: Linux",
"Operating System :: Microsoft :: Windows",
"Operating System :: MacOS :: MacOS X",
]
dynamic = [ "version" ]
requires-python = ">=3.7"
requires-python = ">=3.9"
dependencies = [
"ragger[speculos]",
"web3~=6.0",
"web3~=7.0",
]

[tools.setuptools]
Expand Down
17 changes: 12 additions & 5 deletions client/src/ledger_app_clients/ethereum/client.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import struct
from enum import IntEnum
from typing import Optional, Tuple
from typing import Optional
from hashlib import sha256
import rlp
from web3 import Web3
Expand All @@ -17,6 +17,7 @@
from .tlv import format_tlv, FieldTag
from .response_parser import pk_addr
from .tx_simu import TxSimu
from .tx_auth_7702 import TxAuth7702


class StatusWord(IntEnum):
Expand Down Expand Up @@ -212,13 +213,13 @@ def eip712_filtering_trusted_name(self,
def eip712_filtering_raw(self, name: str, sig: bytes, discarded: bool):
return self._exchange_async(self._cmd_builder.eip712_filtering_raw(name, sig, discarded))

def serialize_tx(self, tx_params: dict) -> Tuple[bytes, bytes]:
def serialize_tx(self, tx_params: dict) -> tuple[bytes, bytes]:
"""Computes the serialized TX and its hash"""

tx = Web3().eth.account.create().sign_transaction(tx_params).rawTransaction
tx = Web3().eth.account.create().sign_transaction(tx_params).raw_transaction
prefix = bytes()
suffix = []
if tx[0] in [0x01, 0x02]:
if tx[0] in [0x01, 0x02, 0x04]:
prefix = tx[:1]
tx = tx[len(prefix):]
else: # legacy
Expand Down Expand Up @@ -330,7 +331,7 @@ def provide_trusted_name_v2(self,
chain_id: int,
nft_id: Optional[int] = None,
challenge: Optional[int] = None,
not_valid_after: Optional[Tuple[int]] = None) -> RAPDU:
not_valid_after: Optional[tuple[int, int, int]] = None) -> RAPDU:
payload = format_tlv(FieldTag.STRUCT_VERSION, 2)
payload += format_tlv(FieldTag.TRUSTED_NAME, name)
payload += format_tlv(FieldTag.ADDRESS, addr)
Expand Down Expand Up @@ -671,3 +672,9 @@ def provide_proxy_info(self, payload: bytes) -> RAPDU:
for chunk in chunks[:-1]:
self._exchange(chunk)
return self._exchange(chunks[-1])

def sign_eip7702_authorization(self, bip32_path: str, auth_params: TxAuth7702) -> RAPDU:
chunks = self._cmd_builder.sign_eip7702_authorization(bip32_path, auth_params.serialize())
for chunk in chunks[:-1]:
self._exchange(chunk)
return self._exchange_async(chunks[-1])
17 changes: 15 additions & 2 deletions client/src/ledger_app_clients/ethereum/command_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# https://github.com/LedgerHQ/app-ethereum/blob/develop/doc/ethapp.adoc

import struct
import math
from enum import IntEnum
from typing import Optional
from ragger.bip import pack_derivation_path
Expand Down Expand Up @@ -31,6 +32,7 @@ class InsType(IntEnum):
PROVIDE_PROXY_INFO = 0x2a
PROVIDE_NETWORK_INFORMATION = 0x30
PROVIDE_TX_SIMULATION = 0x32
SIGN_EIP7702_AUTHORIZATION = 0x34


class P1Type(IntEnum):
Expand Down Expand Up @@ -64,6 +66,11 @@ class P2Type(IntEnum):
class CommandBuilder:
_CLA: int = 0xE0

def _intToBytes(self, i: int) -> bytes:
if i == 0:
return b"\x00"
return i.to_bytes(math.ceil(i.bit_length() / 8), 'big')

def _serialize(self,
ins: InsType,
p1: int,
Expand Down Expand Up @@ -419,11 +426,12 @@ def common_tlv_serialize(self,
ins: InsType,
tlv_payload: bytes,
p1l: list[int] = [0x01, 0x00],
p2l: list[int] = [0x00]) -> list[bytes]:
p2l: list[int] = [0x00],
payload: bytes = bytes()) -> list[bytes]:
assert len(p1l) in [1, 2]
assert len(p2l) in [1, 2]
chunks = []
payload = struct.pack(">H", len(tlv_payload))
payload += struct.pack(">H", len(tlv_payload))
payload += tlv_payload
p1 = p1l[0]
p2 = p2l[0]
Expand Down Expand Up @@ -456,6 +464,11 @@ def provide_network_information(self,
p1 = P1Type.FOLLOWING_CHUNK
return chunks

def sign_eip7702_authorization(self, bip32_path: str, tlv_payload: bytes) -> list[bytes]:
return self.common_tlv_serialize(InsType.SIGN_EIP7702_AUTHORIZATION,
tlv_payload,
payload=pack_derivation_path(bip32_path))

def provide_enum_value(self, tlv_payload: bytes) -> list[bytes]:
return self.common_tlv_serialize(InsType.PROVIDE_ENUM_VALUE, tlv_payload)

Expand Down
8 changes: 4 additions & 4 deletions client/src/ledger_app_clients/ethereum/response_parser.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
def signature(data: bytes) -> tuple[bytes, bytes, bytes]:
def signature(data: bytes) -> tuple[int, int, int]:
assert len(data) == (1 + 32 + 32)

v = data[0:1]
v = int.from_bytes(data[0:1], "big")
data = data[1:]
r = data[0:32]
r = int.from_bytes(data[0:32], "big")
data = data[32:]
s = data[0:32]
s = int.from_bytes(data[0:32], "big")

return v, r, s

Expand Down
8 changes: 8 additions & 0 deletions client/src/ledger_app_clients/ethereum/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class SettingID(Enum):
NONCE = auto()
VERBOSE_EIP712 = auto()
DEBUG_DATA = auto()
EIP7702 = auto()


def get_device_settings(firmware: Firmware) -> list[SettingID]:
Expand All @@ -28,6 +29,7 @@ def get_device_settings(firmware: Firmware) -> list[SettingID]:
SettingID.NONCE,
SettingID.VERBOSE_EIP712,
SettingID.DEBUG_DATA,
SettingID.EIP7702,
]
return [
SettingID.WEB3_CHECK,
Expand All @@ -36,6 +38,7 @@ def get_device_settings(firmware: Firmware) -> list[SettingID]:
SettingID.NONCE,
SettingID.VERBOSE_EIP712,
SettingID.DEBUG_DATA,
SettingID.EIP7702,
]


Expand Down Expand Up @@ -75,6 +78,11 @@ def get_setting_position(firmware: Firmware, setting: SettingID) -> tuple[int, i
page, y = 2, 130
else:
page, y = 2, 315
elif setting == SettingID.EIP7702:
if firmware == Firmware.STAX:
page, y = 2, 300
else:
page, y = 3, 140
else:
raise ValueError(f"Unknown setting: {setting}")
return page, x, y
Expand Down
34 changes: 34 additions & 0 deletions client/src/ledger_app_clients/ethereum/tx_auth_7702.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from typing import Optional
from enum import IntEnum
from .tlv import TlvSerializable


class FieldTag(IntEnum):
STRUCT_VERSION = 0x00
DELEGATE_ADDR = 0x01
CHAIN_ID = 0x02
NONCE = 0x03


class TxAuth7702(TlvSerializable):
delegate: bytes
nonce: int
chain_id: int

def __init__(self,
delegate: bytes,
nonce: int,
chain_id: Optional[int]) -> None:
self.delegate = delegate
self.nonce = nonce
if chain_id is None:
self.chain_id = 0
else:
self.chain_id = chain_id

def serialize(self) -> bytes:
payload: bytes = self.serialize_field(FieldTag.STRUCT_VERSION, 1)
payload += self.serialize_field(FieldTag.DELEGATE_ADDR, self.delegate)
payload += self.serialize_field(FieldTag.CHAIN_ID, self.chain_id)
payload += self.serialize_field(FieldTag.NONCE, self.nonce)
return payload
52 changes: 35 additions & 17 deletions client/src/ledger_app_clients/ethereum/utils.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,29 @@
from eth_account import Account
from eth_account.messages import encode_defunct, encode_typed_data
from eth_account.datastructures import SignedSetCodeAuthorization
from eth_account.typed_transactions.set_code_transaction import Authorization
from eth_keys.datatypes import Signature
import rlp


# eth_account requires it for some reason
def normalize_vrs(vrs: tuple) -> tuple:
vrs_l = []
for elem in vrs:
vrs_l.append(elem.lstrip(b'\x00'))
return tuple(vrs_l)


def get_selector_from_data(data: str) -> bytes:
raw_data = bytes.fromhex(data[2:])
return raw_data[:4]


def recover_message(msg, vrs: tuple) -> bytes:
def recover_message(msg, vrs: tuple[int, int, int]) -> bytes:
if isinstance(msg, dict): # EIP-712
smsg = encode_typed_data(full_message=msg)
else: # EIP-191
smsg = encode_defunct(primitive=msg)
addr = Account.recover_message(smsg, normalize_vrs(vrs))
addr = Account.recover_message(smsg, vrs)
return bytes.fromhex(addr[2:])


def recover_transaction(tx_params, vrs: tuple) -> bytes:
raw_tx = Account.create().sign_transaction(tx_params).rawTransaction
def recover_transaction(tx_params, vrs: tuple[int, int, int]) -> bytes:
raw_tx = Account.create().sign_transaction(tx_params).raw_transaction
prefix = bytes()
if raw_tx[0] in [0x01, 0x02]:
if raw_tx[0] in [0x01, 0x02, 0x04]:
prefix = raw_tx[:1]
raw_tx = raw_tx[len(prefix):]
else:
Expand All @@ -40,7 +35,7 @@ def recover_transaction(tx_params, vrs: tuple) -> bytes:
trunc_chain_id >>= 8

trunc_target = trunc_chain_id * 2 + 35
trunc_v = int.from_bytes(vrs[0], "big")
trunc_v = vrs[0]

if (trunc_target & 0xff) == trunc_v:
parity = 0
Expand All @@ -52,12 +47,35 @@ def recover_transaction(tx_params, vrs: tuple) -> bytes:

# https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
full_v = parity + tx_params["chainId"] * 2 + 35
# 9 bytes would be big enough even for the biggest chain ID
vrs = (int(full_v).to_bytes(9, "big"), vrs[1], vrs[2])
vrs = (full_v, vrs[1], vrs[2])
else:
# Pre EIP-155 TX
assert False
decoded = rlp.decode(raw_tx)
reencoded = rlp.encode(decoded[:-3] + list(normalize_vrs(vrs)))
reencoded = rlp.encode(decoded[:-3] + list(vrs))
addr = Account.recover_transaction(prefix + reencoded)
return bytes.fromhex(addr[2:])


# Code inspired by :
# https://github.com/ethereum/eth-account/blob/a1ba20c9a112d3534ac3296f21f51e2f5127bf9b/eth_account/account.py#L1057
def get_authorization_obj(chain_id: int,
nonce: int,
address: bytes,
vrs: tuple[int, int, int]) -> SignedSetCodeAuthorization:
unsigned_authorization = Authorization(chain_id, address, nonce)
sig = Signature(vrs=vrs)
return SignedSetCodeAuthorization(
chain_id=chain_id,
address=address,
nonce=nonce,
y_parity=sig.v,
r=sig.r,
s=sig.s,
signature=sig,
authorization_hash=unsigned_authorization.hash(),
)


def recover_authorization(chain_id: int, nonce: int, address: bytes, vrs: tuple[int, int, int]) -> bytes:
return get_authorization_obj(chain_id, nonce, address, vrs).authority
Loading
Loading