Code documentation
ragger.address_book
Generic helper for the SDK Address Book feature: each sub-command serializes
itself into a TLV payload and builds its own APDUs via get_chunks().
- class ragger.address_book.address_book.AddressBookFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
IntEnumAddress Book specific fields .
- class ragger.address_book.address_book.BlockchainFamily(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
IntEnumBlockchain family (tag BLOCKCHAIN_FAMILY).
ragger.backend
ragger.backend.interface
Interface contract
The contract a backend must respect:
Response management policy
To change the behavior of the backend on response APDU, one can
tinker with the RaisePolicy:
ragger.error
- class ragger.error.ExceptionRAPDU(status: int, data: bytes = b'')
Depending on the
RaisePolicy, communication with an application can raise this exception.Just like
RAPDU, it is composed of two attributes:status(int), which is extracted from the two last bytes of the response,data(bytes), which is the entire response payload, except the two last bytes.
ragger.firmware
Most Ragger high-level class needs to know which Firmware they
should expect. This is declared with this class:
- class ragger.firmware.Firmware(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
IntEnum- NANOS = 1
- NANOSP = 2
- NANOX = 3
- STAX = 4
- FLEX = 5
- APEX_P = 6
- APEX_M = 7
- property device: str
A proxy property for
Firmware.name. This property is deprecated. It is advise to not use it.
- property is_nano
States if the firmware’s name starts with ‘nano’ or not.
- property name: str
Returns the name of the current firmware’s device
ragger.pki
Helper to sign payloads and onboard a PKI certificate on a device, acting as a Trust Services signing partner.
- class ragger.pki.SigningPartner(pem_key_path: ~pathlib.Path, cert_pub_key_usage: ~ragger.pki.signing_partner.CertificatePubKeyUsage, certificates: dict[ledgered.devices.DeviceType, str], hash_func=<built-in function openssl_sha256>, sigencode=<function sigencode_der>)
A PKI signing partner that can sign payloads and onboard its certificate on a device.
Generic over: - PEM key file used for signing - Signing algorithm (hash function + signature encoding) - PKI certificate APDU data per device firmware
- __init__(pem_key_path: ~pathlib.Path, cert_pub_key_usage: ~ragger.pki.signing_partner.CertificatePubKeyUsage, certificates: dict[ledgered.devices.DeviceType, str], hash_func=<built-in function openssl_sha256>, sigencode=<function sigencode_der>)
- Args:
pem_key_path: Path to the PEM private key file. cert_pub_key_usage: PKI certificate public key usage (sent as P1 in cert APDU). certificates: Mapping of DeviceType -> hex-encoded certificate data string. hash_func: Hash function for PEM key loading and signing (default: SHA-256). sigencode: Signature encoding function (default: DER encoding).
- get_certificate_payload(device_type: DeviceType) bytes
Return the raw PKI certificate APDU bytes for the given device type.
- Raises:
KeyError: If the device type has no certificate configured.
- sign(data: bytes) bytes
Sign data and return the encoded signature.
- class ragger.pki.CertificatePubKeyUsage(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
- BACKUP_PROVIDER = 5
- CALLDATA = 11
- COIN_META = 8
- EXCHANGE_PAYLOAD = 2
- GATING = 15
- GENUINE_CHECK = 1
- LKRP_TOPIC = 16
- NETWORK = 12
- NFT_METADATA = 3
- PERPS_DATA = 17
- PLUGIN_METADATA = 7
- RECOVER_ORCHESTRATOR = 6
- SAFE_ACCOUNT = 14
- SEED_ID_AUTH = 9
- SWAP_TEMPLATE = 13
- TOKEN_MULTIPLIER = 18
- TRUSTED_NAME = 4
- TX_SIMU_SIGNER = 10
ragger.tlv
Generic TLV serialization primitives and the Trust Services tag/enum registry.
ragger.tlv.serializable
- class ragger.tlv.serializable.TlvSerializable
Base class for objects that serialize themselves into a TLV payload.
Subclasses implement
serialize(), concatenating oneserialize_field()(a.k.a.format_tlv()) per field. This is transport-agnostic: APDU framing (CLA/INS, chunking) is the caller’s responsibility.
- ragger.tlv.serializable.der_encode(value: int) bytes
DER-encode an unsigned integer (used for both TLV tags and lengths).
Values below 0x80 are encoded as a single byte. Larger values are encoded as a length-prefix byte (0x80 | byte_count) followed by the big-endian bytes.
- ragger.tlv.serializable.format_tlv(tag: int, value: Union[int, str, bytes, bytearray]) bytes
Serialize a single (tag, value) pair into a DER-style TLV triplet.
intvalues are encoded as minimal-length big-endian bytes andstrvalues as their UTF-8 encoding before the length/value are emitted.
ragger.tlv.common_tags
- class ragger.tlv.common_tags.LedgerCommonFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Globally unique TLV tags (Ledger Trust Services spec).
- ADDRESS = 34
- CHAIN_ID = 35
- CHALLENGE = 18
- COIN_TYPE = 33
- DEPTH = 54
- DER_SIGNATURE = 21
- DOMAIN_HASH = 40
- HMAC_PROOF = 41
- MAGNITUDE = 37
- NOT_VALID_AFTER = 16
- PUBLIC_KEY = 51
- PUBLIC_KEY_CURVE = 50
- PUBLIC_KEY_ID = 48
- PUBLIC_KEY_SIGN_ALGO = 52
- PUBLIC_KEY_USAGE = 49
- SIGNER_ALGO = 20
- SIGNER_KEY_ID = 19
- STRUCTURE_TYPE = 1
- TARGET_DEVICE = 53
- TICKER = 36
- TIME = 38
- TRUSTED_NAME = 32
- TX_HASH = 39
- VALIDITY_INDEX = 17
- VALID_UNTIL = 22
- VERSION = 2
ragger.tlv.feature_tags
- class ragger.tlv.feature_tags.AddressBookFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Address Book specific fields .
- ACCOUNT_IDENTIFIER = 242
- CONTACT_NAME = 240
- GROUP_HANDLE = 246
- HMAC_REST = 247
- PREVIOUS_CONTACT_NAME = 243
- PREVIOUS_IDENTIFIER = 244
- PREVIOUS_SCOPE = 245
- SCOPE = 241
- class ragger.tlv.feature_tags.AleoFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Aleo application specific fields.
- FEE_FUNCTION_NAME = 178
- FEE_PROGRAM_ID = 179
- FUNCTION_NAME = 182
- GAMMAS = 194
- GAMMAS_COUNT = 193
- INPUT_COUNT = 183
- INPUT_TYPES = 185
- INPUT_VALUES = 184
- MAX_BASE_FEE = 176
- MAX_PRIORITY_FEE = 177
- NESTED_CALL_COUNT = 186
- NETWORK_ID = 195
- PROGRAM_CHECKSUM = 196
- PROGRAM_ID = 181
- RECORD_COMMITMENT = 189
- RECORD_COMMITMENTS_COUNT = 188
- REQUEST = 180
- R_HINT = 197
- TPK = 192
- TVK = 191
- class ragger.tlv.feature_tags.CoinInfoFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Coin info / dynamic network specific fields.
- BLOCKCHAIN_FAMILY = 81
- COIN_CONFIG = 80
- NETWORK_ICON_HASH = 83
- NETWORK_NAME = 82
- class ragger.tlv.feature_tags.EvmFunctionFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
EVM function info / plugin descriptor specific fields.
- DELEGATION_TYPE = 66
- EVM_FUNCTION_SELECTOR = 64
- IMPLEMENTATION_ADDRESSES = 65
- class ragger.tlv.feature_tags.LesMultisigFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
LES Multisig specific fields.
- ROLE = 162
- SIGNERS_COUNT = 161
- THRESHOLD = 160
- class ragger.tlv.feature_tags.PerpsActionFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Perps action wrapper.
- ACTION_STRUCTURE = 219
- ACTION_TYPE = 208
- NONCE = 218
- class ragger.tlv.feature_tags.PerpsApprovalBuilderFeeFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Perps ApprovalBuilderFee action structure.
- BUILDER_ADDRESS = 211
- MAX_BASE_FEE = 176
- class ragger.tlv.feature_tags.PerpsCancelOrderFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Perps cancel_order action structure.
- ASSET_ID = 209
- CANCEL_ORDER = 217
- ORDER_ID = 220
- class ragger.tlv.feature_tags.PerpsContextFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Perps context descriptor.
- ACTION_TYPE = 208
- ASSET_ID = 209
- BUILDER_ADDRESS = 211
- LEVERAGE = 213
- MARGIN = 212
- NETWORK_TYPE = 210
- class ragger.tlv.feature_tags.PerpsCreateOrderFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Perps create_order action structure.
- BUILDER = 235
- BUILDER_ADDRESS = 211
- BUILDER_FEE = 236
- GROUPING = 234
- ORDER = 221
- class ragger.tlv.feature_tags.PerpsLeverageFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Perps leverage action structure.
- ASSET_ID = 209
- IS_CROSS = 222
- LEVERAGE = 237
- class ragger.tlv.feature_tags.PerpsOrderFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Perps Order structure, incl. its ORDER_DETAIL tags.
NB: here ASSET_ID is 0xe1 (vs 0xd1 in the other sub-structures).
- ASSET_ID = 225
- IS_BUY = 226
- ORDER_DETAIL = 215
- ORDER_TYPE = 224
- PRICE = 227
- REDUCE_ONLY = 229
- SIZE = 228
- TIF = 230
- TRIGGER_MARKET = 231
- TRIGGER_PRICE = 232
- TRIGGER_TYPE = 233
- class ragger.tlv.feature_tags.PerpsUpdateIsolatedMarginFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Perps UpdateIsolatedMargin action structure.
- ASSET_ID = 225
- IS_BUY = 226
- NTLI = 214
- class ragger.tlv.feature_tags.PerpsUpdateOrderFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Perps update_order action structure.
- ORDER = 221
- ORDER_ID = 220
- UPDATE_ORDER = 216
- class ragger.tlv.feature_tags.SeedIdLkrpFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
SeedID / LKRP specific fields.
- ADDRESS_SIGNATURE = 97
- DERIVATION_PATH = 105
- DISPLAY = 104
- DISPLAYED_STEP_COUNT = 108
- MEMBER = 106
- MEMBER_COUNT = 109
- PROTOCOL_VERSION = 96
- STEP_COUNT = 103
- STEP_TYPE = 102
- TOPIC_CONTROL_DISPLAY = 100
- TOPIC_DICTIONARY = 99
- TOPIC_HASH = 107
- TOPIC_NEW_AUTHORITY = 101
- TOPIC_PARENT = 98
- class ragger.tlv.feature_tags.SwapTemplateFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Solana swap template specific fields.
- AMOUNT_OFFSET = 148
- AMOUNT_RULES = 149
- AMOUNT_SIZE = 147
- ASSET_ACCOUNT_INDEX = 150
- ASSET_ATA_INDEX = 151
- DISCRIMINATOR = 146
- PROGRAM_ID = 145
- RECIPIENT_ACCOUNT_INDEX = 152
- RECIPIENT_ATA_INDEX = 153
- TEMPLATE_ID = 144
- class ragger.tlv.feature_tags.TrustedNameFieldTag(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Trusted domain name specific fields.
- TRUSTED_NAME_NFT_ID = 114
- TRUSTED_NAME_OWNER = 116
- TRUSTED_NAME_OWNER_DERIVATION_PATH = 117
- TRUSTED_NAME_SOURCE = 113
- TRUSTED_NAME_SOURCE_CONTRACT = 115
- TRUSTED_NAME_TYPE = 112
ragger.tlv.enums
- class ragger.tlv.enums.BlockchainFamily(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Blockchain family (tag BLOCKCHAIN_FAMILY).
- BITCOIN = 0
- CARDANO = 5
- COSMOS = 4
- ETHEREUM = 1
- POLKADOT = 3
- SOLANA = 2
- TRON = 6
- class ragger.tlv.enums.LedgerStructType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Structure type discriminator for Ledger Trust Services (tag STRUCTURE_TYPE).
- TYPE_ALEO_INTENT = 40
- TYPE_ALEO_PREPARED_REQUEST = 41
- TYPE_ALEO_REQUEST_SIGNATURE = 42
- TYPE_CERTIFICATE = 1
- TYPE_COIN_INFO = 6
- TYPE_DOMAIN_TRUSTED_NAME = 3
- TYPE_DYNAMIC_NETWORK = 8
- TYPE_EDIT_CONTACT_NAME = 46
- TYPE_EDIT_IDENTIFIER = 49
- TYPE_EDIT_LEDGER_ACCOUNT = 48
- TYPE_EDIT_SCOPE = 50
- TYPE_ERC20_INFO = 4
- TYPE_EVM_FUNCTION_INFO = 5
- TYPE_GATED_SIGNING = 13
- TYPE_LESM_ACCOUNT_INFO = 39
- TYPE_LKRP_STEP = 14
- TYPE_LKRP_TOPIC = 12
- TYPE_NFT_COLLECTION_NAME = 2
- TYPE_PERPS_ACTION = 44
- TYPE_PERPS_METADATA = 43
- TYPE_PROVIDE_CONTACT = 51
- TYPE_PROVIDE_LEDGER_ACCOUNT_CONTACT = 52
- TYPE_PROXY = 38
- TYPE_REGISTER_IDENTITY = 45
- TYPE_REGISTER_LEDGER_ACCOUNT = 47
- TYPE_SEED_ID_AUTHENTICATION_CHALLENGE = 7
- TYPE_SOLANA_SWAP_TEMPLATE = 10
- TYPE_TX_SIMULATION = 9
- TYPE_VERIFIABLE_ADDRESS = 11
- class ragger.tlv.enums.LesMultisigRole(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
LES Multisig address role (tag ROLE).
- PROPOSER = 1
- SIGNER = 0
- class ragger.tlv.enums.LkrpStepType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
LKRP intent step type (tag STEP_TYPE).
- ADD_MEMBER = 1
- AUTHENTICATE = 5
- DISPLAY = 4
- HEADER = 0
- REMOVE_MEMBER = 2
- SET_TOPIC = 3
- class ragger.tlv.enums.ProxyDelegatorType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Proxy/delegator type (tag DELEGATION_TYPE).
- DELEGATOR = 2
- ISSUED_FROM_FACTORY = 1
- PROXY = 0
- class ragger.tlv.enums.SimulationType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
TX simulation type (tag SIMULATION_TYPE).
- MESSAGE = 2
- TRANSACTION = 0
- TYPED_MESSAGE = 1
- class ragger.tlv.enums.TrustedNameSource(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Trusted name namespace (tag TRUSTED_NAME_SOURCE).
- CRYPTO_ASSET_LIST = 1
- DNS = 5
- DYNAMIC_RESOLVER = 6
- ENS = 2
- FREENAME = 4
- LESM_ADDRESS_BOOK = 7
- LOCAL_ADDRESS_BOOK = 0
- UNSTOPPABLE_DOMAIN = 3
- class ragger.tlv.enums.TrustedNameType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Trusted name account type (tag TRUSTED_NAME_TYPE).
- CCD_CONTEXT_ADDRESS = 7
- COLLECTION = 3
- CONTEXT_ADDRESS = 6
- EOA = 1
- SMART_CONTRACT = 2
- TOKEN = 4
- WALLET = 5
ragger.utils
ragger.utils.structs
- class ragger.utils.structs.RAPDU(status: int, data: bytes)
The dataclass containing the application’s response of an APDU from the client to the application.
It is composed of two attributes:
status(int): from the two last bytes of the payload. Common values are 0x9000 for success, other being errors.data(bytes): the rest of the response (the entire payload without the two last bytes)
ragger.utils.misc
ragger.utils.coverage
- ragger.utils.coverage.enable(device_name: str, elf: Path, trace_dir: Path) None
Turn on QEMU
in_asmtracing for the upcoming Speculos launches.Sets the
QEMU_LOG*environment variables (inherited by the QEMU process Speculos spawns) and registers the (elf, trace_dir) couple for this device so the traces can be converted at the end of the session.%din the filename is expanded by QEMU to the process pid: the backend is usually class-scoped, so several QEMU instances run and each must write its own file.
- ragger.utils.coverage.finalize(project_root: Path, output: Path, readelf: str = 'readelf', exclude: Optional[List[str]] = None) List[Tuple[str, int, int, int, Path, Optional[Path]]]
Convert every registered device’s traces into an lcov file.
For a single device, writes
output. For several devices, writes one file per device next tooutput(<stem>-<device><suffix>). An HTML report is rendered next to each.info(<stem>_html/) whenevergenhtmlis available; otherwise only the lcov file is produced.excluderemoves matching repo-relative source paths (e.g. vendored submodules). Returns the per-device results (rendering of the human-readable summary is left to the caller).
- ragger.utils.coverage.to_html(info: Path, html_dir: Path, project_root: Path) Optional[Path]
Render an lcov
.infointo an HTML report withgenhtml.Run from
project_rootso the repo-relativeSF:paths resolve to their sources. Returns the report’sindex.htmlon success, or None (with a warning) ifgenhtmlis unavailable or failed.
- ragger.utils.coverage.to_lcov(elf: Path, trace_files: List[Path], output: Path, project_root: Path, readelf: str = 'readelf', load_base: int = 1073741824, exclude: Optional[List[str]] = None) Tuple[int, int, int]
Convert in_asm traces into an lcov tracefile.
excludeis an optional list of patterns (see_excluded()) removing matching repo-relative source paths, e.g. vendored submodules.Returns (files, covered_lines, instrumented_lines). Raises ValueError if the ELF has no DWARF line info, or if no app code was executed.