Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve plugin interface file #488

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 85 additions & 45 deletions src/eth_plugin_interface.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// clang-format off

#ifndef _ETH_PLUGIN_INTERFACE_H_
#define _ETH_PLUGIN_INTERFACE_H_

Expand All @@ -7,30 +9,43 @@
#include "tokens.h"
#include "shared_context.h"

// Interface version. To be updated everytime we introduce breaking changes to the plugin interface.
typedef enum {
/*************************************************************************************************
* Comments provided in this file are quick reminders on the usage of the plugin interface *
* Reading the real plugin documentation is GREATLY recommended. *
tdejoigny-ledger marked this conversation as resolved.
Show resolved Hide resolved
* 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_LATEST = 6,
} eth_plugin_interface_version_t;

typedef enum {

// 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,
ETH_PLUGIN_CHECK_PRESENCE = 0x01FF

// Special request: the Ethereum app is checking if we are installed on the device
ETH_PLUGIN_CHECK_PRESENCE = 0x01FF,
} eth_plugin_msg_t;

typedef enum {
// Unsuccesful return values

// 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
Expand All @@ -39,38 +54,58 @@ typedef enum {
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_FALLBACK = 0x06,
} eth_plugin_result_t;

typedef enum {

// 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,
ETH_UI_TYPE_GENERIC = 0x02

// 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;

typedef void (*PluginCall)(int, void *);

// Shared objects, read-write

typedef struct ethPluginSharedRW_t {
// Scratch objects and utilities available to the plugin READ-WRITE
typedef struct ethPluginSharedRW_s {
cx_sha3_t *sha3;

} ethPluginSharedRW_t;

// Shared objects, read-only

typedef struct ethPluginSharedRO_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 meaningfull 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_t {
uint8_t interfaceVersion;
uint8_t result;
typedef struct ethPluginInitContract_s {
eth_plugin_interface_version_t interfaceVersion;
eth_plugin_result_t result;

// in
ethPluginSharedRW_t *pluginSharedRW;
Expand All @@ -83,26 +118,30 @@ typedef struct ethPluginInitContract_t {
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_t {
typedef struct ethPluginProvideParameter_s {
ethPluginSharedRW_t *pluginSharedRW;
ethPluginSharedRO_t *pluginSharedRO;
uint8_t *pluginContext;
uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE
const uint8_t *parameter; // 32 bytes parameter
uint32_t parameterOffset;

uint8_t result;
eth_plugin_result_t result;

} ethPluginProvideParameter_t;
// void handle_provide_parameter(ethPluginProvideParameter_t *parameters);


// Finalize

typedef struct ethPluginFinalize_t {
typedef struct ethPluginFinalize_s {
ethPluginSharedRW_t *pluginSharedRW;
ethPluginSharedRO_t *pluginSharedRO;
uint8_t *pluginContext;
uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE

uint8_t *tokenLookup1; // set by the plugin if a token should be looked up
uint8_t *tokenLookup2;
Expand All @@ -111,73 +150,74 @@ typedef struct ethPluginFinalize_t {
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

uint8_t uiType;
eth_ui_type_t uiType;
uint8_t numScreens; // ignored if uiType is UI_AMOUNT_ADDRESS
uint8_t result;
eth_plugin_result_t result;

} ethPluginFinalize_t;
// void handle_finalize(ethPluginFinalize_t *parameters);

// If uiType is UI_AMOUNT_ADDRESS, the amount and address provided by the plugin will be used
// If tokenLookup1 is set, the amount is provided for this token

// if uiType is UI_TYPE_GENERIC, 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

// Provide token

typedef struct ethPluginProvideInfo_t {
typedef struct ethPluginProvideInfo_s {
ethPluginSharedRW_t *pluginSharedRW;
ethPluginSharedRO_t *pluginSharedRO;
uint8_t *pluginContext;
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.

uint8_t result;
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_t {
typedef struct ethQueryContractID_s {
ethPluginSharedRW_t *pluginSharedRW;
ethPluginSharedRO_t *pluginSharedRO;
uint8_t *pluginContext;
uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE

char *name;
size_t nameLength;
char *version;
size_t versionLength;

uint8_t result;
eth_plugin_result_t result;

} ethQueryContractID_t;
// void handle_query_contract_id(ethQueryContractID_t *parameters);


// Query Contract UI

typedef struct ethQueryContractUI_t {
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;
uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE
uint8_t screenIndex;

char *title;
size_t titleLength;
char *msg;
size_t msgLength;

uint8_t result;
eth_plugin_result_t result;

} ethQueryContractUI_t;
// void handle_query_contract_ui(ethQueryContractUI_t *parameters);

#endif // _ETH_PLUGIN_INTERFACE_H_

// clang-format on
1 change: 1 addition & 0 deletions src/eth_plugin_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ bool U2BE_from_parameter(const uint8_t* parameter, uint16_t* value);
bool U4BE_from_parameter(const uint8_t* parameter, uint32_t* value);

typedef bool (*PluginAvailableCheck)(void);
typedef void (*PluginCall)(int, void *);
fbeutin-ledger marked this conversation as resolved.
Show resolved Hide resolved

typedef struct internalEthPlugin_t {
PluginAvailableCheck availableCheck;
Expand Down