Cleanup src_plugin_sdk directory

- No need to copy local files
- No need to keep local copy of 'etherum-plugin-sdk' files
- Select needed files directly from the Makefile
This commit is contained in:
Charles-Edouard de la Vergne
2024-04-12 12:23:30 +02:00
parent 5e21c7c5a9
commit 1ddd0e9671
19 changed files with 12 additions and 1373 deletions

View File

@@ -23,4 +23,4 @@ jobs:
with:
builtin: clear,rare
check_filenames: true
path: src, src_bagl, src_common, src_features, src_nbgl, src_plugin_sdk, src_plugins, doc, client
path: src, src_bagl, src_features, src_nbgl, src_plugin_sdk, src_plugins, doc, client

View File

@@ -38,38 +38,21 @@ ifneq ($(CHAIN),$(filter $(CHAIN),$(SUPPORTED_CHAINS)))
endif
include ./makefile_conf/chain/$(CHAIN).mk
### initialize plugin SDK submodule if needed, rebuild it, and warn if a difference is noticed
ifeq ($(CHAIN),ethereum)
ifneq ($(shell git submodule status | grep '^[-+]'),)
$(info INFO: Need to reinitialize git submodules)
$(shell git submodule update --init)
endif
# rebuild SDK
$(shell ./tools/build_sdk.sh)
# check if a difference is noticed (fail if it happens in CI build)
ifneq ($(shell git status | grep 'ethereum-plugin-sdk'),)
ifneq ($(JENKINS_URL),)
$(error ERROR: please update ethereum-plugin-sdk submodule first)
else
$(warning WARNING: please update ethereum-plugin-sdk submodule first)
endif
endif
endif
APPVERSION_M = 1
APPVERSION_N = 11
APPVERSION_P = 0
APPVERSION = $(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)-dev
# Application source files
APP_SOURCE_PATH += src_common src src_features src_plugins
APP_SOURCE_PATH += src src_features src_plugins
ifeq ($(TARGET_NAME),TARGET_STAX)
APP_SOURCE_PATH += src_nbgl
else
APP_SOURCE_PATH += src_bagl
endif
APP_SOURCE_FILES += ./ethereum-plugin-sdk/src/common_utils.c
APP_SOURCE_FILES += ./ethereum-plugin-sdk/src/plugin_utils.c
INCLUDES_PATH += ./ethereum-plugin-sdk/src
APP_SOURCE_FILES += ${BOLOS_SDK}/lib_standard_app/crypto_helpers.c
INCLUDES_PATH += ${BOLOS_SDK}/lib_standard_app

View File

@@ -135,6 +135,12 @@ If you prefer using a terminal to perform the steps manually, you can use the gu
Setup a compilation environment by following the [shell with docker approach](#with-a-terminal).
Be sure you checkout the submodule:
```shell
git submodule update --init
```
From inside the container, use the following command to build the app:
```shell

View File

@@ -1,51 +0,0 @@
/*******************************************************************************
* Ledger Ethereum App
* (c) 2016-2019 Ledger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
#pragma once
#include <stdint.h>
#include "common_utils.h"
// NFT
#define COLLECTION_NAME_MAX_LEN 70
typedef struct nftInfo_t {
uint8_t contractAddress[ADDRESS_LENGTH]; // must be first item
char collectionName[COLLECTION_NAME_MAX_LEN + 1];
} nftInfo_t;
// TOKENS
#define MAX_TICKER_LEN 11 // 10 characters + '\0'
#define MAX_ITEMS 2
typedef struct tokenDefinition_t {
uint8_t address[ADDRESS_LENGTH]; // must be first item
#ifdef HAVE_CONTRACT_NAME_IN_DESCRIPTOR
uint8_t contractName[ADDRESS_LENGTH];
#endif
char ticker[MAX_TICKER_LEN];
uint8_t decimals;
} tokenDefinition_t;
// UNION
typedef union extraInfo_t {
tokenDefinition_t token;
nftInfo_t nft;
} extraInfo_t;

View File

@@ -1,34 +0,0 @@
/*******************************************************************************
* Ledger Ethereum App
* (c) 2016-2019 Ledger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
#pragma once
#ifdef HAVE_NBGL
#include "ux.h"
#endif
typedef enum { CALLER_TYPE_CLONE, CALLER_TYPE_PLUGIN } e_caller_type;
typedef struct caller_app_t {
const char *name;
#ifdef HAVE_NBGL
const nbgl_icon_details_t *icon;
#endif
char type; // does not have to be set by the caller app
} caller_app_t;
extern caller_app_t *caller_app;

View File

@@ -1,311 +0,0 @@
/*******************************************************************************
* Ledger Ethereum App
* (c) 2016-2019 Ledger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
#include <stdint.h>
#include <string.h>
#include "asset_info.h"
#include "common_utils.h"
#include "lcx_ecfp.h"
#include "lcx_sha3.h"
void array_hexstr(char *strbuf, const void *bin, unsigned int len) {
while (len--) {
*strbuf++ = HEXDIGITS[((*((char *) bin)) >> 4) & 0xF];
*strbuf++ = HEXDIGITS[(*((char *) bin)) & 0xF];
bin = (const void *) ((unsigned int) bin + 1);
}
*strbuf = 0; // EOS
}
uint64_t u64_from_BE(const uint8_t *in, uint8_t size) {
uint8_t i = 0;
uint64_t res = 0;
while (i < size && i < sizeof(res)) {
res <<= 8;
res |= in[i];
i++;
}
return res;
}
bool u64_to_string(uint64_t src, char *dst, uint8_t dst_size) {
// Copy the numbers in ASCII format.
uint8_t i = 0;
do {
// Checking `i + 1` to make sure we have enough space for '\0'.
if (i + 1 >= dst_size) {
return false;
}
dst[i] = src % 10 + '0';
src /= 10;
i++;
} while (src);
// Null terminate string
dst[i] = '\0';
// Revert the string
i--;
uint8_t j = 0;
while (j < i) {
char tmp = dst[i];
dst[i] = dst[j];
dst[j] = tmp;
i--;
j++;
}
return true;
}
bool uint256_to_decimal(const uint8_t *value, size_t value_len, char *out, size_t out_len) {
if (value_len > INT256_LENGTH) {
// value len is bigger than INT256_LENGTH ?!
return false;
}
uint16_t n[16] = {0};
// Copy and right-align the number
memcpy((uint8_t *) n + INT256_LENGTH - value_len, value, value_len);
// Special case when value is 0
if (allzeroes(n, INT256_LENGTH)) {
if (out_len < 2) {
// Not enough space to hold "0" and \0.
return false;
}
strlcpy(out, "0", out_len);
return true;
}
uint16_t *p = n;
for (int i = 0; i < 16; i++) {
n[i] = __builtin_bswap16(*p++);
}
int pos = out_len;
while (!allzeroes(n, sizeof(n))) {
if (pos == 0) {
return false;
}
pos -= 1;
unsigned int carry = 0;
for (int i = 0; i < 16; i++) {
int rem = ((carry << 16) | n[i]) % 10;
n[i] = ((carry << 16) | n[i]) / 10;
carry = rem;
}
out[pos] = '0' + carry;
}
memmove(out, out + pos, out_len - pos);
out[out_len - pos] = 0;
return true;
}
bool adjustDecimals(const char *src,
size_t srcLength,
char *target,
size_t targetLength,
uint8_t decimals) {
uint32_t startOffset;
uint32_t lastZeroOffset = 0;
uint32_t offset = 0;
if ((srcLength == 1) && (*src == '0')) {
if (targetLength < 2) {
return false;
}
target[0] = '0';
target[1] = '\0';
return true;
}
if (srcLength <= decimals) {
uint32_t delta = decimals - srcLength;
if (targetLength < srcLength + 1 + 2 + delta) {
return false;
}
target[offset++] = '0';
target[offset++] = '.';
for (uint32_t i = 0; i < delta; i++) {
target[offset++] = '0';
}
startOffset = offset;
for (uint32_t i = 0; i < srcLength; i++) {
target[offset++] = src[i];
}
target[offset] = '\0';
} else {
uint32_t sourceOffset = 0;
uint32_t delta = srcLength - decimals;
if (targetLength < srcLength + 1 + 1) {
return false;
}
while (offset < delta) {
target[offset++] = src[sourceOffset++];
}
if (decimals != 0) {
target[offset++] = '.';
}
startOffset = offset;
while (sourceOffset < srcLength) {
target[offset++] = src[sourceOffset++];
}
target[offset] = '\0';
}
for (uint32_t i = startOffset; i < offset; i++) {
if (target[i] == '0') {
if (lastZeroOffset == 0) {
lastZeroOffset = i;
}
} else {
lastZeroOffset = 0;
}
}
if (lastZeroOffset != 0) {
target[lastZeroOffset] = '\0';
if (target[lastZeroOffset - 1] == '.') {
target[lastZeroOffset - 1] = '\0';
}
}
return true;
}
bool amountToString(const uint8_t *amount,
uint8_t amount_size,
uint8_t decimals,
const char *ticker,
char *out_buffer,
size_t out_buffer_size) {
char tmp_buffer[100] = {0};
if (uint256_to_decimal(amount, amount_size, tmp_buffer, sizeof(tmp_buffer)) == false) {
return false;
}
uint8_t amount_len = strnlen(tmp_buffer, sizeof(tmp_buffer));
uint8_t ticker_len = strnlen(ticker, MAX_TICKER_LEN);
if (ticker_len > 0) {
if (out_buffer_size <= ticker_len + 1) {
return false;
}
memcpy(out_buffer, ticker, ticker_len);
out_buffer[ticker_len++] = ' ';
}
if (adjustDecimals(tmp_buffer,
amount_len,
out_buffer + ticker_len,
out_buffer_size - ticker_len - 1,
decimals) == false) {
return false;
}
out_buffer[out_buffer_size - 1] = '\0';
return true;
}
void getEthAddressFromRawKey(const uint8_t raw_pubkey[static 65],
uint8_t out[static ADDRESS_LENGTH]) {
uint8_t hashAddress[CX_KECCAK_256_SIZE];
CX_ASSERT(cx_keccak_256_hash(raw_pubkey + 1, 64, hashAddress));
memmove(out, hashAddress + 12, ADDRESS_LENGTH);
}
void getEthAddressStringFromRawKey(const uint8_t raw_pubkey[static 65],
char out[static ADDRESS_LENGTH * 2],
uint64_t chainId) {
uint8_t hashAddress[CX_KECCAK_256_SIZE];
CX_ASSERT(cx_keccak_256_hash(raw_pubkey + 1, 64, hashAddress));
getEthAddressStringFromBinary(hashAddress + 12, out, chainId);
}
bool getEthAddressStringFromBinary(uint8_t *address,
char out[static ADDRESS_LENGTH * 2],
uint64_t chainId) {
// save some precious stack space
union locals_union {
uint8_t hashChecksum[INT256_LENGTH];
uint8_t tmp[51];
} locals_union;
uint8_t i;
bool eip1191 = false;
uint32_t offset = 0;
switch (chainId) {
case 30:
case 31:
eip1191 = true;
break;
}
if (eip1191) {
if (!u64_to_string(chainId, (char *) locals_union.tmp, sizeof(locals_union.tmp))) {
return false;
}
offset = strnlen((char *) locals_union.tmp, sizeof(locals_union.tmp));
strlcat((char *) locals_union.tmp + offset, "0x", sizeof(locals_union.tmp) - offset);
offset = strnlen((char *) locals_union.tmp, sizeof(locals_union.tmp));
}
for (i = 0; i < 20; i++) {
uint8_t digit = address[i];
locals_union.tmp[offset + 2 * i] = HEXDIGITS[(digit >> 4) & 0x0f];
locals_union.tmp[offset + 2 * i + 1] = HEXDIGITS[digit & 0x0f];
}
if (cx_keccak_256_hash(locals_union.tmp, offset + 40, locals_union.hashChecksum) != CX_OK) {
return false;
}
for (i = 0; i < 40; i++) {
uint8_t digit = address[i / 2];
if ((i % 2) == 0) {
digit = (digit >> 4) & 0x0f;
} else {
digit = digit & 0x0f;
}
if (digit < 10) {
out[i] = HEXDIGITS[digit];
} else {
int v = (locals_union.hashChecksum[i / 2] >> (4 * (1 - i % 2))) & 0x0f;
if (v >= 8) {
out[i] = HEXDIGITS[digit] - 'a' + 'A';
} else {
out[i] = HEXDIGITS[digit];
}
}
}
out[40] = '\0';
return true;
}
/* Fills the `out` buffer with the lowercase string representation of the pubkey passed in as binary
format by `in`. (eg: uint8_t*:0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB ->
char*:"0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB\0" ).*/
bool getEthDisplayableAddress(uint8_t *in, char *out, size_t out_len, uint64_t chainId) {
if (out_len < 43) {
strlcpy(out, "ERROR", out_len);
return false;
}
out[0] = '0';
out[1] = 'x';
if (!getEthAddressStringFromBinary(in, out + 2, chainId)) {
strlcpy(out, "ERROR", out_len);
return false;
}
return true;
}

View File

@@ -1,88 +0,0 @@
/*******************************************************************************
* Ledger Ethereum App
* (c) 2016-2019 Ledger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
#pragma once
#include <stddef.h>
#include <stdint.h>
#include "os.h"
#include "cx.h"
#define WEI_TO_ETHER 18
#define ADDRESS_LENGTH 20
#define INT128_LENGTH 16
#define INT256_LENGTH 32
#define KECCAK256_HASH_BYTESIZE 32
static const char HEXDIGITS[] = "0123456789abcdef";
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
void array_hexstr(char *strbuf, const void *bin, unsigned int len);
uint64_t u64_from_BE(const uint8_t *in, uint8_t size);
bool u64_to_string(uint64_t src, char *dst, uint8_t dst_size);
bool uint256_to_decimal(const uint8_t *value, size_t value_len, char *out, size_t out_len);
bool amountToString(const uint8_t *amount,
uint8_t amount_len,
uint8_t decimals,
const char *ticker,
char *out_buffer,
size_t out_buffer_size);
bool adjustDecimals(const char *src,
size_t srcLength,
char *target,
size_t targetLength,
uint8_t decimals);
void getEthAddressFromRawKey(const uint8_t raw_pubkey[static 65],
uint8_t out[static ADDRESS_LENGTH]);
void getEthAddressStringFromRawKey(const uint8_t raw_pubkey[static 65],
char out[static ADDRESS_LENGTH * 2],
uint64_t chainId);
bool getEthAddressStringFromBinary(uint8_t *address,
char out[static ADDRESS_LENGTH * 2],
uint64_t chainId);
bool getEthDisplayableAddress(uint8_t *in, char *out, size_t out_len, uint64_t chainId);
static __attribute__((no_instrument_function)) inline int allzeroes(const void *buf, size_t n) {
uint8_t *p = (uint8_t *) buf;
for (size_t i = 0; i < n; ++i) {
if (p[i]) {
return 0;
}
}
return 1;
}
static __attribute__((no_instrument_function)) inline int ismaxint(uint8_t *buf, int n) {
for (int i = 0; i < n; ++i) {
if (buf[i] != 0xff) {
return 0;
}
}
return 1;
}

View File

@@ -1,224 +0,0 @@
// clang-format off
#pragma once
#include "os.h"
#include "cx.h"
// Include other header compatible with plugins
#include "asset_info.h"
#include "caller_api.h"
#include "common_utils.h"
#include "plugin_utils.h"
#include "tx_content.h"
/*************************************************************************************************
* Comments provided in this file are quick reminders on the usage of the plugin interface *
* Reading the real plugin documentation is GREATLY recommended. *
* You can find the latest version here: *
* https://github.com/LedgerHQ/app-ethereum/blob/develop/doc/ethapp_plugins.adoc *
*************************************************************************************************/
// Interface version. Will be updated every time a breaking change in the interface is introduced.
typedef enum eth_plugin_interface_version_e {
ETH_PLUGIN_INTERFACE_VERSION_1 = 1,
ETH_PLUGIN_INTERFACE_VERSION_2 = 2,
ETH_PLUGIN_INTERFACE_VERSION_3 = 3,
ETH_PLUGIN_INTERFACE_VERSION_4 = 4,
ETH_PLUGIN_INTERFACE_VERSION_5 = 5,
ETH_PLUGIN_INTERFACE_VERSION_LATEST = 6,
} eth_plugin_interface_version_t;
// Codes for the different requests Ethereum can send to the plugin
// The dispatch is handled by the SDK itself, the plugin code does not have to handle it
typedef enum eth_plugin_msg_e {
// Codes for actions the Ethereum app can ask the plugin to perform
ETH_PLUGIN_INIT_CONTRACT = 0x0101,
ETH_PLUGIN_PROVIDE_PARAMETER = 0x0102,
ETH_PLUGIN_FINALIZE = 0x0103,
ETH_PLUGIN_PROVIDE_INFO = 0x0104,
ETH_PLUGIN_QUERY_CONTRACT_ID = 0x0105,
ETH_PLUGIN_QUERY_CONTRACT_UI = 0x0106,
// Special request: the Ethereum app is checking if we are installed on the device
ETH_PLUGIN_CHECK_PRESENCE = 0x01FF,
} eth_plugin_msg_t;
// Reply codes when responding to the Ethereum application
typedef enum eth_plugin_result_e {
// Unsuccessful return values
ETH_PLUGIN_RESULT_ERROR = 0x00,
ETH_PLUGIN_RESULT_UNAVAILABLE = 0x01,
ETH_PLUGIN_RESULT_UNSUCCESSFUL = 0x02, // Used for comparison
// Successful return values
ETH_PLUGIN_RESULT_SUCCESSFUL = 0x03, // Used for comparison
ETH_PLUGIN_RESULT_OK = 0x04,
ETH_PLUGIN_RESULT_OK_ALIAS = 0x05,
ETH_PLUGIN_RESULT_FALLBACK = 0x06,
} eth_plugin_result_t;
// Format of UI the Ethereum application has to use for this plugin
typedef enum eth_ui_type_e {
// If uiType is UI_AMOUNT_ADDRESS, Ethereum will use the amount/address UI
// the amount and address provided by the plugin will be used
// If tokenLookup1 is set, the amount is provided for this token
ETH_UI_TYPE_AMOUNT_ADDRESS = 0x01,
// If uiType is UI_TYPE_GENERIC, Ethereum will use the dedicated ETH plugin UI
// the ETH application provides tokens if requested then prompts for each UI field
// The first field is forced by the ETH app to be the name + version of the plugin handling the
// request. The last field is the fee amount
ETH_UI_TYPE_GENERIC = 0x02,
} eth_ui_type_t;
// Scratch objects and utilities available to the plugin READ-WRITE
typedef struct ethPluginSharedRW_s {
cx_sha3_t *sha3;
} ethPluginSharedRW_t;
// Transaction data available to the plugin READ-ONLY
typedef struct ethPluginSharedRO_s {
txContent_t *txContent;
} ethPluginSharedRO_t;
// Plugin-only memory allocated by the Ethereum application and used by the plugin.
#define PLUGIN_CONTEXT_SIZE (5 * INT256_LENGTH)
// It is recommended to cast the raw uin8_t array to a structure meaningful for your plugin
// Helper to check that the actual plugin context structure is not bigger than the allocated memory
#define ASSERT_SIZEOF_PLUGIN_CONTEXT(s) \
_Static_assert(sizeof(s) <= PLUGIN_CONTEXT_SIZE, "Plugin context structure is too big.")
/*
* HANDLERS AND PARAMETERS
* Parameters associated with the requests the Ethereum application can ask the plugin to perform
* The plugin SDK will automatically call the relevant handler for the received code, so the plugin
* has to define each of the handler functions declared below.
*/
// Init Contract
typedef struct ethPluginInitContract_s {
eth_plugin_interface_version_t interfaceVersion;
eth_plugin_result_t result;
// in
ethPluginSharedRW_t *pluginSharedRW;
ethPluginSharedRO_t *pluginSharedRO;
uint8_t *pluginContext;
size_t pluginContextLength;
const uint8_t *selector; // 4 bytes selector
size_t dataSize;
char *alias; // 29 bytes alias if ETH_PLUGIN_RESULT_OK_ALIAS set
} ethPluginInitContract_t;
// void handle_init_contract(ethPluginInitContract_t *parameters);
// Provide parameter
typedef struct ethPluginProvideParameter_s {
ethPluginSharedRW_t *pluginSharedRW;
ethPluginSharedRO_t *pluginSharedRO;
uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE
const uint8_t *parameter; // 32 bytes parameter
uint32_t parameterOffset;
eth_plugin_result_t result;
} ethPluginProvideParameter_t;
// void handle_provide_parameter(ethPluginProvideParameter_t *parameters);
// Finalize
typedef struct ethPluginFinalize_s {
ethPluginSharedRW_t *pluginSharedRW;
ethPluginSharedRO_t *pluginSharedRO;
uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE
uint8_t *tokenLookup1; // set by the plugin if a token should be looked up
uint8_t *tokenLookup2;
const uint8_t *amount; // set an uint256 pointer if uiType is UI_AMOUNT_ADDRESS
const uint8_t *address; // set to the destination address if uiType is UI_AMOUNT_ADDRESS. Set
// to the user's address if uiType is UI_TYPE_GENERIC
eth_ui_type_t uiType;
uint8_t numScreens; // ignored if uiType is UI_AMOUNT_ADDRESS
eth_plugin_result_t result;
} ethPluginFinalize_t;
// void handle_finalize(ethPluginFinalize_t *parameters);
// Provide token
typedef struct ethPluginProvideInfo_s {
ethPluginSharedRW_t *pluginSharedRW;
ethPluginSharedRO_t *pluginSharedRO;
uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE
union extraInfo_t *item1; // set by the ETH application, to be saved by the plugin
union extraInfo_t *item2;
uint8_t additionalScreens; // Used by the plugin if it needs to display additional screens
// based on the information received from the token definitions.
eth_plugin_result_t result;
} ethPluginProvideInfo_t;
// void handle_provide_token(ethPluginProvideInfo_t *parameters);
// Query Contract name and version
// This is always called on the non aliased contract
typedef struct ethQueryContractID_s {
ethPluginSharedRW_t *pluginSharedRW;
ethPluginSharedRO_t *pluginSharedRO;
uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE
char *name;
size_t nameLength;
char *version;
size_t versionLength;
eth_plugin_result_t result;
} ethQueryContractID_t;
// void handle_query_contract_id(ethQueryContractID_t *parameters);
// Query Contract UI
typedef struct ethQueryContractUI_s {
ethPluginSharedRW_t *pluginSharedRW;
ethPluginSharedRO_t *pluginSharedRO;
union extraInfo_t *item1;
union extraInfo_t *item2;
char network_ticker[MAX_TICKER_LEN];
uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE
uint8_t screenIndex;
char *title;
size_t titleLength;
char *msg;
size_t msgLength;
eth_plugin_result_t result;
} ethQueryContractUI_t;
// void handle_query_contract_ui(ethQueryContractUI_t *parameters);
// clang-format on

View File

@@ -1,42 +0,0 @@
#include <string.h>
#include "common_utils.h"
#include "plugin_utils.h"
void copy_address(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size) {
uint8_t copy_size = MIN(dst_size, ADDRESS_LENGTH);
memmove(dst, parameter + PARAMETER_LENGTH - copy_size, copy_size);
}
void copy_parameter(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size) {
uint8_t copy_size = MIN(dst_size, PARAMETER_LENGTH);
memmove(dst, parameter, copy_size);
}
bool U2BE_from_parameter(const uint8_t* parameter, uint16_t* value) {
if (allzeroes(parameter, PARAMETER_LENGTH - sizeof(uint16_t))) {
*value = U2BE(parameter, PARAMETER_LENGTH - sizeof(uint16_t));
return true;
}
return false;
}
bool U4BE_from_parameter(const uint8_t* parameter, uint32_t* value) {
if (allzeroes(parameter, PARAMETER_LENGTH - sizeof(uint32_t))) {
*value = U4BE(parameter, PARAMETER_LENGTH - sizeof(uint32_t));
return true;
}
return false;
}
bool find_selector(uint32_t selector, const uint32_t* array, size_t size, size_t* idx) {
for (size_t i = 0; i < size; ++i) {
if (selector == array[i]) {
if (idx != NULL) *idx = i;
return true;
}
}
return false;
}

View File

@@ -1,37 +0,0 @@
/*****************************************************************************
* Ledger
* (c) 2023 Ledger SAS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*****************************************************************************/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "eth_plugin_interface.h"
#define SELECTOR_SIZE 4
#define PARAMETER_LENGTH 32
void copy_address(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size);
void copy_parameter(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size);
// Get the value from the beginning of the parameter (right to left) and check if the rest of it is
// zero
bool U2BE_from_parameter(const uint8_t* parameter, uint16_t* value);
bool U4BE_from_parameter(const uint8_t* parameter, uint32_t* value);
bool find_selector(uint32_t selector, const uint32_t* array, size_t size, size_t* idx);

View File

@@ -1,43 +0,0 @@
/*******************************************************************************
* Ledger Ethereum App
* (c) 2016-2019 Ledger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "os.h"
#include "cx.h"
#include "common_utils.h"
typedef struct txInt256_t {
uint8_t value[INT256_LENGTH];
uint8_t length;
} txInt256_t;
typedef struct txContent_t {
txInt256_t gasprice; // Used as MaxFeePerGas when dealing with EIP1559 transactions.
txInt256_t startgas; // Also known as `gasLimit`.
txInt256_t value;
txInt256_t nonce;
txInt256_t chainID;
uint8_t destination[ADDRESS_LENGTH];
uint8_t destinationLength;
uint8_t v[8];
uint8_t vLength;
bool dataPresent;
} txContent_t;

View File

@@ -1,82 +0,0 @@
# Ethereum Plugin SDK changelog
| Icon | Impact |
|----------------------|-------------------------------|
| :rotating_light: | Breaks build |
| :warning: | Breaks compatibility with app |
## [latest](/) - 2024/04/12
### Fixed
* Fix potential oob writes in `amountToString`
## [8fe6572](/../../commit/8fe6572) - 2024/03/27
### Changed
* Add new functions `getEthAddressFromRawKey` and `getEthAddressStringFromRawKey`
* Simplify crypto calls in `getEthAddressStringFromBinary`
* Cleanup useless `cx_sha3_t` useless parameter
## [0a98664](/../../commit/0a98664) - 2024/02/07
### Removed
* UI disabler
## [2250549](/../../commit/2250549) - 2024/02/02
### Changed
* The SDK source code has been split into multiple smaller files
## [3b7e7ad](/../../commit/3b7e7ad) - 2023/12/07
### Fixed
* standard\_plugin build ([this PR on the SDK](https://github.com/LedgerHQ/ledger-secure-sdk/pull/473) had broken it)
* Broken variant auto-setting in the standard\_plugin Makefile
* Missing null-check on parameters received by the plugins
### Changed
* utils renamed to plugin\_utils to prevent filename conflicts in plugins
## [4d8e044](/../../commit/4d8e044) - 2023/11/09
### Added
* standard\_plugin Makefile so plugins can use it & have a really small Makefile
with only the relevant information
* Comments in the plugin interface header file
## [1fe4085](/../../commit/1fe4085) - 2023/10/19
### Changed
* Now only uses *\_no\_throw* functions, SDK functions now return a boolean
(keeps the guidelines enforcer happy)
### Added
* *main* & *dispatch\_call* functions are now part of the SDK and don't need to
be implemented by each plugin :rotating_light:
## [b9777e7](/../../commit/b9777e7) - 2023/05/16
### Added
* Stax support with information passed from plugin to app-ethereum (with caller app struct)
## [a4b971f](/../../commit/a4b971f) - 2023/01/24
### Changed
* Removed end space in tickers :warning:
## [81eb658](/../../commit/81eb658) - 2022/11/17
### Added
* *U2BE\_from\_parameter* & *U4BE\_from\_parameter* safe functions

View File

@@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,18 +0,0 @@
# ethereum-plugin-sdk
This repository is meant to be linked as submodule and used in external plugins working with [app-ethereum](https://github.com/LedgerHQ/app-ethereum).
It is composed of a few headers containing definitions about app-ethereum's internal transaction parsing state and some structures to communicate via shared memory.
## Updating this SDK
This SDK is updated at (app-ethereum) build time every time one of app-ethereum internals structures of interest are modified.
If this SDK gets updated, it is possible that all plugins must be recompiled (and eventually updated to work again with the update) with this new SDK.
Be careful, and weight your choices.
## Manual build
If for some reasons you want to rebuild this SDK manually from [app-ethereum](https://github.com/LedgerHQ/app-ethereum) (reminder: it is rebuild automatically when building app-ethereum itself):
```shell
$> ./tools/build_sdk.sh
```

View File

@@ -1,21 +0,0 @@
/*******************************************************************************
* Ledger Ethereum App
* (c) 2016-2019 Ledger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
********************************************************************************/
#pragma once
// Empty file, introduced to not break compatibility following plugin-sdk structure rework
#warning "Deprecated file, the sdk sources have been rationalized in several dedicated files."

View File

@@ -1,129 +0,0 @@
/*****************************************************************************
* Ledger Plugin SDK
* (c) 2023 Ledger SAS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*****************************************************************************/
#include "eth_plugin_interface.h"
#include "lib_standard_app/swap_lib_calls.h" // RUN_APPLICATION
// Functions implemented by the plugin
void handle_init_contract(ethPluginInitContract_t *parameters);
void handle_provide_parameter(ethPluginProvideParameter_t *parameters);
void handle_finalize(ethPluginFinalize_t *parameters);
void handle_provide_token(ethPluginProvideInfo_t *parameters);
void handle_query_contract_id(ethQueryContractID_t *parameters);
void handle_query_contract_ui(ethQueryContractUI_t *parameters);
// Calls the ethereum app.
static void call_app_ethereum() {
unsigned int libcall_params[5];
libcall_params[0] = (unsigned int) "Ethereum";
libcall_params[1] = 0x100;
libcall_params[2] = RUN_APPLICATION;
libcall_params[3] = (unsigned int) NULL;
#ifdef HAVE_NBGL
caller_app_t capp;
const char name[] = APPNAME;
nbgl_icon_details_t icon_details;
uint8_t bitmap[sizeof(ICONBITMAP)];
memcpy(&icon_details, &ICONGLYPH, sizeof(ICONGLYPH));
memcpy(&bitmap, &ICONBITMAP, sizeof(bitmap));
icon_details.bitmap = (const uint8_t *) bitmap;
capp.name = (const char *) name;
capp.icon = &icon_details;
libcall_params[4] = (unsigned int) &capp;
#else
libcall_params[4] = (unsigned int) NULL;
#endif
os_lib_call((unsigned int *) &libcall_params);
}
// Function to dispatch calls from the ethereum app.
static void dispatch_call(int message, void *parameters) {
if (parameters != NULL) {
switch (message) {
case ETH_PLUGIN_INIT_CONTRACT:
handle_init_contract(parameters);
break;
case ETH_PLUGIN_PROVIDE_PARAMETER:
handle_provide_parameter(parameters);
break;
case ETH_PLUGIN_FINALIZE:
handle_finalize(parameters);
break;
case ETH_PLUGIN_PROVIDE_INFO:
handle_provide_token(parameters);
break;
case ETH_PLUGIN_QUERY_CONTRACT_ID:
handle_query_contract_id(parameters);
break;
case ETH_PLUGIN_QUERY_CONTRACT_UI:
handle_query_contract_ui(parameters);
break;
default:
PRINTF("Unhandled message %d\n", message);
break;
}
} else {
PRINTF("Received null parameters\n");
}
}
// Low-level main for plugins.
__attribute__((section(".boot"))) int main(int arg0) {
// Exit critical section
__asm volatile("cpsie i");
os_boot();
BEGIN_TRY {
TRY {
// Check if plugin is called from the dashboard.
if (!arg0) {
// Called from dashboard, launch Ethereum app
call_app_ethereum();
// Will not get reached.
__builtin_unreachable();
os_sched_exit(-1);
} else {
// Not called from dashboard: called from the ethereum app!
const unsigned int *args = (unsigned int *) arg0;
// If `ETH_PLUGIN_CHECK_PRESENCE` is set, this means the caller is just trying to
// know whether this app exists or not. We can skip `paraswap_plugin_call`.
if (args[0] != ETH_PLUGIN_CHECK_PRESENCE) {
dispatch_call(args[0], (void *) args[1]);
}
}
// Call `os_lib_end`, go back to the ethereum app.
os_lib_end();
// Will not get reached.
__builtin_unreachable();
}
CATCH_OTHER(e) {
PRINTF("Exiting following exception: %d\n", e);
}
FINALLY {
os_lib_end();
}
}
END_TRY;
}

View File

@@ -1,59 +0,0 @@
# ****************************************************************************
# Ledger Ethereum Plugin SDK
# (c) 2023 Ledger SAS.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ****************************************************************************
ifeq ($(BOLOS_SDK),)
$(error Environment variable BOLOS_SDK is not set)
endif
include $(BOLOS_SDK)/Makefile.defines
APPVERSION ?= "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)"
# Application source files
APP_SOURCE_PATH += src ethereum-plugin-sdk
# Application icons following guidelines:
# https://developers.ledger.com/docs/embedded-app/design-requirements/#device-icon
NORMAL_NAME ?= $(shell echo -n "$(APPNAME)" | tr " ." "_" | tr "[:upper:]" "[:lower:]")
ICON_NANOS = icons/nanos_app_$(NORMAL_NAME).gif
ICON_NANOX = icons/nanox_app_$(NORMAL_NAME).gif
ICON_NANOSP = $(ICON_NANOX)
ICON_STAX = icons/stax_app_$(NORMAL_NAME).gif
ifeq ($(TARGET_NAME),TARGET_STAX)
DEFINES += ICONGLYPH=C_stax_$(NORMAL_NAME)_64px
DEFINES += ICONBITMAP=C_stax_$(NORMAL_NAME)_64px_bitmap
endif
CURVE_APP_LOAD_PARAMS = secp256k1
PATH_APP_LOAD_PARAMS ?= "44'/60'"
VARIANT_PARAM = COIN
VARIANT_VALUES ?= $(NORMAL_NAME)
HAVE_APPLICATION_FLAG_LIBRARY = 1
DISABLE_STANDARD_APP_FILES = 1
DISABLE_STANDARD_SNPRINTF = 1
DISABLE_STANDARD_USB = 1
DISABLE_STANDARD_WEBUSB = 1
DISABLE_STANDARD_BAGL_UX_FLOW = 1
DISABLE_DEBUG_LEDGER_ASSERT = 1
DISABLE_DEBUG_THROW = 1
include $(BOLOS_SDK)/Makefile.standard_app

View File

@@ -52,7 +52,7 @@ FetchContent_MakeAvailable(cmocka)
add_compile_definitions(TEST DEBUG=0 SKIP_FOR_CMOCKA)
include_directories(../../src/)
include_directories(../../src_common)
include_directories(../../src_plugin_sdk)
# add cmocka tests
add_executable(test_demo tests/demo.c)

View File

@@ -1,10 +0,0 @@
#!/bin/bash
# Clean the sdk
find ./ethereum-plugin-sdk/ -mindepth 1 -maxdepth 1 ! -name .git -exec rm -r {} \;
# Copy exclusive files
cp -r src_plugin_sdk/* ./ethereum-plugin-sdk/
# Copy common sources
cp -r src_common/* ./ethereum-plugin-sdk/src/