Skip to content

Commit

Permalink
Merge pull request #449 from LedgerHQ/tdj/eth_plugin_sdk_update
Browse files Browse the repository at this point in the history
Update plugins SDK framework
  • Loading branch information
apaillier-ledger authored Oct 19, 2023
2 parents 0595496 + 6126bb6 commit 5d913f3
Show file tree
Hide file tree
Showing 24 changed files with 607 additions and 225 deletions.
39 changes: 26 additions & 13 deletions client/src/ledger_app_clients/ethereum/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from enum import IntEnum
from ragger.backend import BackendInterface
from ragger.utils import RAPDU
from typing import List, Optional, Union
from typing import List, Optional

from .command_builder import CommandBuilder
from .eip712 import EIP712FieldType
Expand Down Expand Up @@ -30,8 +30,7 @@ class StatusWord(IntEnum):
CONDITION_NOT_SATISFIED = 0x6985
REF_DATA_NOT_FOUND = 0x6a88


class DOMAIN_NAME_TAG(IntEnum):
class DomainNameTag(IntEnum):
STRUCTURE_TYPE = 0x01
STRUCTURE_VERSION = 0x02
CHALLENGE = 0x12
Expand All @@ -52,7 +51,7 @@ def _send(self, payload: bytes):
return self._client.exchange_async_raw(payload)

def response(self) -> Optional[RAPDU]:
return self._client._last_async_response
return self._client.last_async_response

def eip712_send_struct_def_struct_name(self, name: str):
return self._send(self._cmd_builder.eip712_send_struct_def_struct_name(name))
Expand Down Expand Up @@ -190,15 +189,15 @@ def get_public_addr(self,
chain_id))

def provide_domain_name(self, challenge: int, name: str, addr: bytes):
payload = format_tlv(DOMAIN_NAME_TAG.STRUCTURE_TYPE, 3) # TrustedDomainName
payload += format_tlv(DOMAIN_NAME_TAG.STRUCTURE_VERSION, 1)
payload += format_tlv(DOMAIN_NAME_TAG.SIGNER_KEY_ID, 0) # test key
payload += format_tlv(DOMAIN_NAME_TAG.SIGNER_ALGO, 1) # secp256k1
payload += format_tlv(DOMAIN_NAME_TAG.CHALLENGE, challenge)
payload += format_tlv(DOMAIN_NAME_TAG.COIN_TYPE, 0x3c) # ETH in slip-44
payload += format_tlv(DOMAIN_NAME_TAG.DOMAIN_NAME, name)
payload += format_tlv(DOMAIN_NAME_TAG.ADDRESS, addr)
payload += format_tlv(DOMAIN_NAME_TAG.SIGNATURE,
payload = format_tlv(DomainNameTag.STRUCTURE_TYPE, 3) # TrustedDomainName
payload += format_tlv(DomainNameTag.STRUCTURE_VERSION, 1)
payload += format_tlv(DomainNameTag.SIGNER_KEY_ID, 0) # test key
payload += format_tlv(DomainNameTag.SIGNER_ALGO, 1) # secp256k1
payload += format_tlv(DomainNameTag.CHALLENGE, challenge)
payload += format_tlv(DomainNameTag.COIN_TYPE, 0x3c) # ETH in slip-44
payload += format_tlv(DomainNameTag.DOMAIN_NAME, name)
payload += format_tlv(DomainNameTag.ADDRESS, addr)
payload += format_tlv(DomainNameTag.SIGNATURE,
sign_data(Key.DOMAIN_NAME, payload))

chunks = self._cmd_builder.provide_domain_name(payload)
Expand Down Expand Up @@ -271,3 +270,17 @@ def provide_nft_metadata(self,
key_id,
algo_id,
sig))

def set_external_plugin(self,
plugin_name: str,
contract_address: bytes,
method_selelector: bytes,
sig: Optional[bytes] = None):
if sig is None:
# Temporarily get a command with an empty signature to extract the payload and
# compute the signature on it
tmp = self._cmd_builder.set_external_plugin(plugin_name, contract_address, method_selelector, bytes())

# skip APDU header & empty sig
sig = sign_data(Key.SET_PLUGIN, tmp[5:-1])
return self._send(self._cmd_builder.set_external_plugin(plugin_name, contract_address, method_selelector, sig))
17 changes: 17 additions & 0 deletions client/src/ledger_app_clients/ethereum/command_builder.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# documentation about APDU format is available here:
# https://github.com/LedgerHQ/app-ethereum/blob/develop/doc/ethapp.adoc

import struct
from enum import IntEnum
from typing import Optional
Expand All @@ -18,6 +21,7 @@ class InsType(IntEnum):
EIP712_SIGN = 0x0c
GET_CHALLENGE = 0x20
PROVIDE_DOMAIN_NAME = 0x22
EXTERNAL_PLUGIN_SETUP = 0x12


class P1Type(IntEnum):
Expand Down Expand Up @@ -178,6 +182,19 @@ def eip712_filtering_show_field(self, name: str, sig: bytes) -> bytes:
P2Type.FILTERING_FIELD_NAME,
self._eip712_filtering_send_name(name, sig))

def set_external_plugin(self, plugin_name: str, contract_address: bytes, method_selelector: bytes, sig: bytes) -> bytes:
data = bytearray()
data.append(len(plugin_name))
data += self._string_to_bytes(plugin_name)
data += contract_address
data += method_selelector
data += sig

return self._serialize(InsType.EXTERNAL_PLUGIN_SETUP,
P1Type.COMPLETE_SEND,
0x00,
data)

def sign(self, bip32_path: str, rlp_data: bytes) -> list[bytes]:
apdus = list()
payload = pack_derivation_path(bip32_path)
Expand Down
10 changes: 6 additions & 4 deletions src/handle_check_address.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@ int handle_check_address(check_address_parameters_t* params, chain_config_t* cha
ZERO(locals_union2);
cx_ecfp_generate_pair(CX_CURVE_256K1, &locals_union2.publicKey, &locals_union1.privateKey, 1);
ZERO(locals_union1);
getEthAddressStringFromKey(&locals_union2.publicKey,
locals_union1.address,
&local_sha3,
chain_config->chainId);
if (!getEthAddressStringFromKey(&locals_union2.publicKey,
locals_union1.address,
&local_sha3,
chain_config->chainId)) {
THROW(CX_INVALID_PARAMETER);
}
ZERO(locals_union2);

uint8_t offset_0x = 0;
Expand Down
14 changes: 8 additions & 6 deletions src/handle_get_printable_amount.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@ int handle_get_printable_amount(get_printable_amount_parameters_t* params, chain
}
}

amountToString(params->amount,
params->amount_length,
decimals,
ticker,
params->printable_amount,
sizeof(params->printable_amount));
if (!amountToString(params->amount,
params->amount_length,
decimals,
ticker,
params->printable_amount,
sizeof(params->printable_amount))) {
THROW(EXCEPTION_OVERFLOW);
}
return 1;
}
28 changes: 16 additions & 12 deletions src/handle_swap_sign_transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,26 @@ bool copy_transaction_parameters(create_transaction_parameters_t* sign_transacti
PRINTF("Error while parsing config\n");
return false;
}
amountToString(sign_transaction_params->amount,
sign_transaction_params->amount_length,
decimals,
ticker,
stack_data.fullAmount,
sizeof(stack_data.fullAmount));
if (!amountToString(sign_transaction_params->amount,
sign_transaction_params->amount_length,
decimals,
ticker,
stack_data.fullAmount,
sizeof(stack_data.fullAmount))) {
THROW(EXCEPTION_OVERFLOW);
}

// If the amount is a fee, its value is nominated in ETH even if we're doing an ERC20 swap
strlcpy(ticker, config->coinName, MAX_TICKER_LEN);
decimals = WEI_TO_ETHER;
amountToString(sign_transaction_params->fee_amount,
sign_transaction_params->fee_amount_length,
decimals,
ticker,
stack_data.maxFee,
sizeof(stack_data.maxFee));
if (!amountToString(sign_transaction_params->fee_amount,
sign_transaction_params->fee_amount_length,
decimals,
ticker,
stack_data.maxFee,
sizeof(stack_data.maxFee))) {
THROW(EXCEPTION_OVERFLOW);
}

// Full reset the global variables
os_explicit_zero_BSS_segment();
Expand Down
7 changes: 4 additions & 3 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ bool uint256_to_decimal(const uint8_t *value, size_t value_len, char *out, size_
return true;
}

void amountToString(const uint8_t *amount,
bool amountToString(const uint8_t *amount,
uint8_t amount_size,
uint8_t decimals,
const char *ticker,
Expand All @@ -125,7 +125,7 @@ void amountToString(const uint8_t *amount,
char tmp_buffer[100] = {0};

if (uint256_to_decimal(amount, amount_size, tmp_buffer, sizeof(tmp_buffer)) == false) {
THROW(EXCEPTION_OVERFLOW);
return false;
}

uint8_t amount_len = strnlen(tmp_buffer, sizeof(tmp_buffer));
Expand All @@ -141,10 +141,11 @@ void amountToString(const uint8_t *amount,
out_buffer + ticker_len,
out_buffer_size - ticker_len - 1,
decimals) == false) {
THROW(EXCEPTION_OVERFLOW);
return false;
}

out_buffer[out_buffer_size - 1] = '\0';
return true;
}

bool parse_swap_config(const uint8_t *config, uint8_t config_len, char *ticker, uint8_t *decimals) {
Expand Down
2 changes: 1 addition & 1 deletion src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ uint64_t u64_from_BE(const uint8_t* in, uint8_t size);

bool uint256_to_decimal(const uint8_t* value, size_t value_len, char* out, size_t out_len);

void amountToString(const uint8_t* amount,
bool amountToString(const uint8_t* amount,
uint8_t amount_len,
uint8_t decimals,
const char* ticker,
Expand Down
17 changes: 12 additions & 5 deletions src_bagl/ui_flow_stark_sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "ui_callbacks.h"
#include "ethUtils.h"
#include "starkDisplayUtils.h"
#include "apdu_constants.h"

// clang-format off
UX_STEP_NOCB(ux_stark_limit_order_1_step,
Expand Down Expand Up @@ -78,6 +79,16 @@ UX_FLOW(ux_stark_limit_order_flow,
&ux_stark_limit_order_7_step,
&ux_stark_limit_order_8_step);

static void stark_format_address(void) {
if (!getEthDisplayableAddress(dataContext.starkContext.conditionAddress,
strings.tmp.tmp,
sizeof(strings.tmp.tmp),
&global_sha3,
chainConfig->chainId)) {
THROW(APDU_RESPONSE_ERROR_NO_INFO);
}
}

//////////////////////////////////////////////////////////////////////
// clang-format off
UX_STEP_NOCB(ux_stark_transfer_1_step,
Expand Down Expand Up @@ -167,11 +178,7 @@ UX_STEP_NOCB_INIT(
UX_STEP_NOCB_INIT(
ux_stark_conditional_transfer_8_step,
bnnn_paging,
getEthDisplayableAddress(dataContext.starkContext.conditionAddress,
strings.tmp.tmp,
sizeof(strings.tmp.tmp),
&global_sha3,
chainConfig->chainId),
stark_format_address(),
{
.title = "Cond. Address",
.text = strings.tmp.tmp
Expand Down
Loading

0 comments on commit 5d913f3

Please sign in to comment.