Merge pull request #466 from LedgerHQ/feat/apa/nft_on_other_chains

NFT on other chains
This commit is contained in:
apaillier-ledger
2023-09-07 17:03:13 +02:00
committed by GitHub
588 changed files with 703 additions and 96 deletions

View File

@@ -114,9 +114,9 @@ jobs:
- name: Build testing binaries
run: |
mkdir tests/speculos/elfs
make clean && make -j DEBUG=1 NFT_TESTING_KEY=1 BOLOS_SDK=$NANOS_SDK && mv bin/app.elf tests/speculos/elfs/nanos.elf
make clean && make -j DEBUG=1 NFT_TESTING_KEY=1 BOLOS_SDK=$NANOX_SDK && mv bin/app.elf tests/speculos/elfs/nanox.elf
make clean && make -j DEBUG=1 NFT_TESTING_KEY=1 BOLOS_SDK=$NANOSP_SDK && mv bin/app.elf tests/speculos/elfs/nanosp.elf
make clean && make -j DEBUG=1 NFT_STAGING_KEY=1 BOLOS_SDK=$NANOS_SDK && mv bin/app.elf tests/speculos/elfs/nanos.elf
make clean && make -j DEBUG=1 NFT_STAGING_KEY=1 BOLOS_SDK=$NANOX_SDK && mv bin/app.elf tests/speculos/elfs/nanox.elf
make clean && make -j DEBUG=1 NFT_STAGING_KEY=1 BOLOS_SDK=$NANOSP_SDK && mv bin/app.elf tests/speculos/elfs/nanosp.elf
- name: Upload app binaries
uses: actions/upload-artifact@v3
@@ -171,7 +171,7 @@ jobs:
uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_build.yml@v1
with:
upload_app_binaries_artifact: "ragger_elfs"
flags: "DEBUG=1 CAL_CI_KEY=1 DOMAIN_NAME_TEST_KEY=1"
flags: "DEBUG=1 CAL_TEST_KEY=1 DOMAIN_NAME_TEST_KEY=1 SET_PLUGIN_TEST_KEY=1 NFT_TEST_KEY=1"
jobs-ragger-tests:
name: Run Ragger tests

View File

@@ -136,25 +136,40 @@ endif
endif
# Enables direct data signing without having to specify it in the settings. Useful when testing with speculos.
ALLOW_DATA:=0
ALLOW_DATA?=0
ifneq ($(ALLOW_DATA),0)
DEFINES += HAVE_ALLOW_DATA
endif
# Bypass the signature verification for setExternalPlugin, setPlugin, provideERC20TokenInfo and provideNFTInfo calls
BYPASS_SIGNATURES:=0
BYPASS_SIGNATURES?=0
ifneq ($(BYPASS_SIGNATURES),0)
DEFINES += HAVE_BYPASS_SIGNATURES
endif
# Enable the SET_PLUGIN test key
SET_PLUGIN_TEST_KEY?=0
ifneq ($(SET_PLUGIN_TEST_KEY),0)
DEFINES += HAVE_SET_PLUGIN_TEST_KEY
endif
# NFTs
ifneq ($(TARGET_NAME),TARGET_NANOS)
DEFINES += HAVE_NFT_SUPPORT
# Enable the NFT testing key
NFT_TESTING_KEY:=0
ifneq ($(NFT_TESTING_KEY),0)
DEFINES += HAVE_NFT_TESTING_KEY
DEFINES += HAVE_NFT_SUPPORT
NFT_TEST_KEY?=0
ifneq ($(NFT_TEST_KEY),0)
DEFINES += HAVE_NFT_TEST_KEY
endif
NFT_STAGING_KEY?=0
ifneq ($(NFT_STAGING_KEY),0)
# Key used by the staging backend
DEFINES += HAVE_NFT_STAGING_KEY
endif
endif
ifneq (,$(filter $(DEFINES),HAVE_NFT_TEST_KEY))
ifneq (, $(filter $(DEFINES),HAVE_NFT_STAGING_KEY))
$(error Multiple alternative NFT keys set at once)
endif
endif
# Dynamic memory allocator
@@ -168,19 +183,25 @@ DEFINES += HAVE_EIP712_FULL_SUPPORT
endif
# CryptoAssetsList key
CAL_TEST_KEY:=0
CAL_CI_KEY:=0
CAL_TEST_KEY?=0
ifneq ($(CAL_TEST_KEY),0)
DEFINES += HAVE_CAL_TEST_KEY
DEFINES += HAVE_CAL_TEST_KEY
endif
ifneq ($(CAL_CI_KEY),0)
DEFINES += HAVE_CAL_CI_KEY
CAL_STAGING_KEY?=0
ifneq ($(CAL_STAGING_KEY),0)
# Key used by the staging CAL
DEFINES += HAVE_CAL_STAGING_KEY
endif
ifneq (,$(filter $(DEFINES),HAVE_CAL_TEST_KEY))
ifneq (, $(filter $(DEFINES),HAVE_CAL_STAGING_KEY))
$(error Multiple alternative CAL keys set at once)
endif
endif
# ENS
ifneq ($(TARGET_NAME),TARGET_NANOS)
DEFINES += HAVE_DOMAIN_NAME
DOMAIN_NAME_TEST_KEY:=0
DOMAIN_NAME_TEST_KEY?=0
ifneq ($(DOMAIN_NAME_TEST_KEY),0)
DEFINES += HAVE_DOMAIN_NAME_TEST_KEY
endif

View File

@@ -29,6 +29,7 @@ requires-python = ">=3.7"
dependencies = [
"ragger[speculos]",
"simple-rlp",
"pysha3",
]
[tools.setuptools]

View File

@@ -11,7 +11,14 @@ from .tlv import format_tlv
WEI_IN_ETH = 1e+18
GWEI_IN_ETH = 1e+9
class TxData:
selector: bytes
parameters: list[bytes]
def __init__(self, selector: bytes, params: list[bytes]):
self.selector = selector
self.parameters = params
class StatusWord(IntEnum):
OK = 0x9000
@@ -96,31 +103,79 @@ class EthAppClient:
def eip712_filtering_show_field(self, name: str, sig: bytes):
return self._send(self._cmd_builder.eip712_filtering_show_field(name, sig))
def send_fund(self,
bip32_path: str,
nonce: int,
gas_price: int,
gas_limit: int,
to: bytes,
amount: float,
chain_id: int):
data: List[Union[int, bytes]] = list()
data.append(nonce)
data.append(gas_price)
data.append(gas_limit)
data.append(to)
data.append(int(amount * WEI_IN_ETH))
data.append(bytes())
data.append(chain_id)
data.append(bytes())
data.append(bytes())
chunks = self._cmd_builder.sign(bip32_path, rlp.encode(data))
def _sign(self, bip32_path: str, raw_tx: bytes):
chunks = self._cmd_builder.sign(bip32_path, raw_tx)
for chunk in chunks[:-1]:
with self._send(chunk):
pass
return self._send(chunks[-1])
def _data_to_payload(self, data: TxData) -> bytes:
payload = bytearray(data.selector)
for param in data.parameters:
payload += param.rjust(32, b'\x00')
return payload
def _sign_common(self,
tx: list,
gas_price: float,
gas_limit: int,
destination: bytes,
amount: float,
data: TxData):
tx.append(int(gas_price * GWEI_IN_ETH))
tx.append(gas_limit)
tx.append(destination)
if amount > 0:
tx.append(int(amount * WEI_IN_ETH))
else:
tx.append(bytes())
if data is not None:
tx.append(self._data_to_payload(data))
else:
tx.append(bytes())
return tx
def sign_legacy(self,
bip32_path: str,
nonce: int,
gas_price: float,
gas_limit: int,
destination: bytes,
amount: float,
chain_id: int,
data: TxData = None):
tx = list()
tx.append(nonce)
tx = self._sign_common(tx, gas_price, gas_limit, destination, amount, data)
tx.append(chain_id)
tx.append(bytes())
tx.append(bytes())
return self._sign(bip32_path, rlp.encode(tx))
def sign_1559(self,
bip32_path: str,
chain_id: int,
nonce: int,
max_prio_gas_price: float,
max_gas_price: float,
gas_limit: int,
destination: bytes,
amount: float,
data: TxData = None,
access_list = list()):
tx = list()
tx.append(chain_id)
tx.append(nonce)
tx.append(int(max_prio_gas_price * GWEI_IN_ETH))
tx = self._sign_common(tx, max_gas_price, gas_limit, destination, amount, data)
tx.append(access_list)
tx.append(False)
tx.append(bytes())
tx.append(bytes())
# prefix with transaction type
return self._sign(bip32_path, b'\x02' + rlp.encode(tx))
def get_challenge(self):
return self._send(self._cmd_builder.get_challenge())
@@ -151,3 +206,68 @@ class EthAppClient:
with self._send(chunk):
pass
return self._send(chunks[-1])
def set_plugin(self,
plugin_name: str,
contract_addr: bytes,
selector: bytes,
chain_id: int,
type_: int = 1,
version: int = 1,
key_id: int = 2,
algo_id: int = 1,
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_plugin(type_,
version,
plugin_name,
contract_addr,
selector,
chain_id,
key_id,
algo_id,
bytes())
# skip APDU header & empty sig
sig = sign_data(Key.SET_PLUGIN, tmp[5:-1])
return self._send(self._cmd_builder.set_plugin(type_,
version,
plugin_name,
contract_addr,
selector,
chain_id,
key_id,
algo_id,
sig))
def provide_nft_metadata(self,
collection: str,
addr: bytes,
chain_id: int,
type_: int = 1,
version: int = 1,
key_id: int = 1,
algo_id: int = 1,
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.provide_nft_information(type_,
version,
collection,
addr,
chain_id,
key_id,
algo_id,
bytes())
# skip APDU header & empty sig
sig = sign_data(Key.NFT, tmp[5:-1])
return self._send(self._cmd_builder.provide_nft_information(type_,
version,
collection,
addr,
chain_id,
key_id,
algo_id,
sig))

View File

@@ -10,6 +10,8 @@ from .eip712 import EIP712FieldType
class InsType(IntEnum):
GET_PUBLIC_ADDR = 0x02
SIGN = 0x04
PROVIDE_NFT_INFORMATION = 0x14
SET_PLUGIN = 0x16
EIP712_SEND_STRUCT_DEF = 0x1a
EIP712_SEND_STRUCT_IMPL = 0x1c
EIP712_SEND_FILTERING = 0x1e
@@ -219,3 +221,49 @@ class CommandBuilder:
int(display),
int(chaincode),
payload)
def set_plugin(self,
type_: int,
version: int,
plugin_name: str,
contract_addr: bytes,
selector: bytes,
chain_id: int,
key_id: int,
algo_id: int,
sig: bytes) -> bytes:
payload = bytearray()
payload.append(type_)
payload.append(version)
payload.append(len(plugin_name))
payload += plugin_name.encode()
payload += contract_addr
payload += selector
payload += struct.pack(">Q", chain_id)
payload.append(key_id)
payload.append(algo_id)
payload.append(len(sig))
payload += sig
return self._serialize(InsType.SET_PLUGIN, 0x00, 0x00, payload)
def provide_nft_information(self,
type_: int,
version: int,
collection_name: str,
addr: bytes,
chain_id: int,
key_id: int,
algo_id: int,
sig: bytes):
payload = bytearray()
payload.append(type_)
payload.append(version)
payload.append(len(collection_name))
payload += collection_name.encode()
payload += addr
payload += struct.pack(">Q", chain_id)
payload.append(key_id)
payload.append(algo_id)
payload.append(len(sig))
payload += sig
return self._serialize(InsType.PROVIDE_NFT_INFORMATION, 0x00, 0x00, payload)

View File

@@ -11,6 +11,8 @@ from typing import Dict
class Key(Enum):
CAL = auto()
DOMAIN_NAME = auto()
SET_PLUGIN = auto()
NFT = auto()
_keys: Dict[Key, SigningKey] = dict()

View File

@@ -0,0 +1,8 @@
-----BEGIN EC PARAMETERS-----
BgUrgQQACg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIK69Gt4o0bzkOaEwUE5X2tI+Ks80FQi785Co+6woU9hioAcGBSuBBAAK
oUQDQgAEPPtfsxkF9L052dU1pAwmqrUcXX0yGbKKyUK5gPsgbPswtRzC3iEZrAOO
uw191lQXcCBKPO06eeKLMvu2cmRowA==
-----END EC PRIVATE KEY-----

View File

@@ -0,0 +1,8 @@
-----BEGIN EC PARAMETERS-----
BgUrgQQACg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIBErwcYvqeKSOlmQ/j3xPkVcwFf+j1aiMsA+RabczvN7oAcGBSuBBAAK
oUQDQgAEwFW8Ts8FXi2FCF01Eno95nBcf4hQVc1wceh2cb8ZH+M8yPAavC8ofIGa
FIq+G1gd8bSUCvXU3DpOa2AZF3ErNw==
-----END EC PRIVATE KEY-----

View File

@@ -0,0 +1,4 @@
import sha3
def get_selector_from_function(fn: str) -> bytes:
return sha3.keccak_256(fn.encode()).digest()[0:4]

View File

@@ -528,7 +528,7 @@ The plugin names `ERC20`, `ERC721` and `ERC1155` are reserved. Additional plugin
The signature is computed on
type || version || len(pluginName) || pluginName || address || selector || chainId || keyId || algorithmId || len(signature) || signature
type || version || len(pluginName) || pluginName || address || selector || chainId || keyId || algorithmId
#### Coding

View File

@@ -43,24 +43,20 @@ extern tokenDefinition_t const TOKENS_EXTRA[NUM_TOKENS_EXTRA];
#ifndef HAVE_TOKENS_LIST
#if defined(HAVE_CAL_TEST_KEY) && defined(HAVE_CAL_CI_KEY)
#error "CAL key contradiction, two alternative keys selected at once"
#endif
static const uint8_t LEDGER_SIGNATURE_PUBLIC_KEY[] = {
#if defined(HAVE_CAL_TEST_KEY)
// test key 2019-01-11 03:07PM (erc20signer)
0x04, 0x20, 0xda, 0x62, 0x00, 0x3c, 0x0c, 0xe0, 0x97, 0xe3, 0x36, 0x44, 0xa1, 0x0f,
0xe4, 0xc3, 0x04, 0x54, 0x06, 0x9a, 0x44, 0x54, 0xf0, 0xfa, 0x9d, 0x4e, 0x84, 0xf4,
0x50, 0x91, 0x42, 0x9b, 0x52, 0x20, 0xaf, 0x9e, 0x35, 0xc0, 0xb2, 0xd9, 0x28, 0x93,
0x80, 0x13, 0x73, 0x07, 0xde, 0x4d, 0xd1, 0xd4, 0x18, 0x42, 0x8c, 0xf2, 0x1a, 0x93,
0xb3, 0x35, 0x61, 0xbb, 0x09, 0xd8, 0x8f, 0xe5, 0x79
#elif defined(HAVE_CAL_CI_KEY)
0x04, 0x4c, 0xca, 0x8f, 0xad, 0x49, 0x6a, 0xa5, 0x04, 0x0a, 0x00, 0xa7, 0xeb, 0x2f,
0x5c, 0xc3, 0xb8, 0x53, 0x76, 0xd8, 0x8b, 0xa1, 0x47, 0xa7, 0xd7, 0x05, 0x4a, 0x99,
0xc6, 0x40, 0x56, 0x18, 0x87, 0xfe, 0x17, 0xa0, 0x96, 0xe3, 0x6c, 0x3b, 0x52, 0x3b,
0x24, 0x4f, 0x3e, 0x2f, 0xf7, 0xf8, 0x40, 0xae, 0x26, 0xc4, 0xe7, 0x7a, 0xd3, 0xbc,
0x73, 0x9a, 0xf5, 0xde, 0x6f, 0x2d, 0x77, 0xa7, 0xb6
#elif defined(HAVE_CAL_STAGING_KEY)
// staging key 2019-01-11 03:07PM (erc20signer)
0x04, 0x20, 0xda, 0x62, 0x00, 0x3c, 0x0c, 0xe0, 0x97, 0xe3, 0x36, 0x44, 0xa1, 0x0f,
0xe4, 0xc3, 0x04, 0x54, 0x06, 0x9a, 0x44, 0x54, 0xf0, 0xfa, 0x9d, 0x4e, 0x84, 0xf4,
0x50, 0x91, 0x42, 0x9b, 0x52, 0x20, 0xaf, 0x9e, 0x35, 0xc0, 0xb2, 0xd9, 0x28, 0x93,
0x80, 0x13, 0x73, 0x07, 0xde, 0x4d, 0xd1, 0xd4, 0x18, 0x42, 0x8c, 0xf2, 0x1a, 0x93,
0xb3, 0x35, 0x61, 0xbb, 0x09, 0xd8, 0x8f, 0xe5, 0x79
#else
// production key 2019-01-11 03:07PM (erc20signer)
0x04, 0x5e, 0x6c, 0x10, 0x20, 0xc1, 0x4d, 0xc4, 0x64, 0x42, 0xfe, 0x89, 0xf9, 0x7c,

View File

@@ -19,8 +19,8 @@
#define MIN_DER_SIG_SIZE 67
#define MAX_DER_SIG_SIZE 72
#define TEST_NFT_METADATA_KEY 0
#define PROD_NFT_METADATA_KEY 1
#define STAGING_NFT_METADATA_KEY 0
#define PROD_NFT_METADATA_KEY 1
#define ALGORITHM_ID_1 1
@@ -29,13 +29,19 @@
#define VERSION_1 1
static const uint8_t LEDGER_NFT_METADATA_PUBLIC_KEY[] = {
#ifdef HAVE_NFT_TESTING_KEY
#if defined(HAVE_NFT_TEST_KEY)
0x04, 0x3c, 0xfb, 0x5f, 0xb3, 0x19, 0x05, 0xf4, 0xbd, 0x39, 0xd9, 0xd5, 0x35, 0xa4,
0x0c, 0x26, 0xaa, 0xb5, 0x1c, 0x5d, 0x7d, 0x32, 0x19, 0xb2, 0x8a, 0xc9, 0x42, 0xb9,
0x80, 0xfb, 0x20, 0x6c, 0xfb, 0x30, 0xb5, 0x1c, 0xc2, 0xde, 0x21, 0x19, 0xac, 0x03,
0x8e, 0xbb, 0x0d, 0x7d, 0xd6, 0x54, 0x17, 0x70, 0x20, 0x4a, 0x3c, 0xed, 0x3a, 0x79,
0xe2, 0x8b, 0x32, 0xfb, 0xb6, 0x72, 0x64, 0x68, 0xc0
#elif defined(HAVE_NFT_STAGING_KEY)
0x04, 0xf5, 0x70, 0x0c, 0xa1, 0xe8, 0x74, 0x24, 0xc7, 0xc7, 0xd1, 0x19, 0xe7, 0xe3,
0xc1, 0x89, 0xb1, 0x62, 0x50, 0x94, 0xdb, 0x6e, 0xa0, 0x40, 0x87, 0xc8, 0x30, 0x00,
0x7d, 0x0b, 0x46, 0x9a, 0x53, 0x11, 0xee, 0x6a, 0x1a, 0xcd, 0x1d, 0xa5, 0xaa, 0xb0,
0xf5, 0xc6, 0xdf, 0x13, 0x15, 0x8d, 0x28, 0xcc, 0x12, 0xd1, 0xdd, 0xa6, 0xec, 0xe9,
0x46, 0xb8, 0x9d, 0x5c, 0x05, 0x49, 0x92, 0x59, 0xc4
#else
#else // production key
0x04, 0x98, 0x8d, 0xa6, 0xb2, 0x46, 0xf2, 0x8e, 0x77, 0xc1, 0xba, 0xb6, 0x75, 0xcb,
0x2a, 0x27, 0x44, 0xf7, 0xf5, 0xce, 0xc5, 0x6a, 0xe6, 0xe0, 0x32, 0x23, 0x33, 0x7b,
0x57, 0x94, 0xcd, 0x6a, 0xe0, 0x7d, 0x48, 0xb3, 0x0d, 0xb9, 0xcc, 0xb4, 0x0f, 0x5a,
@@ -140,13 +146,13 @@ void handleProvideNFTInformation(uint8_t p1,
PRINTF("Address: %.*H\n", ADDRESS_LENGTH, workBuffer + offset);
offset += ADDRESS_LENGTH;
uint64_t chainId = u64_from_BE(workBuffer + offset, CHAIN_ID_SIZE);
uint64_t chain_id = u64_from_BE(workBuffer + offset, CHAIN_ID_SIZE);
// this prints raw data, so to have a more meaningful print, display
// the buffer before the endianness swap
PRINTF("ChainID: %.*H\n", sizeof(chainId), (workBuffer + offset));
if ((chainConfig->chainId != 0) && (chainConfig->chainId != chainId)) {
PRINTF("Chain ID token mismatch\n");
THROW(0x6A80);
PRINTF("ChainID: %.*H\n", sizeof(chain_id), (workBuffer + offset));
if (!chain_is_ethereum_compatible(&chain_id)) {
PRINTF("Unsupported chain ID!\n");
THROW(APDU_RESPONSE_INVALID_DATA);
}
offset += CHAIN_ID_SIZE;
@@ -156,8 +162,8 @@ void handleProvideNFTInformation(uint8_t p1,
PRINTF("KeyID: %d\n", keyId);
switch (keyId) {
#ifdef HAVE_NFT_TESTING_KEY
case TEST_NFT_METADATA_KEY:
#ifdef HAVE_NFT_STAGING_KEY
case STAGING_NFT_METADATA_KEY:
#endif
case PROD_NFT_METADATA_KEY:
rawKey = (uint8_t *) LEDGER_NFT_METADATA_PUBLIC_KEY;

View File

@@ -46,7 +46,13 @@ typedef enum AlgorithmID {
// Only used for signing NFT plugins (ERC721 and ERC1155)
static const uint8_t LEDGER_NFT_SELECTOR_PUBLIC_KEY[] = {
#ifdef HAVE_NFT_TESTING_KEY
#if defined(HAVE_SET_PLUGIN_TEST_KEY)
0x04, 0xc0, 0x55, 0xbc, 0x4e, 0xcf, 0x05, 0x5e, 0x2d, 0x85, 0x08, 0x5d, 0x35, 0x12,
0x7a, 0x3d, 0xe6, 0x70, 0x5c, 0x7f, 0x88, 0x50, 0x55, 0xcd, 0x70, 0x71, 0xe8, 0x76,
0x71, 0xbf, 0x19, 0x1f, 0xe3, 0x3c, 0xc8, 0xf0, 0x1a, 0xbc, 0x2f, 0x28, 0x7c, 0x81,
0x9a, 0x14, 0x8a, 0xbe, 0x1b, 0x58, 0x1d, 0xf1, 0xb4, 0x94, 0x0a, 0xf5, 0xd4, 0xdc,
0x3a, 0x4e, 0x6b, 0x60, 0x19, 0x17, 0x71, 0x2b, 0x37
#elif defined(HAVE_NFT_STAGING_KEY)
0x04, 0xf5, 0x70, 0x0c, 0xa1, 0xe8, 0x74, 0x24, 0xc7, 0xc7, 0xd1, 0x19, 0xe7, 0xe3,
0xc1, 0x89, 0xb1, 0x62, 0x50, 0x94, 0xdb, 0x6e, 0xa0, 0x40, 0x87, 0xc8, 0x30, 0x00,
0x7d, 0x0b, 0x46, 0x9a, 0x53, 0x11, 0xee, 0x6a, 0x1a, 0xcd, 0x1d, 0xa5, 0xaa, 0xb0,
@@ -169,13 +175,13 @@ void handleSetPlugin(uint8_t p1,
PRINTF("Selector: %.*H\n", SELECTOR_SIZE, tokenContext->methodSelector);
offset += SELECTOR_SIZE;
uint64_t chainId = u64_from_BE(workBuffer + offset, CHAIN_ID_SIZE);
uint64_t chain_id = u64_from_BE(workBuffer + offset, CHAIN_ID_SIZE);
// this prints raw data, so to have a more meaningful print, display
// the buffer before the endianness swap
PRINTF("ChainID: %.*H\n", sizeof(chainId), (workBuffer + offset));
if ((chainConfig->chainId != 0) && (chainConfig->chainId != chainId)) {
PRINTF("Chain ID token mismatch\n");
THROW(0x6A80);
PRINTF("ChainID: %.*H\n", sizeof(chain_id), (workBuffer + offset));
if (!chain_is_ethereum_compatible(&chain_id)) {
PRINTF("Unsupported chain ID!\n");
THROW(APDU_RESPONSE_INVALID_DATA);
}
offset += CHAIN_ID_SIZE;
@@ -185,7 +191,7 @@ void handleSetPlugin(uint8_t p1,
PRINTF("KeyID: %d\n", keyId);
switch (keyId) {
#ifdef HAVE_NFT_TESTING_KEY
#ifdef HAVE_NFT_STAGING_KEY
case TEST_PLUGIN_KEY:
#endif
case PROD_PLUGIN_KEY:

View File

@@ -108,7 +108,12 @@ static void handle_query_contract_id(void *parameters) {
switch (context->selectorIndex) {
case SET_APPROVAL_FOR_ALL:
#ifdef HAVE_NBGL
strlcpy(msg->version, "manage", msg->versionLength);
strlcat(msg->name, " allowance", msg->nameLength);
#else
strlcpy(msg->version, "Allowance", msg->versionLength);
#endif
break;
case SAFE_TRANSFER:
strlcpy(msg->version, "Transfer", msg->versionLength);

View File

@@ -116,7 +116,12 @@ static void handle_query_contract_id(void *parameters) {
switch (context->selectorIndex) {
case SET_APPROVAL_FOR_ALL:
case APPROVE:
#ifdef HAVE_NBGL
strlcpy(msg->version, "manage", msg->versionLength);
strlcat(msg->name, " allowance", msg->nameLength);
#else
strlcpy(msg->version, "Allowance", msg->versionLength);
#endif
break;
case SAFE_TRANSFER:
case SAFE_TRANSFER_DATA:

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 823 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 846 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 823 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 823 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 846 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 823 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 533 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

Some files were not shown because too many files have changed in this diff Show More