Skip to content

Commit c0b85d2

Browse files
authored
Merge pull request #267 from LedgerHQ/develop_1.9.17
Add Non-Fungible Token (ERC 721 & 1155) support
2 parents cf4640b + 7d9d0fb commit c0b85d2

File tree

117 files changed

+2612
-397
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

117 files changed

+2612
-397
lines changed

CHANGELOG.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,40 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

8+
## [1.9.17](https://github.com/ledgerhq/app-ethereum/compare/1.9.16...1.9.17) - 2022-01-14
9+
10+
### Added
11+
12+
- Support for Non-Fungible Tokens (ERC-721 & ERC-1155)
13+
14+
## [1.9.16](https://github.com/ledgerhq/app-ethereum/compare/1.9.14...1.9.16) - 2022-01-13
15+
16+
### Added
17+
18+
- Shyft variant
19+
20+
## [1.9.14](https://github.com/ledgerhq/app-ethereum/compare/1.9.13...1.9.14) - 2021-11-30
21+
22+
### Added
23+
24+
- Added Moonriver BIP44 1285
25+
26+
### Fixed
27+
28+
- Fixed stark order signature on LNS
29+
30+
## [1.9.13](https://github.com/ledgerhq/app-ethereum/compare/1.9.12...1.9.13) - 2021-11-17
31+
32+
### Changed
33+
34+
- Small improvement in app size
35+
836
## [1.9.12](https://github.com/ledgerhq/app-ethereum/compare/1.9.11...1.9.12) - 2021-11-12
937

1038
### Fixed
1139

1240
- Fixed stark order signature on LNX
1341

14-
1542
## [1.9.11](https://github.com/ledgerhq/app-ethereum/compare/1.9.10...1.9.11) - 2021-10-12
1643

1744
### Added

Makefile

100755100644
Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ APP_LOAD_PARAMS += --path "1517992542'/1101353413'"
3030

3131
APPVERSION_M=1
3232
APPVERSION_N=9
33-
APPVERSION_P=16
33+
APPVERSION_P=17
3434
APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)
3535
APP_LOAD_FLAGS= --appFlags 0x240 --dep Ethereum:$(APPVERSION)
3636

@@ -248,10 +248,10 @@ APP_LOAD_PARAMS += $(APP_LOAD_FLAGS) --path "44'/1'"
248248
DEFINES += $(DEFINES_LIB)
249249

250250
#prepare hsm generation
251-
ifeq ($(TARGET_NAME), TARGET_NANOX)
252-
ICONNAME=icons/nanox_app_$(CHAIN).gif
253-
else
251+
ifeq ($(TARGET_NAME),TARGET_NANOS)
254252
ICONNAME=icons/nanos_app_$(CHAIN).gif
253+
else
254+
ICONNAME=icons/nanox_app_$(CHAIN).gif
255255
endif
256256

257257
################
@@ -283,19 +283,21 @@ DEFINES += HAVE_UX_FLOW
283283
DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=0 WEBUSB_URL=""
284284

285285
ifeq ($(TARGET_NAME),TARGET_NANOX)
286-
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300
287286
DEFINES += HAVE_BLE BLE_COMMAND_TIMEOUT_MS=2000
288287
DEFINES += HAVE_BLE_APDU # basic ledger apdu transport over BLE
288+
endif
289289

290+
ifeq ($(TARGET_NAME),TARGET_NANOS)
291+
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=72
292+
DEFINES += HAVE_WALLET_ID_SDK
293+
else
294+
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300
290295
DEFINES += HAVE_GLO096
291296
DEFINES += HAVE_BAGL BAGL_WIDTH=128 BAGL_HEIGHT=64
292297
DEFINES += HAVE_BAGL_ELLIPSIS # long label truncation feature
293298
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX
294299
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX
295300
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX
296-
else
297-
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=72
298-
DEFINES += HAVE_WALLET_ID_SDK
299301
endif
300302

301303
# Enables direct data signing without having to specify it in the settings. Useful when testing with speculos.
@@ -304,21 +306,31 @@ ifneq ($(ALLOW_DATA),0)
304306
DEFINES += HAVE_ALLOW_DATA
305307
endif
306308

307-
# Bypass the signature verification for setExternalPlugin and provideERC20TokenInfo calls
309+
# Bypass the signature verification for setExternalPlugin, setPlugin, provideERC20TokenInfo and provideNFTInfo calls
308310
BYPASS_SIGNATURES:=0
309311
ifneq ($(BYPASS_SIGNATURES),0)
310312
DEFINES += HAVE_BYPASS_SIGNATURES
311313
endif
312314

315+
# NFTs
316+
ifneq ($(TARGET_NAME),TARGET_NANOS)
317+
DEFINES += HAVE_NFT_SUPPORT
318+
# Enable the NFT testing key
319+
NFT_TESTING_KEY:=0
320+
ifneq ($(NFT_TESTING_KEY),0)
321+
DEFINES += HAVE_NFT_TESTING_KEY
322+
endif
323+
endif
324+
313325

314326
# Enabling debug PRINTF
315327
DEBUG:=0
316328
ifneq ($(DEBUG),0)
317329
DEFINES += HAVE_STACK_OVERFLOW_CHECK
318-
ifeq ($(TARGET_NAME),TARGET_NANOX)
319-
DEFINES += HAVE_PRINTF PRINTF=mcu_usb_printf
320-
else
330+
ifeq ($(TARGET_NAME),TARGET_NANOS)
321331
DEFINES += HAVE_PRINTF PRINTF=screen_printf
332+
else
333+
DEFINES += HAVE_PRINTF PRINTF=mcu_usb_printf
322334
endif
323335
else
324336
DEFINES += PRINTF\(...\)=

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Ledger Blue is not maintained anymore, but the app can still be compiled for thi
44

55
This app follows the specification available in the `doc/` folder.
66

7-
To compile it and load it on a device, please check out our [developer portal](https://developers.ledger.com/docs/NA/start_here/).
7+
To compile it and load it on a device, please check out our [developer portal](https://developers.ledger.com/docs/nano-app/introduction/).
88

99
# Plugins
1010

@@ -20,7 +20,7 @@ First [install yarn](https://classic.yarnpkg.com/en/docs/install/#debian-stable)
2020
Open `tests/build_local_test_elfs.sh` and add your BOLOS SDKs path to `NANOS_SDK` and `NANOX_SDK`.
2121
This helper script will build the applications required by the test suite and move them at the right place.
2222
```
23-
cd test
23+
cd tests
2424
./build_local_test_elfs.sh
2525
```
2626
Then you can install the project by simply running:

doc/ethapp.asc

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ Application version 1.5.0 - 25th of September 2020
2323
## 1.7.6
2424
- Add SET EXTERNAL PLUGIN
2525

26+
## 1.9.13
27+
- Add SET PLUGIN
28+
2629
## About
2730

2831
This application describes the APDU messages interface to communicate with the Ethereum application.
@@ -240,6 +243,49 @@ signed by the following secp256k1 public key 0482bbf2f34f367b2e5bc21847b6566f21f
240243

241244
None
242245

246+
### PROVIDE NFT INFORMATION
247+
248+
#### Description
249+
250+
This commands provides a trusted description of an NFT to associate a contract address with a collectionName.
251+
252+
It shall be run immediately before performing a transaction involving a contract calling this contract address to display the proper nft information to the user if necessary, as marked in GET APP CONFIGURATION flags.
253+
254+
The signature is computed on
255+
256+
type || version || len(collectionName) || collectionName || address || chainId || keyId || algorithmId || len(signature) || signature
257+
258+
#### Coding
259+
260+
'Command'
261+
262+
[width="80%"]
263+
|==============================================================================================================================
264+
| *CLA* | *INS* | *P1* | *P2* | *Lc* | *Le*
265+
| E0 | 14 | 00 | 00 | variable | 00
266+
|==============================================================================================================================
267+
268+
'Input data'
269+
270+
[width="80%"]
271+
|==============================================================================================================================
272+
| *Description* | *Length*
273+
| Type | 1
274+
| Version | 1
275+
| Collection Name Length | 1
276+
| Collection Name | variable
277+
| Address | 20
278+
| Chain ID | 8
279+
| KeyID | 1
280+
| Algorithm ID | 1
281+
| Signature Length | 1
282+
| Signature | variable
283+
|==============================================================================================================================
284+
285+
'Output data'
286+
287+
None
288+
243289

244290
### SET EXTERNAL PLUGIN
245291

@@ -283,6 +329,56 @@ signed by the following secp256k1 public key 0482bbf2f34f367b2e5bc21847b6566f21f
283329

284330
None
285331

332+
### SET PLUGIN
333+
334+
#### Description
335+
336+
This commands provides the name of a trusted binding of a plugin with a contract address and a supported method selector. This plugin will be called to interpret contract data in the following transaction signing command.
337+
338+
It can be used to set both internal and external plugins.
339+
340+
It shall be run immediately before performing a transaction involving a contract supported by this plugin to display the proper information to the user if necessary.
341+
342+
The function returns an error sw (0x6984) if the plugin requested is not installed on the device, 0x9000 otherwise.
343+
344+
The plugin names `ERC20`, `ERC721` and `ERC1155` are reserved. Additional plugin names might be added to this list in the future.
345+
346+
The signature is computed on
347+
348+
type || version || len(pluginName) || pluginName || address || selector || chainId || keyId || algorithmId || len(signature) || signature
349+
350+
#### Coding
351+
352+
'Command'
353+
354+
[width="80%"]
355+
|==============================================================================================================================
356+
| *CLA* | *INS* | *P1* | *P2* | *Lc* | *Le*
357+
| E0 | 16 | 00 | 00 | variable | 00
358+
|==============================================================================================================================
359+
360+
'Input data'
361+
362+
[width="80%"]
363+
|==============================================================================================================================
364+
| *Description* | *Length*
365+
| Type | 1
366+
| Version | 1
367+
| Plugin Name Length | 1
368+
| Plugin Name | variable
369+
| Address | 20
370+
| Selector | 4
371+
| Chain ID | 8
372+
| KeyID | 1
373+
| Algorithm ID | 1
374+
| Signature Length | 1
375+
| Signature | variable
376+
|==============================================================================================================================
377+
378+
'Output data'
379+
380+
None
381+
286382
### GET APP CONFIGURATION
287383

288384
#### Description

doc/ethapp_plugins.asc

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ typedef struct ethPluginFinalize_t {
145145
ethPluginSharedRO_t *pluginSharedRO;
146146
uint8_t *pluginContext;
147147
148-
uint8_t *tokenLookup1; // set by the plugin if a token should be looked up
149-
uint8_t *tokenLookup2;
148+
uint8_t *itemLookup1; // set by the plugin if a token or an nft should be looked up
149+
uint8_t *itemLookup2;
150150
151151
uint8_t *amount; // set an uint256 pointer if uiType is UI_AMOUNT_ADDRESS
152152
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
@@ -161,8 +161,8 @@ typedef struct ethPluginFinalize_t {
161161

162162
This message is sent when the data field has been fully parsed. The following specific fields can be filled by the plugin :
163163

164-
* tokenLookup1 : the pointer shall be set to a 20 bytes address to look up an ERC 20 token descriptor if needed by the plugin
165-
* tokenLookup2 : the pointer shall be set to a 20 bytes address to look up an ERC 20 token descriptor if needed by the plugin
164+
* itemLookup1 : the pointer shall be set to a 20 bytes address to look up an ERC20 token or NFT if needed by the plugin
165+
* itemLookup2 : the pointer shall be set to a 20 bytes address to look up an ERC20 token or NFT if needed by the plugin
166166
* uiType : set to either ETH_UI_TYPE_AMOUNT_ADDRESS for an amount/address UI or ETH_UI_TYPE_GENERIC for a generic UI
167167

168168
The following specific fields are filled by the plugin when returning an amount/address UI :
@@ -179,32 +179,32 @@ The following return codes are expected, any other will abort the signing proces
179179
* ETH_PLUGIN_RESULT_OK : if the plugin can be successfully initialized
180180
* ETH_PLUGIN_RESULT_FALLBACK : if the signing logic should fallback to the generic one
181181

182-
### ETH_PLUGIN_PROVIDE_TOKEN
182+
### ETH_PLUGIN_PROVIDE_INFO
183183

184184
[source,C]
185185
----
186186
187-
typedef struct ethPluginProvideToken_t {
187+
typedef struct ethPluginProvideInfo_t {
188188
189189
ethPluginSharedRW_t *pluginSharedRW;
190190
ethPluginSharedRO_t *pluginSharedRO;
191191
uint8_t *pluginContext;
192192
193-
tokenDefinition_t *token1; // set by the ETH application, to be saved by the plugin
194-
tokenDefinition_t *token2;
193+
union extraInfo *item1; // set by the ETH application, to be saved by the plugin
194+
union extraInfo *item2;
195195
196-
uint8_t additionalScreens; // Used by the plugin if it needs to display additional screens based on the information received from the token definitions.
196+
uint8_t additionalScreens; // Used by the plugin if it needs to display additional screens based on the information received.
197197
198198
uint8_t result;
199199
200-
} ethPluginProvideToken_t;
200+
} ethPluginProvideInfo_t;
201201
202202
----
203203

204-
This message is sent if a token lookup was required by the plugin when parsing a finalize message. The following specific fields are filled when the plugin is called :
204+
This message is sent if an information lookup was required by the plugin when parsing a finalize message. The following specific fields are filled when the plugin is called :
205205

206-
* token1 : pointer to a token definition matching tokenLookup1, or NULL if not found
207-
* token2 : pointer to a token definition matching tokenLookup2, or NULL if not found or not requested
206+
* item1 : pointer to an union matching itemLookup1, or NULL if not found
207+
* item2 : pointer to an union matching itemLookup2, or NULL if not found
208208

209209
The following return codes are expected, any other will abort the signing process :
210210

@@ -233,7 +233,7 @@ typedef struct ethQueryContractID_t {
233233
234234
----
235235

236-
This message is sent after the parsing finalization and token lookups if requested if a generic UI is used. The following specific fields are provided when the plugin is called :
236+
This message is sent after the parsing finalization and information lookups if requested if a generic UI is used. The following specific fields are provided when the plugin is called :
237237

238238
* name : pointer to the name of the plugin, to be filled by the plugin
239239
* nameLength : maximum name length
@@ -253,6 +253,9 @@ typedef struct ethQueryContractUI_t {
253253
254254
ethPluginSharedRW_t *pluginSharedRW;
255255
ethPluginSharedRO_t *pluginSharedRO;
256+
union extraInfo_t *item1;
257+
union extraInfo_t *item2;
258+
char network_ticker[MAX_TICKER_LEN];
256259
uint8_t *pluginContext;
257260
uint8_t screenIndex;
258261
char *title;
@@ -268,6 +271,10 @@ typedef struct ethQueryContractUI_t {
268271

269272
This message is sent when a plugin screen shall be displayed if a generic UI is used. The following specific fields are provided when the plugin is called :
270273

274+
275+
* item1 : pointer to token / nft information
276+
* item2 : pointer to token / nft information
277+
* network_ticker : string that holds the network ticker
271278
* screenIndex : index of the screen to display, starting from 0
272279
* title : pointer to the first line of the screen, to be filled by the plugin
273280
* titleLength : maximum title length

src/apdu_constants.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#define INS_GET_ETH2_PUBLIC_KEY 0x0E
1616
#define INS_SET_ETH2_WITHDRAWAL_INDEX 0x10
1717
#define INS_SET_EXTERNAL_PLUGIN 0x12
18+
#define INS_PROVIDE_NFT_INFORMATION 0x14
19+
#define INS_SET_PLUGIN 0x16
1820
#define P1_CONFIRM 0x01
1921
#define P1_NON_CONFIRM 0x00
2022
#define P2_NO_CHAINCODE 0x00
@@ -64,6 +66,12 @@ void handleProvideErc20TokenInformation(uint8_t p1,
6466
uint16_t dataLength,
6567
unsigned int *flags,
6668
unsigned int *tx);
69+
void handleProvideNFTInformation(uint8_t p1,
70+
uint8_t p2,
71+
uint8_t *dataBuffer,
72+
uint16_t dataLength,
73+
unsigned int *flags,
74+
unsigned int *tx);
6775
void handleSign(uint8_t p1,
6876
uint8_t p2,
6977
uint8_t *dataBuffer,
@@ -96,6 +104,13 @@ void handleSetExternalPlugin(uint8_t p1,
96104
unsigned int *flags,
97105
unsigned int *tx);
98106

107+
void handleSetPlugin(uint8_t p1,
108+
uint8_t p2,
109+
uint8_t *workBuffer,
110+
uint16_t dataLength,
111+
unsigned int *flags,
112+
unsigned int *tx);
113+
99114
#ifdef HAVE_ETH2
100115

101116
void handleGetEth2PublicKey(uint8_t p1,

0 commit comments

Comments
 (0)