Skip to content

Commit

Permalink
Updated to use the latest plugin SDK
Browse files Browse the repository at this point in the history
  • Loading branch information
apaillier-ledger committed Oct 19, 2023
1 parent 90ccabb commit bc2453b
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 208 deletions.
2 changes: 1 addition & 1 deletion ethereum-plugin-sdk
7 changes: 0 additions & 7 deletions src/boilerplate_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,3 @@ typedef struct context_t {
// Piece of code that will check that the above structure is not bigger than 5 * 32. Do not remove
// this check.
_Static_assert(sizeof(context_t) <= 5 * 32, "Structure of parameters too big.");

void handle_provide_parameter(void *parameters);
void handle_query_contract_ui(void *parameters);
void handle_init_contract(void *parameters);
void handle_finalize(void *parameters);
void handle_provide_token(void *parameters);
void handle_query_contract_id(void *parameters);
32 changes: 32 additions & 0 deletions src/contract.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*******************************************************************************
* Plugin Boilerplate
* (c) 2023 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 "boilerplate_plugin.h"

// List of selectors supported by this plugin.
// EDIT THIS: Adapt the variable names and change the `0x` values to match your selectors.
static const uint32_t SWAP_EXACT_ETH_FOR_TOKENS_SELECTOR = 0x7ff36ab5;
static const uint32_t BOILERPLATE_DUMMY_SELECTOR_2 = 0x13374242;

// Array of all the different boilerplate selectors. Make sure this follows the same order as the
// enum defined in `boilerplate_plugin.h`
// EDIT THIS: Use the names of the array declared above.
const uint32_t BOILERPLATE_SELECTORS[NUM_SELECTORS] = {
SWAP_EXACT_ETH_FOR_TOKENS_SELECTOR,
BOILERPLATE_DUMMY_SELECTOR_2,
};
28 changes: 12 additions & 16 deletions src/handle_init_contract.c
Original file line number Diff line number Diff line change
@@ -1,20 +1,8 @@
#include "boilerplate_plugin.h"

static int find_selector(uint32_t selector, const uint32_t *selectors, size_t n, selector_t *out) {
for (selector_t i = 0; i < n; i++) {
if (selector == selectors[i]) {
*out = i;
return 0;
}
}
return -1;
}
#include "utils.h"

// Called once to init.
void handle_init_contract(void *parameters) {
// Cast the msg to the type of structure we expect (here, ethPluginInitContract_t).
ethPluginInitContract_t *msg = (ethPluginInitContract_t *) parameters;

void handle_init_contract(ethPluginInitContract_t *msg) {
// Make sure we are running a compatible version.
if (msg->interfaceVersion != ETH_PLUGIN_INTERFACE_VERSION_LATEST) {
// If not the case, return the `UNAVAILABLE` status.
Expand All @@ -35,11 +23,19 @@ void handle_init_contract(void *parameters) {
// Initialize the context (to 0).
memset(context, 0, sizeof(*context));

uint32_t selector = U4BE(msg->selector, 0);
if (find_selector(selector, BOILERPLATE_SELECTORS, NUM_SELECTORS, &context->selectorIndex)) {
size_t index;
if (!find_selector(U4BE(msg->selector, 0), BOILERPLATE_SELECTORS, NUM_SELECTORS, &index)) {
PRINTF("Error: selector not found!\n");
msg->result = ETH_PLUGIN_RESULT_UNAVAILABLE;
return;
}
context->selectorIndex = index;
// check for overflow
if ((size_t) context->selectorIndex != index) {
PRINTF("Error: overflow detected on selector index!\n");
msg->result = ETH_PLUGIN_RESULT_ERROR;
return;
}

// Set `next_param` to be the first field we expect to parse.
// EDIT THIS: Adapt the `cases`, and set the `next_param` to be the first parameter you expect
Expand Down
5 changes: 2 additions & 3 deletions src/handle_provide_parameter.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ static void handle_swap_exact_eth_for_tokens(ethPluginProvideParameter_t *msg, c
}
}

void handle_provide_parameter(void *parameters) {
ethPluginProvideParameter_t *msg = (ethPluginProvideParameter_t *) parameters;
void handle_provide_parameter(ethPluginProvideParameter_t *msg) {
context_t *context = (context_t *) msg->pluginContext;
// We use `%.*H`: it's a utility function to print bytes. You first give
// the number of bytes you wish to print (in this case, `PARAMETER_LENGTH`) and then
Expand All @@ -66,4 +65,4 @@ void handle_provide_parameter(void *parameters) {
msg->result = ETH_PLUGIN_RESULT_ERROR;
break;
}
}
}
5 changes: 2 additions & 3 deletions src/handle_provide_token.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
// EDIT THIS: Adapt this function to your needs! Remember, the information for tokens are held in
// `msg->token1` and `msg->token2`. If those pointers are `NULL`, this means the ethereum app didn't
// find any info regarding the requested tokens!
void handle_provide_token(void *parameters) {
ethPluginProvideInfo_t *msg = (ethPluginProvideInfo_t *) parameters;
void handle_provide_token(ethPluginProvideInfo_t *msg) {
context_t *context = (context_t *) msg->pluginContext;

if (msg->item1) {
Expand All @@ -26,4 +25,4 @@ void handle_provide_token(void *parameters) {
// msg->additionalScreens = 1;
}
msg->result = ETH_PLUGIN_RESULT_OK;
}
}
5 changes: 2 additions & 3 deletions src/handle_query_contract_id.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#include "boilerplate_plugin.h"

// Sets the first screen to display.
void handle_query_contract_id(void *parameters) {
ethQueryContractID_t *msg = (ethQueryContractID_t *) parameters;
void handle_query_contract_id(ethQueryContractID_t *msg) {
const context_t *context = (const context_t *) msg->pluginContext;
// msg->name will be the upper sentence displayed on the screen.
// msg->version will be the lower sentence displayed on the screen.
Expand All @@ -18,4 +17,4 @@ void handle_query_contract_id(void *parameters) {
PRINTF("Selector index: %d not supported\n", context->selectorIndex);
msg->result = ETH_PLUGIN_RESULT_ERROR;
}
}
}
42 changes: 22 additions & 20 deletions src/handle_query_contract_ui.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,25 @@

// Set UI for the "Send" screen.
// EDIT THIS: Adapt / remove this function to your needs.
static void set_send_ui(ethQueryContractUI_t *msg) {
static bool set_send_ui(ethQueryContractUI_t *msg) {
strlcpy(msg->title, "Send", msg->titleLength);

const uint8_t *eth_amount = msg->pluginSharedRO->txContent->value.value;
uint8_t eth_amount_size = msg->pluginSharedRO->txContent->value.length;

// Converts the uint256 number located in `eth_amount` to its string representation and
// copies this to `msg->msg`.
amountToString(eth_amount, eth_amount_size, WEI_TO_ETHER, "ETH", msg->msg, msg->msgLength);
return amountToString(eth_amount,
eth_amount_size,
WEI_TO_ETHER,
"ETH",
msg->msg,
msg->msgLength);
}

// Set UI for "Receive" screen.
// EDIT THIS: Adapt / remove this function to your needs.
static void set_receive_ui(ethQueryContractUI_t *msg, const context_t *context) {
static bool set_receive_ui(ethQueryContractUI_t *msg, const context_t *context) {
strlcpy(msg->title, "Receive Min.", msg->titleLength);

uint8_t decimals = context->decimals;
Expand All @@ -30,17 +35,17 @@ static void set_receive_ui(ethQueryContractUI_t *msg, const context_t *context)
ticker = msg->network_ticker;
}

amountToString(context->amount_received,
sizeof(context->amount_received),
decimals,
ticker,
msg->msg,
msg->msgLength);
return amountToString(context->amount_received,
sizeof(context->amount_received),
decimals,
ticker,
msg->msg,
msg->msgLength);
}

// Set UI for "Beneficiary" screen.
// EDIT THIS: Adapt / remove this function to your needs.
static void set_beneficiary_ui(ethQueryContractUI_t *msg, context_t *context) {
static bool set_beneficiary_ui(ethQueryContractUI_t *msg, context_t *context) {
strlcpy(msg->title, "Beneficiary", msg->titleLength);

// Prefix the address with `0x`.
Expand All @@ -53,16 +58,16 @@ static void set_beneficiary_ui(ethQueryContractUI_t *msg, context_t *context) {

// Get the string representation of the address stored in `context->beneficiary`. Put it in
// `msg->msg`.
getEthAddressStringFromBinary(
return getEthAddressStringFromBinary(
context->beneficiary,
msg->msg + 2, // +2 here because we've already prefixed with '0x'.
msg->pluginSharedRW->sha3,
chainid);
}

void handle_query_contract_ui(void *parameters) {
ethQueryContractUI_t *msg = (ethQueryContractUI_t *) parameters;
void handle_query_contract_ui(ethQueryContractUI_t *msg) {
context_t *context = (context_t *) msg->pluginContext;
bool ret = false;

// msg->title is the upper line displayed on the device.
// msg->msg is the lower line displayed on the device.
Expand All @@ -71,23 +76,20 @@ void handle_query_contract_ui(void *parameters) {
memset(msg->title, 0, msg->titleLength);
memset(msg->msg, 0, msg->msgLength);

msg->result = ETH_PLUGIN_RESULT_OK;

// EDIT THIS: Adapt the cases for the screens you'd like to display.
switch (msg->screenIndex) {
case 0:
set_send_ui(msg);
ret = set_send_ui(msg);
break;
case 1:
set_receive_ui(msg, context);
ret = set_receive_ui(msg, context);
break;
case 2:
set_beneficiary_ui(msg, context);
ret = set_beneficiary_ui(msg, context);
break;
// Keep this
default:
PRINTF("Received an invalid screenIndex\n");
msg->result = ETH_PLUGIN_RESULT_ERROR;
return;
}
msg->result = ret ? ETH_PLUGIN_RESULT_OK : ETH_PLUGIN_RESULT_ERROR;
}
Loading

0 comments on commit bc2453b

Please sign in to comment.