diff --git a/.gitignore b/.gitignore index 199a053c..64ce1386 100644 --- a/.gitignore +++ b/.gitignore @@ -53,5 +53,9 @@ dkms.conf # Project-level stuff debug/ +ledger-nanopb/ .DS_Store -*.pyc \ No newline at end of file +*.pyc +src/glyphs.c +src/glyphs.h +bin \ No newline at end of file diff --git a/Makefile b/Makefile old mode 100755 new mode 100644 index 211cebb8..622fdde9 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ include $(BOLOS_SDK)/Makefile.defines # Main app configuration APPVERSION_M=1 -APPVERSION_N=1 +APPVERSION_N=2 APPVERSION_P=0 APPNAME = "Waves" @@ -31,12 +31,10 @@ APPVERSION = $(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P) ifeq ($(TARGET_NAME),TARGET_BLUE) ICONNAME=blue_app_waves.gif +else ifeq ($(TARGET_NAME),TARGET_NANOS) +ICONNAME=nanos_app_waves.gif else - ifeq ($(TARGET_NAME),TARGET_NANOX) -ICONNAME=nanox_app_waves.gif - else -ICONNAME = nanos_app_waves.gif - endif +ICONNAME = nanox_app_waves.gif endif APP_LOAD_PARAMS = --appFlags 0x240 --path "44'/5741564'" --curve secp256k1 --curve ed25519 $(COMMON_LOAD_PARAMS) @@ -48,16 +46,11 @@ APP_SOURCE_PATH += src SDK_SOURCE_PATH += lib_stusb #qrcode #use the SDK U2F+HIDGEN USB profile SDK_SOURCE_PATH += lib_u2f lib_stusb_impl +SDK_SOURCE_PATH += lib_ux +DEFINES += HAVE_UX_FLOW ifeq ($(TARGET_NAME),TARGET_NANOX) SDK_SOURCE_PATH += lib_blewbxx lib_blewbxx_impl -SDK_SOURCE_PATH += lib_ux -DEFINES += HAVE_UX_FLOW -endif - -ifeq ($(TARGET_NAME),TARGET_NANOS) -SDK_SOURCE_PATH += lib_ux -DEFINES += HAVE_UX_FLOW endif DEFINES += APPVERSION=\"$(APPVERSION)\" @@ -83,28 +76,30 @@ DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=0 WEBUSB_URL="" ifeq ($(TARGET_NAME),TARGET_NANOX) -DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300 DEFINES += HAVE_BLE BLE_COMMAND_TIMEOUT_MS=2000 DEFINES += HAVE_BLE_APDU # basic ledger apdu transport over BLE +endif +ifeq ($(TARGET_NAME),TARGET_NANOS) +DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128 +else +DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300 DEFINES += HAVE_GLO096 DEFINES += HAVE_BAGL BAGL_WIDTH=128 BAGL_HEIGHT=64 DEFINES += HAVE_BAGL_ELLIPSIS # long label truncation feature DEFINES += HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX DEFINES += HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX DEFINES += HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX -else -DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128 endif # Enabling debug PRINTF DEBUG = 0 ifneq ($(DEBUG),0) - ifeq ($(TARGET_NAME),TARGET_NANOX) - DEFINES += HAVE_PRINTF PRINTF=mcu_usb_printf - else + ifeq ($(TARGET_NAME),TARGET_NANOS) DEFINES += HAVE_PRINTF PRINTF=screen_printf + else + DEFINES += HAVE_PRINTF PRINTF=mcu_usb_printf endif else DEFINES += PRINTF\(...\)= diff --git a/generate_proto.sh b/generate_proto.sh new file mode 100755 index 00000000..5e388dc5 --- /dev/null +++ b/generate_proto.sh @@ -0,0 +1,13 @@ +NANOPB=../ledger-nanopb + +pushd proto +protoc --plugin=protoc-gen-nanopb=${NANOPB}/generator/protoc-gen-nanopb --nanopb_out=../src/nanopb_stubs -I. -I${NANOPB}/generator/proto/ *.proto +protoc --python_out=../python -I. -I${NANOPB}/generator/proto/ *.proto +popd + +if ! [ "$(ls src/nanopb)" ]; then + cd src/nanopb + cp ../../ledger-nanopb/*.c . + cp ../../ledger-nanopb/*.h . + cd .. +fi diff --git a/proto/amount.proto b/proto/amount.proto new file mode 100644 index 00000000..e3afef09 --- /dev/null +++ b/proto/amount.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; +package waves; +option java_package = "com.wavesplatform.protobuf"; +option csharp_namespace = "Waves"; + +message Amount { + bytes asset_id = 1; + int64 amount = 2; +}; diff --git a/proto/order.options b/proto/order.options new file mode 100644 index 00000000..29f56735 --- /dev/null +++ b/proto/order.options @@ -0,0 +1 @@ +waves.Order.proofs type: FT_IGNORE diff --git a/proto/order.proto b/proto/order.proto new file mode 100644 index 00000000..d5388ee1 --- /dev/null +++ b/proto/order.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; +package waves; +option java_package = "com.wavesplatform.protobuf.order"; +option csharp_namespace = "Waves"; + +import "amount.proto"; + +message AssetPair { + bytes amount_asset_id = 1; + bytes price_asset_id = 2; +}; + +message Order { + enum Side { + BUY = 0; + SELL = 1; + }; + + int32 chain_id = 1; + bytes sender_public_key = 2; + bytes matcher_public_key = 3; + AssetPair asset_pair = 4; + Side order_side = 5; + int64 amount = 6; + int64 price = 7; + int64 timestamp = 8; + int64 expiration = 9; + Amount matcher_fee = 10; + int32 version = 11; + repeated bytes proofs = 12; +}; diff --git a/proto/recipient.options b/proto/recipient.options new file mode 100644 index 00000000..19a1a976 --- /dev/null +++ b/proto/recipient.options @@ -0,0 +1,2 @@ +waves.Recipient.public_key_hash max_size:20 fixed_length:true +waves.Recipient.alias max_size:31 \ No newline at end of file diff --git a/proto/recipient.proto b/proto/recipient.proto new file mode 100644 index 00000000..21ce9c15 --- /dev/null +++ b/proto/recipient.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package waves; +option java_package = "com.wavesplatform.protobuf.transaction"; +option csharp_namespace = "Waves"; + +message Recipient { + oneof recipient { + // First 20 bytes of the result of the Keccak256(Blake2b256(publicKey)) hashing function. + bytes public_key_hash = 1; + string alias = 2; + }; +}; diff --git a/proto/transaction.options b/proto/transaction.options new file mode 100644 index 00000000..6958b9d0 --- /dev/null +++ b/proto/transaction.options @@ -0,0 +1,20 @@ +#Transaction filed sizes +waves.Transaction.chain_id type: FT_IGNORE +waves.Transaction.timestamp type: FT_IGNORE +waves.Transaction.version type: FT_IGNORE + +waves.GenesisTransactionData type: FT_IGNORE + +waves.PaymentTransactionData type: FT_IGNORE + +waves.ExchangeTransactionData type: FT_IGNORE + +waves.SetAssetScriptTransactionData.script type: FT_IGNORE + +waves.SetScriptTransactionData.script type: FT_IGNORE + +waves.MassTransferTransactionData.transfers type: FT_IGNORE + +waves.InvokeScriptTransactionData.payments max_count: 2 + +waves.DataTransactionData.data type: FT_IGNORE \ No newline at end of file diff --git a/proto/transaction.proto b/proto/transaction.proto new file mode 100644 index 00000000..39846999 --- /dev/null +++ b/proto/transaction.proto @@ -0,0 +1,151 @@ +syntax = "proto3"; +package waves; + +option java_package = "com.wavesplatform.protobuf.transaction"; +option csharp_namespace = "Waves"; + +import "nanopb.proto"; +import "amount.proto"; +import "recipient.proto"; +import "order.proto"; + +message SignedTransaction { + Transaction transaction = 1; + repeated bytes proofs = 2; +} + +message Transaction { + option (nanopb_msgopt).submsg_callback = true; + int32 chain_id = 1; + bytes sender_public_key = 2; + Amount fee = 3; + int64 timestamp = 4; + int32 version = 5; + + oneof data { + GenesisTransactionData genesis = 101; + PaymentTransactionData payment = 102; + IssueTransactionData issue = 103; + TransferTransactionData transfer = 104; + ReissueTransactionData reissue = 105; + BurnTransactionData burn = 106; + ExchangeTransactionData exchange = 107; + LeaseTransactionData lease = 108; + LeaseCancelTransactionData lease_cancel = 109; + CreateAliasTransactionData create_alias = 110; + MassTransferTransactionData mass_transfer = 111; + DataTransactionData data_transaction = 112; + SetScriptTransactionData set_script = 113; + SponsorFeeTransactionData sponsor_fee = 114; + SetAssetScriptTransactionData set_asset_script = 115; + InvokeScriptTransactionData invoke_script = 116; + UpdateAssetInfoTransactionData update_asset_info = 117; + }; +}; + +message GenesisTransactionData { + bytes recipient_address = 1; + int64 amount = 2; +}; + +message PaymentTransactionData { + bytes recipient_address = 1; + int64 amount = 2; +}; + +message TransferTransactionData { + Recipient recipient = 1; + Amount amount = 2; + bytes attachment = 3; +}; + +message CreateAliasTransactionData { + string alias = 1; +}; + +message DataTransactionData { + message DataEntry { + option (nanopb_msgopt).skip_message = true; + string key = 1; + oneof value { + int64 int_value = 10; + bool bool_value = 11; + bytes binary_value = 12; + string string_value = 13; + }; + }; + + repeated DataEntry data = 1; +}; + +message MassTransferTransactionData { + message Transfer { + option (nanopb_msgopt).skip_message = true; + Recipient recipient = 1; + int64 amount = 2; + }; + + bytes asset_id = 1; + repeated Transfer transfers = 2; + bytes attachment = 3; +}; + +message LeaseTransactionData { + Recipient recipient = 1; + int64 amount = 2; +}; + +message LeaseCancelTransactionData { + bytes lease_id = 1; +}; + +message BurnTransactionData { + Amount asset_amount = 1; +}; + +message IssueTransactionData { + string name = 1; + string description = 2; + int64 amount = 3; + int32 decimals = 4; + bool reissuable = 5; + bytes script = 6; +}; + +message ReissueTransactionData { + Amount asset_amount = 1; + bool reissuable = 2; +}; + +message SetAssetScriptTransactionData { + bytes asset_id = 1; + bytes script = 2; +}; + +message SetScriptTransactionData { + bytes script = 1; +}; + +message ExchangeTransactionData { + int64 amount = 1; + int64 price = 2; + int64 buy_matcher_fee = 3; + int64 sell_matcher_fee = 4; + repeated Order orders = 5; +}; + +message SponsorFeeTransactionData { + Amount min_fee = 1; +}; + +message InvokeScriptTransactionData { + Recipient d_app = 1; + bytes function_call = 2; + repeated Amount payments = 3; +} + +message UpdateAssetInfoTransactionData { + bytes asset_id = 1; + string name = 2; + string description = 3; +} \ No newline at end of file diff --git a/python/amount_pb2.py b/python/amount_pb2.py new file mode 100644 index 00000000..c5c56e7d --- /dev/null +++ b/python/amount_pb2.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: amount.proto + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='amount.proto', + package='waves', + syntax='proto3', + serialized_options=b'\n\032com.wavesplatform.protobuf\252\002\005Waves', + serialized_pb=b'\n\x0c\x61mount.proto\x12\x05waves\"*\n\x06\x41mount\x12\x10\n\x08\x61sset_id\x18\x01 \x01(\x0c\x12\x0e\n\x06\x61mount\x18\x02 \x01(\x03\x42$\n\x1a\x63om.wavesplatform.protobuf\xaa\x02\x05Wavesb\x06proto3' +) + + + + +_AMOUNT = _descriptor.Descriptor( + name='Amount', + full_name='waves.Amount', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='asset_id', full_name='waves.Amount.asset_id', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='amount', full_name='waves.Amount.amount', index=1, + number=2, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=23, + serialized_end=65, +) + +DESCRIPTOR.message_types_by_name['Amount'] = _AMOUNT +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +Amount = _reflection.GeneratedProtocolMessageType('Amount', (_message.Message,), { + 'DESCRIPTOR' : _AMOUNT, + '__module__' : 'amount_pb2' + # @@protoc_insertion_point(class_scope:waves.Amount) + }) +_sym_db.RegisterMessage(Amount) + + +DESCRIPTOR._options = None +# @@protoc_insertion_point(module_scope) diff --git a/python/ledger-waves.py b/python/ledger-waves.py index e403e916..620652fe 100644 --- a/python/ledger-waves.py +++ b/python/ledger-waves.py @@ -23,6 +23,11 @@ import pywaves.crypto as pwcrypto import pywaves as pw import time +import base64 +import order_pb2 as opb +from amount_pb2 import Amount +import transaction_pb2 as tpb +from recipient_pb2 import Recipient global dongle dongle = None @@ -82,14 +87,16 @@ def getKeysFromDongle(path, networkByte): global dongle while (True): try: - data_bytes = bytes(("800400" + '{0:x}'.format(ord(networkByte)) + "14").decode('hex')) + path_to_bytes(path) + data_bytes = bytes( + ("800400" + '{0:x}'.format(ord(networkByte)) + "14").decode('hex')) + path_to_bytes(path) data = dongle.exchange(data_bytes) return [data[0:32], data[32:67]] except CommException as e: if (e.sw == 0x6985): print(colors.fg.red + "Required condition failed." + colors.reset) if (e.sw == 0x9100): - print(colors.fg.red + "User denied signing request on Ledger Nano S device." + colors.reset) + print( + colors.fg.red + "User denied signing request on Ledger Nano S device." + colors.reset) break except Exception as e: raw_input( @@ -97,6 +104,7 @@ def getKeysFromDongle(path, networkByte): sys.exc_clear() break + def getVersionFromDongle(): global dongle while (True): @@ -108,7 +116,8 @@ def getVersionFromDongle(): if (e.sw == 0x6985): print(colors.fg.red + "Required condition failed." + colors.reset) if (e.sw == 0x9100): - print(colors.fg.red + "User denied signing request on Ledger Nano S device." + colors.reset) + print( + colors.fg.red + "User denied signing request on Ledger Nano S device." + colors.reset) break except Exception as e: raw_input( @@ -116,6 +125,7 @@ def getVersionFromDongle(): sys.exc_clear() break + # 128 - 5 service bytes CHUNK_SIZE = 123 PRIME_DERIVATION_FLAG = 0x80000000 @@ -161,7 +171,7 @@ def expand_path(n): return path -def build_transfer_bytes(publicKey, recipient, asset, amount, attachment='', feeAsset='', txFee=100000, timestamp=0, version = b'\2'): +def build_transfer_bytes(publicKey, recipient, asset, amount, attachment='', feeAsset='', txFee=100000, timestamp=0, version=b'\2'): if timestamp == 0: timestamp = int(time.time() * 1000) @@ -169,7 +179,7 @@ def build_transfer_bytes(publicKey, recipient, asset, amount, attachment='', fee if version == b'\2': sData += version - + start_index = 31 start_len = len(sData) + start_index @@ -177,7 +187,7 @@ def build_transfer_bytes(publicKey, recipient, asset, amount, attachment='', fee sData += field end_len = start_len + len(field) print('public key [{} - {}]'.format(start_len, end_len)) - + start_len = len(sData) + start_index field = (b'\1' + base58.b58decode(asset.assetId) if asset else b'\0') sData += field @@ -228,6 +238,211 @@ def build_transfer_bytes(publicKey, recipient, asset, amount, attachment='', fee return sData + +def build_transfer_protobuf(publicKey, recipient, asset, amount, attachment='', feeAsset='', txFee=100000, timestamp=0, version=3): + if timestamp == 0: + timestamp = int(time.time() * 1000) + to = Recipient(public_key_hash=base58.b58decode(recipient)) + amountTx = Amount(asset_id=(base58.b58decode( + asset.assetId) if asset else None), amount=amount) + transfer = tpb.TransferTransactionData( + recipient=to, amount=amountTx, attachment=attachment) + fee = Amount(asset_id=(base58.b58decode(feeAsset.assetId) + if feeAsset else None), amount=txFee) + trx = tpb.Transaction(chain_id=ord(chain_id), sender_public_key=base58.b58decode(publicKey), fee=fee, timestamp=timestamp, version=version, transfer=transfer) + return trx.SerializeToString() + + +def build_masstransfer_protobuf(publicKey, recipient, asset, amount, attachment='', feeAsset='', txFee=100000, timestamp=0, version=2): + if timestamp == 0: + timestamp = int(time.time() * 1000) + to = Recipient(public_key_hash=base58.b58decode(recipient)) + transfers = list() + transfers.append(tpb.MassTransferTransactionData.Transfer( + recipient=to, amount=amount)) + transfers.append(tpb.MassTransferTransactionData.Transfer( + recipient=to, amount=amount)) + transfers.append(tpb.MassTransferTransactionData.Transfer( + recipient=to, amount=amount)) + mass_transfer = tpb.MassTransferTransactionData(asset_id=(base58.b58decode( + asset.assetId) if asset else None), transfers=transfers, attachment=attachment) + fee = Amount(asset_id=(base58.b58decode(feeAsset.assetId) + if feeAsset else None), amount=txFee) + trx = tpb.Transaction(chain_id=ord(chain_id), sender_public_key=base58.b58decode( + publicKey), fee=fee, timestamp=timestamp, version=version, mass_transfer=mass_transfer) + return trx.SerializeToString() + + +def build_issue_protobuf(publicKey, name, descr, amount, decimals, reissue, feeAsset='', txFee=100000, timestamp=0, version=3): + if timestamp == 0: + timestamp = int(time.time() * 1000) + issue = tpb.IssueTransactionData( + name=name, description=descr, amount=amount, decimals=decimals, reissuable=reissue) + fee = Amount(asset_id=(base58.b58decode(feeAsset.assetId) + if feeAsset else None), amount=txFee) + trx = tpb.Transaction(chain_id=ord(chain_id), sender_public_key=base58.b58decode( + publicKey), fee=fee, timestamp=timestamp, version=version, issue=issue) + return trx.SerializeToString() + + +def build_set_ac_script_protobuf(publicKey, script, feeAsset='', txFee=100000, timestamp=0, version=2): + if timestamp == 0: + timestamp = int(time.time() * 1000) + scr = tpb.SetScriptTransactionData(script=script) + fee = Amount(asset_id=(base58.b58decode(feeAsset.assetId) + if feeAsset else None), amount=txFee) + trx = tpb.Transaction(chain_id=ord(chain_id), sender_public_key=base58.b58decode( + publicKey), fee=fee, timestamp=timestamp, version=version, set_script=scr) + return trx.SerializeToString() + + +def build_set_as_script_protobuf(publicKey, asset, script, feeAsset='', txFee=100000, timestamp=0, version=2): + if timestamp == 0: + timestamp = int(time.time() * 1000) + scr = tpb.SetAssetScriptTransactionData( + asset_id=base58.b58decode(asset.assetId), script=script) + fee = Amount(asset_id=(base58.b58decode(feeAsset.assetId) + if feeAsset else None), amount=txFee) + trx = tpb.Transaction(chain_id=ord(chain_id), sender_public_key=base58.b58decode( + publicKey), fee=fee, timestamp=timestamp, version=version, set_asset_script=scr) + return trx.SerializeToString() + + +def build_reissue_protobuf(publicKey, asset, amount, re, feeAsset='', txFee=100000, timestamp=0, version=3): + if timestamp == 0: + timestamp = int(time.time() * 1000) + amountTx = Amount(asset_id=base58.b58decode(asset.assetId), amount=amount) + reissue = tpb.ReissueTransactionData(asset_amount=amountTx, reissuable=re) + fee = Amount(asset_id=(base58.b58decode(feeAsset.assetId) + if feeAsset else None), amount=txFee) + trx = tpb.Transaction(chain_id=ord(chain_id), sender_public_key=base58.b58decode( + publicKey), fee=fee, timestamp=timestamp, version=version, reissue=reissue) + return trx.SerializeToString() + + +def build_burn_protobuf(publicKey, asset, amount, feeAsset='', txFee=100000, timestamp=0, version=3): + if timestamp == 0: + timestamp = int(time.time() * 1000) + amountTx = Amount(asset_id=base58.b58decode(asset.assetId), amount=amount) + burn = tpb.BurnTransactionData(asset_amount=amountTx) + fee = Amount(asset_id=(base58.b58decode(feeAsset.assetId) + if feeAsset else None), amount=txFee) + trx = tpb.Transaction(chain_id=ord(chain_id), sender_public_key=base58.b58decode( + publicKey), fee=fee, timestamp=timestamp, version=version, burn=burn) + return trx.SerializeToString() + + +def build_lease_protobuf(publicKey, to, amount, feeAsset='', txFee=100000, timestamp=0, version=3): + if timestamp == 0: + timestamp = int(time.time() * 1000) + recipient = Recipient(public_key_hash=base58.b58decode(to)) + lease = tpb.LeaseTransactionData(recipient=recipient, amount=amount) + fee = Amount(asset_id=(base58.b58decode(feeAsset.assetId) + if feeAsset else None), amount=txFee) + trx = tpb.Transaction(chain_id=ord(chain_id), sender_public_key=base58.b58decode( + publicKey), fee=fee, timestamp=timestamp, version=version, lease=lease) + return trx.SerializeToString() + + +def build_cancel_lease_protobuf(publicKey, leaseId, feeAsset='', txFee=100000, timestamp=0, version=3): + if timestamp == 0: + timestamp = int(time.time() * 1000) + lease_cancel = tpb.LeaseCancelTransactionData( + lease_id=base58.b58decode(leaseId)) + fee = Amount(asset_id=(base58.b58decode(feeAsset.assetId) + if feeAsset else None), amount=txFee) + trx = tpb.Transaction(chain_id=ord(chain_id), sender_public_key=base58.b58decode( + publicKey), fee=fee, timestamp=timestamp, version=version, lease_cancel=lease_cancel) + return trx.SerializeToString() + + +def build_creating_alias_protobuf(publicKey, alias, feeAsset='', txFee=100000, timestamp=0, version=3): + if timestamp == 0: + timestamp = int(time.time() * 1000) + alias = tpb.CreateAliasTransactionData(alias=alias) + fee = Amount(asset_id=(base58.b58decode(feeAsset.assetId) + if feeAsset else None), amount=txFee) + trx = tpb.Transaction(chain_id=ord(chain_id), sender_public_key=base58.b58decode( + publicKey), fee=fee, timestamp=timestamp, version=version, create_alias=alias) + return trx.SerializeToString() + + +def build_update_asset_protobuf(publicKey, asset, name, description, feeAsset='', txFee=100000, timestamp=0, version=1): + if timestamp == 0: + timestamp = int(time.time() * 1000) + update_asset = tpb.UpdateAssetInfoTransactionData( + asset_id=base58.b58decode(asset.assetId), name=name, description=description) + fee = Amount(asset_id=(base58.b58decode(feeAsset.assetId) + if feeAsset else None), amount=txFee) + trx = tpb.Transaction(chain_id=ord(chain_id), sender_public_key=base58.b58decode( + publicKey), fee=fee, timestamp=timestamp, version=version, update_asset_info=update_asset) + return trx.SerializeToString() + + +def build_data_protobuf(publicKey, feeAsset='', txFee=100000, timestamp=0, version=2): + if timestamp == 0: + timestamp = int(time.time() * 1000) + list = [] + for x in range(1): + k = "jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj" + str(x) + s = "jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj" + str(x) + dataEntery = tpb.DataTransactionData.DataEntry(key=k, string_value=s) + list.append(dataEntery) + data = tpb.DataTransactionData(data=list) + fee = Amount(asset_id=(base58.b58decode(feeAsset.assetId) + if feeAsset else b''), amount=txFee) + trx = tpb.Transaction(chain_id=ord(chain_id), sender_public_key=base58.b58decode( + publicKey), fee=fee, timestamp=timestamp, version=version, data_transaction=data) + return trx.SerializeToString() + + +def build_sponsorship_protobuf(publicKey, asset, amount, feeAsset='', txFee=100000, timestamp=0, version=2): + if timestamp == 0: + timestamp = int(time.time() * 1000) + amountTx = Amount(asset_id=(base58.b58decode(asset.assetId) + if feeAsset else None), amount=amount) + sponsorship = tpb.SponsorFeeTransactionData(min_fee=amountTx) + fee = Amount(asset_id=(base58.b58decode(feeAsset.assetId) + if feeAsset else None), amount=txFee) + trx = tpb.Transaction(chain_id=ord(chain_id), sender_public_key=base58.b58decode( + publicKey), fee=fee, timestamp=timestamp, version=version, sponsor_fee=sponsorship) + return trx.SerializeToString() + + +def build_invoke_protobuf(publicKey, dapp, function, asset, amount, asset2, amount2, feeAsset='', txFee=100000, timestamp=0, version=2): + if timestamp == 0: + timestamp = int(time.time() * 1000) + amounts = [] + amountTx = Amount(asset_id=base58.b58decode(asset.assetId), amount=amount) + amounts.append(amountTx) + amountTx = Amount(asset_id=base58.b58decode( + asset2.assetId), amount=amount2) + amounts.append(amountTx) + to = Recipient(public_key_hash=base58.b58decode(dapp)) + invoke = tpb.InvokeScriptTransactionData( + d_app=to, function_call=function, payments=amounts) + fee = Amount(asset_id=(base58.b58decode(feeAsset.assetId) + if feeAsset else None), amount=txFee) + trx = tpb.Transaction(chain_id=ord(chain_id), sender_public_key=base58.b58decode( + publicKey), fee=fee, timestamp=timestamp, version=version, invoke_script=invoke) + return trx.SerializeToString() + + +def build_order_protobuf(publicKey, matcherPK, amountAsset, priceAsset, type, amount, price, expiration, timestamp=0, feeAsset='', txFee=100000, version=3): + if timestamp == 0: + timestamp = int(time.time() * 1000) + fee = Amount(asset_id=(base58.b58decode(feeAsset.assetId) + if feeAsset else None), amount=txFee) + assetPair = opb.AssetPair( + amount_asset_id=(base58.b58decode(amountAsset.assetId) + if amountAsset else None), + price_asset_id=(base58.b58decode(priceAsset.assetId) + if priceAsset else None), + ) + order = opb.Order(chain_id=ord(chain_id), sender_public_key=base58.b58decode(publicKey), matcher_public_key=base58.b58decode( + matcherPK), asset_pair=assetPair, order_side=1, amount=amount, price=price, timestamp=timestamp, expiration=expiration, matcher_fee=fee, version=3) + return order.SerializeToString() + while (True): while (dongle == None): try: @@ -239,12 +454,14 @@ def build_transfer_bytes(publicKey, recipient, asset, amount, attachment='', fee sys.exit(0) sys.exc_clear() - print("") - print(colors.fg.lightcyan + colors.bold + "Ledger Nano S - Waves test app" + colors.reset) - print(colors.fg.white + "\t 1. Get PublicKey/Address from Ledger Nano S" + colors.reset) + print(colors.fg.lightcyan + colors.bold + + "Ledger Nano S - Waves test app" + colors.reset) + print(colors.fg.white + + "\t 1. Get PublicKey/Address from Ledger Nano S" + colors.reset) print(colors.fg.white + "\t 2. Sign tx using Ledger Nano S" + colors.reset) print(colors.fg.white + "\t 3. Get app version from Ledger Nano S" + colors.reset) - print(colors.fg.white + "\t 4. Exit" + colors.reset) + print(colors.fg.white + "\t 4. Sign protobuf tx using Ledger Nano S" + colors.reset) + print(colors.fg.white + "\t 5. Exit" + colors.reset) select = raw_input(colors.fg.cyan + "Please select> " + colors.reset) if (select == "1"): @@ -257,7 +474,8 @@ def build_transfer_bytes(publicKey, recipient, asset, amount, attachment='', fee publicKey = keys[0] address = keys[1] - print(colors.fg.blue + "publicKey (base58): " + colors.reset + base58.b58encode(str(publicKey))) + print(colors.fg.blue + "publicKey (base58): " + + colors.reset + base58.b58encode(str(publicKey))) print(colors.fg.blue + "address: " + colors.reset + address) elif (select == "2"): path = raw_input( @@ -265,13 +483,15 @@ def build_transfer_bytes(publicKey, recipient, asset, amount, attachment='', fee if len(path) == 0: path = "44'/5741564'/0'/0'/1'" binary_data = path_to_bytes(expand_path(path)) - print(colors.fg.lightgrey + "path bytes: " + base58.b58encode(str(path_to_bytes(expand_path(path))))) + print(colors.fg.lightgrey + "path bytes: " + + base58.b58encode(str(path_to_bytes(expand_path(path))))) # tx amount asset decimals binary_data += chr(8) + # tx amount asset decimals 2 + binary_data += chr(0) # fee amount asset decimals binary_data += chr(8) - # Tx info # # amount: 1 @@ -282,9 +502,11 @@ def build_transfer_bytes(publicKey, recipient, asset, amount, attachment='', fee # fee: 0.001 # fee asset: WAVES some_transfer_bytes = build_transfer_bytes('4ovEU8YpbHTurwzw8CDZaCD7m6LpyMTC4nrJcgDHb4Jh', - pw.Address('3PMpANFyKGBwzvv1UVk2KdN23fJZ8sXSVEK'), - pw.Asset('9gqcTyupiDWuogWhKv8G3EMwjMaobkw9Lpys4EY2F62t'), 1, - 'privet', timestamp = 1526477921829) + pw.Address( + '3PMpANFyKGBwzvv1UVk2KdN23fJZ8sXSVEK'), + pw.Asset( + '9gqcTyupiDWuogWhKv8G3EMwjMaobkw9Lpys4EY2F62t'), 100000000, + 'privet', timestamp=1526477921829) input = raw_input(colors.fg.lightblue + "Please input message to sign (for example \"" + base58.b58encode( str(some_transfer_bytes)) + "\")> " + colors.reset) if len(input) == 0: @@ -293,14 +515,21 @@ def build_transfer_bytes(publicKey, recipient, asset, amount, attachment='', fee binary_data += struct.pack(">I", len(some_transfer_bytes)) binary_data += some_transfer_bytes binary_data += some_transfer_bytes - print(colors.fg.lightgrey + "tx bytes: " + base58.b58encode(str(some_transfer_bytes))) + binary_data += some_transfer_bytes + binary_data += some_transfer_bytes + print(colors.fg.lightgrey + "tx bytes: " + + base58.b58encode(str(some_transfer_bytes))) else: binary_input = base58.b58decode(input) binary_data += struct.pack(">I", len(binary_input)) binary_data += binary_input binary_data += binary_input - print(colors.fg.lightgrey + "tx bytes: " + base58.b58encode(str(binary_input))) - print(colors.fg.lightgrey + "all request bytes: " + base58.b58encode(str(binary_data))) + binary_data += binary_input + binary_data += binary_input + print(colors.fg.lightgrey + "tx bytes: " + + base58.b58encode(str(binary_input))) + print(colors.fg.lightgrey + "all request bytes: " + + base58.b58encode(str(binary_data))) signature = None while (True): try: @@ -318,18 +547,22 @@ def build_transfer_bytes(publicKey, recipient, asset, amount, attachment='', fee if (offset == 0): print("Waiting for approval to sign on the Ledger Nano S") - apdu = bytes("8002".decode('hex')) + chr(p1) + chain_id + chr(len(chunk)) + bytes(chunk) + apdu = bytes("8002".decode('hex')) + chr(p1) + \ + chain_id + chr(len(chunk)) + bytes(chunk) signature = dongle.exchange(apdu) offset += len(chunk) print("signature " + base58.b58encode(str(signature))) break except CommException as e: if (e.sw == 0x6990): - print(colors.fg.red + "Transaction buffer max size reached." + colors.reset) + print(colors.fg.red + + "Transaction buffer max size reached." + colors.reset) if (e.sw == 0x6985): - print(colors.fg.red + "Required condition failed." + colors.reset) + print(colors.fg.red + + "Required condition failed." + colors.reset) if (e.sw == 0x9100): - print(colors.fg.red + "User denied signing request on Ledger Nano S device." + colors.reset) + print( + colors.fg.red + "User denied signing request on Ledger Nano S device." + colors.reset) break except Exception as e: print(e, type(e)) @@ -340,6 +573,328 @@ def build_transfer_bytes(publicKey, recipient, asset, amount, attachment='', fee sys.exc_clear() elif (select == "3"): version = getVersionFromDongle() - print('App version is {}.{}.{}'.format(version[0],version[1],version[2])) + print('App version is {}.{}.{}'.format( + version[0], version[1], version[2])) + elif (select == "4"): + while (True): + print("") + print(colors.fg.lightcyan + colors.bold + + "Ledger Nano S - Waves test app" + colors.reset) + print(colors.fg.lightcyan + colors.bold + + "Test protobuf transactions" + colors.reset) + print(colors.fg.white + "\t 3. Issue" + colors.reset) + print(colors.fg.white + "\t 4. Transfer" + colors.reset) + print(colors.fg.white + "\t 5. Reissue" + colors.reset) + print(colors.fg.white + "\t 6. Burn" + colors.reset) + print(colors.fg.white + "\t 8. Lease" + colors.reset) + print(colors.fg.white + "\t 9. Lease Cancel" + colors.reset) + print(colors.fg.white + "\t 10. Create Alias" + colors.reset) + print(colors.fg.white + "\t 11. MassTransfer" + colors.reset) + print(colors.fg.white + "\t 12. Data" + colors.reset) + print(colors.fg.white + "\t 13. Set Account Script" + colors.reset) + print(colors.fg.white + "\t 14. Sponsor Fee" + colors.reset) + print(colors.fg.white + "\t 15. Set Asset Script" + colors.reset) + print(colors.fg.white + "\t 16. Invoke Script" + colors.reset) + print(colors.fg.white + "\t 17. Update Asset Info" + colors.reset) + print(colors.fg.white + "\t 252. Order" + colors.reset) + print(colors.fg.white + "\t 0. Exit" + colors.reset) + select = raw_input( + colors.fg.cyan + "Please select transaction type> " + colors.reset) + decimals = 8 # tx amount asset decimals + decimals2 = 0 + feeDecimals = 8 # fee amount asset decimals + version = 3 + if (select == "3"): + decimals = 3 + some_transfer_bytes = build_issue_protobuf( + # 3PDCeakWckRvK5vVeJnCy1R2rE1utBcJMwt + '4ovEU8YpbHTurwzw8CDZaCD7m6LpyMTC4nrJcgDHb4Jh', + "Test asset name", + "Test asset description, Test asset description, Test asset description", + 1000000000, + decimals, + True, + pw.Asset('9gqcTyupiDWuogWhKv8G3EMwjMaobkw9Lpys4EY2F62t'), + 100000, + 1526477921829, + version + ) + elif (select == "4"): + decimals = 4 + feeDecimals = 4 + version = 3 + chain_id = 'R' + some_transfer_bytes = build_transfer_protobuf( + # 3M4qwDomRabJKLZxuXhwfqLApQkU592nWxF + 'AXbaBkJNocyrVpwqTzD4TpUY8fQ6eeRto9k1m2bNCzXV', + "Yx1KwZyaRFWaWZALgQ8D1Ft4sdd", # 3P8mkuJyiFvVRLjVNfDvdqVqH92bZZkQtAL + pw.Asset('9Z9DqJz4GbrJiMDHRFdGPz4GdVy6sWzzRQKZARkvsgMp'), + 9223372036854775807, + '', + None, + 100001, + 1600000000000, + version + ) + elif (select == "5"): + decimals = 8 + some_transfer_bytes = build_reissue_protobuf( + # 3PDCeakWckRvK5vVeJnCy1R2rE1utBcJMwt + '4ovEU8YpbHTurwzw8CDZaCD7m6LpyMTC4nrJcgDHb4Jh', + pw.Asset('B3mFpuCTpShBkSNiKaVbKeipktYWufEMAEGvBAdNP6tu'), + 100000000, + True, + pw.Asset('9gqcTyupiDWuogWhKv8G3EMwjMaobkw9Lpys4EY2F62t'), + 100000, + 1526477921829, + version + ) + elif (select == "6"): + decimals = 8 + some_transfer_bytes = build_burn_protobuf( + # 3PDCeakWckRvK5vVeJnCy1R2rE1utBcJMwt + '4ovEU8YpbHTurwzw8CDZaCD7m6LpyMTC4nrJcgDHb4Jh', + pw.Asset('B3mFpuCTpShBkSNiKaVbKeipktYWufEMAEGvBAdNP6tu'), + 1000000000, + pw.Asset('9gqcTyupiDWuogWhKv8G3EMwjMaobkw9Lpys4EY2F62t'), + 100000, + 1526477921829, + version + ) + + elif (select == "8"): + some_transfer_bytes = build_lease_protobuf( + # 3PDCeakWckRvK5vVeJnCy1R2rE1utBcJMwt + '4ovEU8YpbHTurwzw8CDZaCD7m6LpyMTC4nrJcgDHb4Jh', + "23edvPK94JRdmDj7rKwzLbu22Sem", # 3P8mkuJyiFvVRLjVNfDvdqVqH92bZZkQtAL + 100000000000, + pw.Asset('9gqcTyupiDWuogWhKv8G3EMwjMaobkw9Lpys4EY2F62t'), + 100000, + 1526477921829, + version + ) + elif (select == "9"): + some_transfer_bytes = build_cancel_lease_protobuf( + # 3PDCeakWckRvK5vVeJnCy1R2rE1utBcJMwt + '4ovEU8YpbHTurwzw8CDZaCD7m6LpyMTC4nrJcgDHb4Jh', + 'B3mFpuCTpShBkSNiKaVbKeipktYWufEMAEGvBAdNP6tu', + pw.Asset('9gqcTyupiDWuogWhKv8G3EMwjMaobkw9Lpys4EY2F62t'), + 100000, + 1526477921829, + version + ) + elif (select == "10"): + some_transfer_bytes = build_creating_alias_protobuf( + # 3PDCeakWckRvK5vVeJnCy1R2rE1utBcJMwt + '4ovEU8YpbHTurwzw8CDZaCD7m6LpyMTC4nrJcgDHb4Jh', + "Test Alias", + pw.Asset('9gqcTyupiDWuogWhKv8G3EMwjMaobkw9Lpys4EY2F62t'), + 100000, + 1526477921829, + version + ) + elif (select == "11"): + version = 2 + some_transfer_bytes = build_masstransfer_protobuf( + # 3PDCeakWckRvK5vVeJnCy1R2rE1utBcJMwt + '4ovEU8YpbHTurwzw8CDZaCD7m6LpyMTC4nrJcgDHb4Jh', + "23edvPK94JRdmDj7rKwzLbu22Sem", # 3P8mkuJyiFvVRLjVNfDvdqVqH92bZZkQtAL + pw.Asset('B3mFpuCTpShBkSNiKaVbKeipktYWufEMAEGvBAdNP6tu'), + 10000000, + 'privet0000privet0000privet0000privet0000privet0000privet0000privet0000privet0000privet0000privet0000privet0000', + pw.Asset('9gqcTyupiDWuogWhKv8G3EMwjMaobkw9Lpys4EY2F62t'), + 100000, + 1526477921829, + version + ) + elif (select == "12"): + version = 2 + some_transfer_bytes = build_data_protobuf( + # 3PDCeakWckRvK5vVeJnCy1R2rE1utBcJMwt + '4ovEU8YpbHTurwzw8CDZaCD7m6LpyMTC4nrJcgDHb4Jh', + pw.Asset('9gqcTyupiDWuogWhKv8G3EMwjMaobkw9Lpys4EY2F62t'), + 100000, + 1526477921829, + version + ) + elif (select == "13"): + version = 2 + script = base64.b64decode("AAIDAAAAAAAAAAYIARIAEgAAAAAEAAAAAAVscEtleQIAAAALbGFzdFBheW1lbnQAAAAABWxpS2V5AgAAAApiZXN0Rm9tb2VyAAAAAAVsaEtleQIAAAAGaGVpZ2h0AAAAAANkYXkAAAAAAAAABaAAAAACAAAAAWkBAAAAC2ZlYXJtaXNzaW5nAAAAAAQAAAAHcGF5bWVudAQAAAAHJG1hdGNoMAgFAAAAAWkAAAAHcGF5bWVudAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAPQXR0YWNoZWRQYXltZW50BAAAAAFwBQAAAAckbWF0Y2gwBAAAAAckbWF0Y2gxCAUAAAABcAAAAAdhc3NldElkAwkAAAEAAAACBQAAAAckbWF0Y2gxAgAAAApCeXRlVmVjdG9yBAAAAAdhc3NldElkBQAAAAckbWF0Y2gxCQAAAgAAAAECAAAAD2ZvbW8gd2F2ZXMgb25seQgFAAAAAXAAAAAGYW1vdW50CQAAAgAAAAECAAAAGHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQAAAALbGFzdFBheW1lbnQEAAAAByRtYXRjaDAJAAQaAAAAAgUAAAAEdGhpcwIAAAALbGFzdFBheW1lbnQDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAA0ludAQAAAABcAUAAAAHJG1hdGNoMAUAAAABcAAAAAAAAAAAAAMJAABnAAAAAgUAAAALbGFzdFBheW1lbnQFAAAAB3BheW1lbnQJAAACAAAAAQkAASwAAAACAgAAAA9taW4gcGF5bWVudCBpcyAJAAGkAAAAAQUAAAAHcGF5bWVudAkBAAAACFdyaXRlU2V0AAAAAQkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgUAAAAFbHBLZXkFAAAAB3BheW1lbnQJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIFAAAABWxpS2V5CAgFAAAAAWkAAAAGY2FsbGVyAAAABWJ5dGVzCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACBQAAAAVsaEtleQUAAAAGaGVpZ2h0BQAAAANuaWwAAAABaQEAAAAId2l0aGRyYXcAAAAABAAAAA1jYWxsZXJDb3JyZWN0CQAAAAAAAAIICAUAAAABaQAAAAZjYWxsZXIAAAAFYnl0ZXMJAQAAAAdleHRyYWN0AAAAAQkABBwAAAACBQAAAAR0aGlzBQAAAAVsaUtleQQAAAANaGVpZ2h0Q29ycmVjdAkAAGcAAAACCQAAZQAAAAIJAQAAAAdleHRyYWN0AAAAAQkABBoAAAACBQAAAAR0aGlzBQAAAAVsaEtleQUAAAAGaGVpZ2h0BQAAAANkYXkEAAAAC2NhbldpdGhkcmF3AwUAAAANaGVpZ2h0Q29ycmVjdAUAAAANY2FsbGVyQ29ycmVjdAcDBQAAAAtjYW5XaXRoZHJhdwkBAAAAC1RyYW5zZmVyU2V0AAAAAQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIJAQAAAAx3YXZlc0JhbGFuY2UAAAABBQAAAAR0aGlzBQAAAAR1bml0BQAAAANuaWwJAAACAAAAAQIAAAAGYmVob2xkAAAAACSiqig=") + some_transfer_bytes = build_set_ac_script_protobuf( + # 3PDCeakWckRvK5vVeJnCy1R2rE1utBcJMwt + '4ovEU8YpbHTurwzw8CDZaCD7m6LpyMTC4nrJcgDHb4Jh', + script, + pw.Asset('9gqcTyupiDWuogWhKv8G3EMwjMaobkw9Lpys4EY2F62t'), + 100000, + 1526477921829, + version + ) + elif (select == "14"): + decimals = 6 + version = 2 + some_transfer_bytes = build_sponsorship_protobuf( + # 3PDCeakWckRvK5vVeJnCy1R2rE1utBcJMwt + '4ovEU8YpbHTurwzw8CDZaCD7m6LpyMTC4nrJcgDHb4Jh', + pw.Asset('51LxAtwBXapvvTFSbbh4nLyWFxH6x8ocfNvrXxbTChze'), + 10000, + pw.Asset('9gqcTyupiDWuogWhKv8G3EMwjMaobkw9Lpys4EY2F62t'), + 100000, + 1526477921829, + version + ) + elif (select == "15"): + version = 2 + script = base64.b64decode("AAIDAAAAAAAAAAYIARIAEgAAAAAEAAAAAAVscEtleQIAAAALbGFzdFBheW1lbnQAAAAABWxpS2V5AgAAAApiZXN0Rm9tb2VyAAAAAAVsaEtleQIAAAAGaGVpZ2h0AAAAAANkYXkAAAAAAAAABaAAAAACAAAAAWkBAAAAC2ZlYXJtaXNzaW5nAAAAAAQAAAAHcGF5bWVudAQAAAAHJG1hdGNoMAgFAAAAAWkAAAAHcGF5bWVudAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAPQXR0YWNoZWRQYXltZW50BAAAAAFwBQAAAAckbWF0Y2gwBAAAAAckbWF0Y2gxCAUAAAABcAAAAAdhc3NldElkAwkAAAEAAAACBQAAAAckbWF0Y2gxAgAAAApCeXRlVmVjdG9yBAAAAAdhc3NldElkBQAAAAckbWF0Y2gxCQAAAgAAAAECAAAAD2ZvbW8gd2F2ZXMgb25seQgFAAAAAXAAAAAGYW1vdW50CQAAAgAAAAECAAAAGHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQAAAALbGFzdFBheW1lbnQEAAAAByRtYXRjaDAJAAQaAAAAAgUAAAAEdGhpcwIAAAALbGFzdFBheW1lbnQDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAA0ludAQAAAABcAUAAAAHJG1hdGNoMAUAAAABcAAAAAAAAAAAAAMJAABnAAAAAgUAAAALbGFzdFBheW1lbnQFAAAAB3BheW1lbnQJAAACAAAAAQkAASwAAAACAgAAAA9taW4gcGF5bWVudCBpcyAJAAGkAAAAAQUAAAAHcGF5bWVudAkBAAAACFdyaXRlU2V0AAAAAQkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgUAAAAFbHBLZXkFAAAAB3BheW1lbnQJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIFAAAABWxpS2V5CAgFAAAAAWkAAAAGY2FsbGVyAAAABWJ5dGVzCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACBQAAAAVsaEtleQUAAAAGaGVpZ2h0BQAAAANuaWwAAAABaQEAAAAId2l0aGRyYXcAAAAABAAAAA1jYWxsZXJDb3JyZWN0CQAAAAAAAAIICAUAAAABaQAAAAZjYWxsZXIAAAAFYnl0ZXMJAQAAAAdleHRyYWN0AAAAAQkABBwAAAACBQAAAAR0aGlzBQAAAAVsaUtleQQAAAANaGVpZ2h0Q29ycmVjdAkAAGcAAAACCQAAZQAAAAIJAQAAAAdleHRyYWN0AAAAAQkABBoAAAACBQAAAAR0aGlzBQAAAAVsaEtleQUAAAAGaGVpZ2h0BQAAAANkYXkEAAAAC2NhbldpdGhkcmF3AwUAAAANaGVpZ2h0Q29ycmVjdAUAAAANY2FsbGVyQ29ycmVjdAcDBQAAAAtjYW5XaXRoZHJhdwkBAAAAC1RyYW5zZmVyU2V0AAAAAQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIJAQAAAAx3YXZlc0JhbGFuY2UAAAABBQAAAAR0aGlzBQAAAAR1bml0BQAAAANuaWwJAAACAAAAAQIAAAAGYmVob2xkAAAAACSiqig=") + some_transfer_bytes = build_set_as_script_protobuf( + # 3PDCeakWckRvK5vVeJnCy1R2rE1utBcJMwt + '4ovEU8YpbHTurwzw8CDZaCD7m6LpyMTC4nrJcgDHb4Jh', + pw.Asset('51LxAtwBXapvvTFSbbh4nLyWFxH6x8ocfNvrXxbTChze'), + script, + pw.Asset('9gqcTyupiDWuogWhKv8G3EMwjMaobkw9Lpys4EY2F62t'), + 100000, + 1526477921829, + version + ) + elif (select == "16"): + version = 2 + fname = "function_name" + function_call = chr( + 2) + chr(2) + "argument1".encode() + chr(2) + "argument2".encode() + fcal = chr(1) + chr(9) + chr(1) + struct.pack(">I", + len(fname)) + fname.encode() + function_call + decimals = 6 + decimals2 = 8 + some_transfer_bytes = build_invoke_protobuf( + # 3PDCeakWckRvK5vVeJnCy1R2rE1utBcJMwt + '4ovEU8YpbHTurwzw8CDZaCD7m6LpyMTC4nrJcgDHb4Jh', + "23edvPK94JRdmDj7rKwzLbu22Sem", # 3P8mkuJyiFvVRLjVNfDvdqVqH92bZZkQtAL + fcal, + pw.Asset('51LxAtwBXapvvTFSbbh4nLyWFxH6x8ocfNvrXxbTChze'), + 1000000, + pw.Asset('9gqcTyupiDWuogWhKv8G3EMwjMaobkw9Lpys4EY2F62t'), + 1000000000, + pw.Asset('51LxAtwBXapvvTFSbbh4nLyWFxH6x8ocfNvrXxbTChze'), + 1000000, + 1526477921829, + version + ) + + elif (select == "17"): + version = 1 + some_transfer_bytes = build_update_asset_protobuf( + # 3PDCeakWckRvK5vVeJnCy1R2rE1utBcJMwt + '4ovEU8YpbHTurwzw8CDZaCD7m6LpyMTC4nrJcgDHb4Jh', + pw.Asset('51LxAtwBXapvvTFSbbh4nLyWFxH6x8ocfNvrXxbTChze'), + "Test name 1", + "Test descr", + pw.Asset('9gqcTyupiDWuogWhKv8G3EMwjMaobkw9Lpys4EY2F62t'), + 100000, + 1526477921829, + version + ) + elif(select == "252"): + version = 4 + some_transfer_bytes = build_order_protobuf( + # 3PDCeakWckRvK5vVeJnCy1R2rE1utBcJMwt + '4ovEU8YpbHTurwzw8CDZaCD7m6LpyMTC4nrJcgDHb4Jh', + # 3P8mkuJyiFvVRLjVNfDvdqVqH92bZZkQtAL + "8f9MUt5QXBBC11Yu4LcfWSdgdUSZBbvXATDfykQymmLe", + pw.Asset('51LxAtwBXapvvTFSbbh4nLyWFxH6x8ocfNvrXxbTChze'), + pw.Asset('9gqcTyupiDWuogWhKv8G3EMwjMaobkw9Lpys4EY2F62t'), + 1, # sell + 1000000, + 100, + 1526477921829, + 1526477921829, + '', # waves + 100000, + version + ) + else: + break + + path = raw_input( + colors.fg.lightblue + "Please input BIP-32 path (for example \"44'/5741564'/0'/0'/1'\")> " + colors.reset) + if len(path) == 0: + path = "44'/5741564'/0'/0'/1'" + binary_data = path_to_bytes(expand_path(path)) + print(colors.fg.lightgrey + "path bytes: " + + base58.b58encode(str(path_to_bytes(expand_path(path))))) + # tx amount asset decimals + binary_data += chr(decimals) + # tx amount2 asset decimals + binary_data += chr(decimals2) + # fee amount asset decimals + binary_data += chr(feeDecimals) + + #some_transfer_bytes = base58.b58decode("uq4YDsWuUhQ2ajpzvHxWeikWkF8XodVWi8F1VdYsqFESLGc2k6g5UvtxVrER4a") + #some_transfer_bytes = base58.b58decode("c4wP1kugNdzm3Sm88YVaJ3dVZ73S1RshSZNxvqmCZbQUW5yDSCGuXVK666EwipM4yqoA7EeDzseLjSDRQFaoG7pcGvSMrHEqVxw8z3qoBb3zjEvpMhFG598koLXBTZS8RXvN4U4LLJpUcEnqAbDrM4jeUwcYkqekMM3Mbm8tWAaTUbwHgE4DbUPoUid3xncWovvcZ5j9RBExrKpNhxmN1YDS2mwK59GnN4KxUxMnwAuQ5dgrbkAnDGCV9TjeJemj6eCLHKr6mhGUns7W69fRioUmJMADbkYTvgJe1nFgG5n8GiavNfDeCNKD8CYjwZBgZtRZma88pcfAtgBG293JTgcBgSdJWAMTT5J4B5URhrJWyF3mNdq6rbumTGWTGpA8HgYEPA2VgD6EGRprm1DYwdr8UD7HEx2gzDTV6A31") + input = raw_input(colors.fg.lightblue + "Please input message to sign (for example \"" + base58.b58encode( + str(some_transfer_bytes)) + "\")> " + colors.reset) + if len(input) == 0: + # 2 first bytes aren't the tx data, but info type for the ledger + binary_data += chr(int(select)) + chr(version) + binary_data += struct.pack(">I", len(some_transfer_bytes)) + binary_data += some_transfer_bytes + binary_data += some_transfer_bytes + binary_data += some_transfer_bytes + binary_data += some_transfer_bytes + print(colors.fg.lightgrey + "tx bytes: " + + base58.b58encode(str(some_transfer_bytes))) + else: + binary_input = base58.b58decode(input) + binary_data += struct.pack(">I", len(binary_input)) + binary_data += binary_input + binary_data += binary_input + binary_data += binary_input + binary_data += binary_input + print(colors.fg.lightgrey + "tx bytes: " + + base58.b58encode(str(binary_input))) + print(colors.fg.lightgrey + "all request bytes: " + + base58.b58encode(str(binary_data))) + + signature = None + while (True): + try: + offset = 0 + while offset != len(binary_data): + if (len(binary_data) - offset) > CHUNK_SIZE: + chunk = binary_data[offset: offset + CHUNK_SIZE] + else: + chunk = binary_data[offset:] + if (offset + len(chunk)) == len(binary_data): + p1 = 0x80 + else: + p1 = 0x00 + + if (offset == 0): + print( + "Waiting for approval to sign on the Ledger Nano S") + + apdu = bytes("8002".decode('hex')) + chr(p1) + \ + chain_id + chr(len(chunk)) + bytes(chunk) + signature = dongle.exchange(apdu) + offset += len(chunk) + + print("signature " + base58.b58encode(str(signature))) + break + except CommException as e: + if (e.sw == 0x6990): + print( + colors.fg.red + "Transaction buffer max size reached." + colors.reset) + if (e.sw == 0x6985): + print(colors.fg.red + + "Required condition failed." + colors.reset) + if (e.sw == 0x9100): + print( + colors.fg.red + "User denied signing request on Ledger Nano S device." + colors.reset) + break + except Exception as e: + print(e, type(e)) + answer = raw_input( + "Please connect your Ledger Nano S, unlock, and launch the Waves app. Press when ready. (Q quits)") + if (answer.upper() == 'Q'): + sys.exit(0) + sys.exc_clear() else: break diff --git a/python/nanopb_pb2.py b/python/nanopb_pb2.py new file mode 100644 index 00000000..2d7f0be9 --- /dev/null +++ b/python/nanopb_pb2.py @@ -0,0 +1,467 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: nanopb.proto + +from google.protobuf.internal import enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='nanopb.proto', + package='', + syntax='proto2', + serialized_options=b'\n\030fi.kapsi.koti.jpa.nanopb', + serialized_pb=b'\n\x0cnanopb.proto\x1a google/protobuf/descriptor.proto\"\xd9\x06\n\rNanoPBOptions\x12\x10\n\x08max_size\x18\x01 \x01(\x05\x12\x12\n\nmax_length\x18\x0e \x01(\x05\x12\x11\n\tmax_count\x18\x02 \x01(\x05\x12&\n\x08int_size\x18\x07 \x01(\x0e\x32\x08.IntSize:\nIS_DEFAULT\x12$\n\x04type\x18\x03 \x01(\x0e\x32\n.FieldType:\nFT_DEFAULT\x12\x18\n\nlong_names\x18\x04 \x01(\x08:\x04true\x12\x1c\n\rpacked_struct\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0bpacked_enum\x18\n \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0cskip_message\x18\x06 \x01(\x08:\x05\x66\x61lse\x12\x18\n\tno_unions\x18\x08 \x01(\x08:\x05\x66\x61lse\x12\r\n\x05msgid\x18\t \x01(\r\x12\x1e\n\x0f\x61nonymous_oneof\x18\x0b \x01(\x08:\x05\x66\x61lse\x12\x15\n\x06proto3\x18\x0c \x01(\x08:\x05\x66\x61lse\x12#\n\x14proto3_singular_msgs\x18\x15 \x01(\x08:\x05\x66\x61lse\x12\x1d\n\x0e\x65num_to_string\x18\r \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0c\x66ixed_length\x18\x0f \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0b\x66ixed_count\x18\x10 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x0fsubmsg_callback\x18\x16 \x01(\x08:\x05\x66\x61lse\x12/\n\x0cmangle_names\x18\x11 \x01(\x0e\x32\x11.TypenameMangling:\x06M_NONE\x12(\n\x11\x63\x61llback_datatype\x18\x12 \x01(\t:\rpb_callback_t\x12\x34\n\x11\x63\x61llback_function\x18\x13 \x01(\t:\x19pb_default_field_callback\x12\x30\n\x0e\x64\x65scriptorsize\x18\x14 \x01(\x0e\x32\x0f.DescriptorSize:\x07\x44S_AUTO\x12\x1a\n\x0b\x64\x65\x66\x61ult_has\x18\x17 \x01(\x08:\x05\x66\x61lse\x12\x0f\n\x07include\x18\x18 \x03(\t\x12\x0f\n\x07\x65xclude\x18\x1a \x03(\t\x12\x0f\n\x07package\x18\x19 \x01(\t\x12\x41\n\rtype_override\x18\x1b \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.Type*i\n\tFieldType\x12\x0e\n\nFT_DEFAULT\x10\x00\x12\x0f\n\x0b\x46T_CALLBACK\x10\x01\x12\x0e\n\nFT_POINTER\x10\x04\x12\r\n\tFT_STATIC\x10\x02\x12\r\n\tFT_IGNORE\x10\x03\x12\r\n\tFT_INLINE\x10\x05*D\n\x07IntSize\x12\x0e\n\nIS_DEFAULT\x10\x00\x12\x08\n\x04IS_8\x10\x08\x12\t\n\x05IS_16\x10\x10\x12\t\n\x05IS_32\x10 \x12\t\n\x05IS_64\x10@*Z\n\x10TypenameMangling\x12\n\n\x06M_NONE\x10\x00\x12\x13\n\x0fM_STRIP_PACKAGE\x10\x01\x12\r\n\tM_FLATTEN\x10\x02\x12\x16\n\x12M_PACKAGE_INITIALS\x10\x03*E\n\x0e\x44\x65scriptorSize\x12\x0b\n\x07\x44S_AUTO\x10\x00\x12\x08\n\x04\x44S_1\x10\x01\x12\x08\n\x04\x44S_2\x10\x02\x12\x08\n\x04\x44S_4\x10\x04\x12\x08\n\x04\x44S_8\x10\x08:E\n\x0enanopb_fileopt\x12\x1c.google.protobuf.FileOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:G\n\rnanopb_msgopt\x12\x1f.google.protobuf.MessageOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:E\n\x0enanopb_enumopt\x12\x1c.google.protobuf.EnumOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:>\n\x06nanopb\x12\x1d.google.protobuf.FieldOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptionsB\x1a\n\x18\x66i.kapsi.koti.jpa.nanopb' + , + dependencies=[google_dot_protobuf_dot_descriptor__pb2.DESCRIPTOR,]) + +_FIELDTYPE = _descriptor.EnumDescriptor( + name='FieldType', + full_name='FieldType', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='FT_DEFAULT', index=0, number=0, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='FT_CALLBACK', index=1, number=1, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='FT_POINTER', index=2, number=4, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='FT_STATIC', index=3, number=2, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='FT_IGNORE', index=4, number=3, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='FT_INLINE', index=5, number=5, + serialized_options=None, + type=None), + ], + containing_type=None, + serialized_options=None, + serialized_start=910, + serialized_end=1015, +) +_sym_db.RegisterEnumDescriptor(_FIELDTYPE) + +FieldType = enum_type_wrapper.EnumTypeWrapper(_FIELDTYPE) +_INTSIZE = _descriptor.EnumDescriptor( + name='IntSize', + full_name='IntSize', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='IS_DEFAULT', index=0, number=0, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='IS_8', index=1, number=8, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='IS_16', index=2, number=16, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='IS_32', index=3, number=32, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='IS_64', index=4, number=64, + serialized_options=None, + type=None), + ], + containing_type=None, + serialized_options=None, + serialized_start=1017, + serialized_end=1085, +) +_sym_db.RegisterEnumDescriptor(_INTSIZE) + +IntSize = enum_type_wrapper.EnumTypeWrapper(_INTSIZE) +_TYPENAMEMANGLING = _descriptor.EnumDescriptor( + name='TypenameMangling', + full_name='TypenameMangling', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='M_NONE', index=0, number=0, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='M_STRIP_PACKAGE', index=1, number=1, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='M_FLATTEN', index=2, number=2, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='M_PACKAGE_INITIALS', index=3, number=3, + serialized_options=None, + type=None), + ], + containing_type=None, + serialized_options=None, + serialized_start=1087, + serialized_end=1177, +) +_sym_db.RegisterEnumDescriptor(_TYPENAMEMANGLING) + +TypenameMangling = enum_type_wrapper.EnumTypeWrapper(_TYPENAMEMANGLING) +_DESCRIPTORSIZE = _descriptor.EnumDescriptor( + name='DescriptorSize', + full_name='DescriptorSize', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='DS_AUTO', index=0, number=0, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='DS_1', index=1, number=1, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='DS_2', index=2, number=2, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='DS_4', index=3, number=4, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='DS_8', index=4, number=8, + serialized_options=None, + type=None), + ], + containing_type=None, + serialized_options=None, + serialized_start=1179, + serialized_end=1248, +) +_sym_db.RegisterEnumDescriptor(_DESCRIPTORSIZE) + +DescriptorSize = enum_type_wrapper.EnumTypeWrapper(_DESCRIPTORSIZE) +FT_DEFAULT = 0 +FT_CALLBACK = 1 +FT_POINTER = 4 +FT_STATIC = 2 +FT_IGNORE = 3 +FT_INLINE = 5 +IS_DEFAULT = 0 +IS_8 = 8 +IS_16 = 16 +IS_32 = 32 +IS_64 = 64 +M_NONE = 0 +M_STRIP_PACKAGE = 1 +M_FLATTEN = 2 +M_PACKAGE_INITIALS = 3 +DS_AUTO = 0 +DS_1 = 1 +DS_2 = 2 +DS_4 = 4 +DS_8 = 8 + +NANOPB_FILEOPT_FIELD_NUMBER = 1010 +nanopb_fileopt = _descriptor.FieldDescriptor( + name='nanopb_fileopt', full_name='nanopb_fileopt', index=0, + number=1010, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=True, extension_scope=None, + serialized_options=None, file=DESCRIPTOR) +NANOPB_MSGOPT_FIELD_NUMBER = 1010 +nanopb_msgopt = _descriptor.FieldDescriptor( + name='nanopb_msgopt', full_name='nanopb_msgopt', index=1, + number=1010, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=True, extension_scope=None, + serialized_options=None, file=DESCRIPTOR) +NANOPB_ENUMOPT_FIELD_NUMBER = 1010 +nanopb_enumopt = _descriptor.FieldDescriptor( + name='nanopb_enumopt', full_name='nanopb_enumopt', index=2, + number=1010, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=True, extension_scope=None, + serialized_options=None, file=DESCRIPTOR) +NANOPB_FIELD_NUMBER = 1010 +nanopb = _descriptor.FieldDescriptor( + name='nanopb', full_name='nanopb', index=3, + number=1010, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=True, extension_scope=None, + serialized_options=None, file=DESCRIPTOR) + + +_NANOPBOPTIONS = _descriptor.Descriptor( + name='NanoPBOptions', + full_name='NanoPBOptions', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='max_size', full_name='NanoPBOptions.max_size', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='max_length', full_name='NanoPBOptions.max_length', index=1, + number=14, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='max_count', full_name='NanoPBOptions.max_count', index=2, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='int_size', full_name='NanoPBOptions.int_size', index=3, + number=7, type=14, cpp_type=8, label=1, + has_default_value=True, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='type', full_name='NanoPBOptions.type', index=4, + number=3, type=14, cpp_type=8, label=1, + has_default_value=True, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='long_names', full_name='NanoPBOptions.long_names', index=5, + number=4, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=True, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='packed_struct', full_name='NanoPBOptions.packed_struct', index=6, + number=5, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='packed_enum', full_name='NanoPBOptions.packed_enum', index=7, + number=10, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='skip_message', full_name='NanoPBOptions.skip_message', index=8, + number=6, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='no_unions', full_name='NanoPBOptions.no_unions', index=9, + number=8, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='msgid', full_name='NanoPBOptions.msgid', index=10, + number=9, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='anonymous_oneof', full_name='NanoPBOptions.anonymous_oneof', index=11, + number=11, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='proto3', full_name='NanoPBOptions.proto3', index=12, + number=12, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='proto3_singular_msgs', full_name='NanoPBOptions.proto3_singular_msgs', index=13, + number=21, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='enum_to_string', full_name='NanoPBOptions.enum_to_string', index=14, + number=13, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='fixed_length', full_name='NanoPBOptions.fixed_length', index=15, + number=15, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='fixed_count', full_name='NanoPBOptions.fixed_count', index=16, + number=16, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='submsg_callback', full_name='NanoPBOptions.submsg_callback', index=17, + number=22, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='mangle_names', full_name='NanoPBOptions.mangle_names', index=18, + number=17, type=14, cpp_type=8, label=1, + has_default_value=True, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='callback_datatype', full_name='NanoPBOptions.callback_datatype', index=19, + number=18, type=9, cpp_type=9, label=1, + has_default_value=True, default_value=b"pb_callback_t".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='callback_function', full_name='NanoPBOptions.callback_function', index=20, + number=19, type=9, cpp_type=9, label=1, + has_default_value=True, default_value=b"pb_default_field_callback".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='descriptorsize', full_name='NanoPBOptions.descriptorsize', index=21, + number=20, type=14, cpp_type=8, label=1, + has_default_value=True, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='default_has', full_name='NanoPBOptions.default_has', index=22, + number=23, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='include', full_name='NanoPBOptions.include', index=23, + number=24, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='exclude', full_name='NanoPBOptions.exclude', index=24, + number=26, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='package', full_name='NanoPBOptions.package', index=25, + number=25, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='type_override', full_name='NanoPBOptions.type_override', index=26, + number=27, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=1, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto2', + extension_ranges=[], + oneofs=[ + ], + serialized_start=51, + serialized_end=908, +) + +_NANOPBOPTIONS.fields_by_name['int_size'].enum_type = _INTSIZE +_NANOPBOPTIONS.fields_by_name['type'].enum_type = _FIELDTYPE +_NANOPBOPTIONS.fields_by_name['mangle_names'].enum_type = _TYPENAMEMANGLING +_NANOPBOPTIONS.fields_by_name['descriptorsize'].enum_type = _DESCRIPTORSIZE +_NANOPBOPTIONS.fields_by_name['type_override'].enum_type = google_dot_protobuf_dot_descriptor__pb2._FIELDDESCRIPTORPROTO_TYPE +DESCRIPTOR.message_types_by_name['NanoPBOptions'] = _NANOPBOPTIONS +DESCRIPTOR.enum_types_by_name['FieldType'] = _FIELDTYPE +DESCRIPTOR.enum_types_by_name['IntSize'] = _INTSIZE +DESCRIPTOR.enum_types_by_name['TypenameMangling'] = _TYPENAMEMANGLING +DESCRIPTOR.enum_types_by_name['DescriptorSize'] = _DESCRIPTORSIZE +DESCRIPTOR.extensions_by_name['nanopb_fileopt'] = nanopb_fileopt +DESCRIPTOR.extensions_by_name['nanopb_msgopt'] = nanopb_msgopt +DESCRIPTOR.extensions_by_name['nanopb_enumopt'] = nanopb_enumopt +DESCRIPTOR.extensions_by_name['nanopb'] = nanopb +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +NanoPBOptions = _reflection.GeneratedProtocolMessageType('NanoPBOptions', (_message.Message,), { + 'DESCRIPTOR' : _NANOPBOPTIONS, + '__module__' : 'nanopb_pb2' + # @@protoc_insertion_point(class_scope:NanoPBOptions) + }) +_sym_db.RegisterMessage(NanoPBOptions) + +nanopb_fileopt.message_type = _NANOPBOPTIONS +google_dot_protobuf_dot_descriptor__pb2.FileOptions.RegisterExtension(nanopb_fileopt) +nanopb_msgopt.message_type = _NANOPBOPTIONS +google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(nanopb_msgopt) +nanopb_enumopt.message_type = _NANOPBOPTIONS +google_dot_protobuf_dot_descriptor__pb2.EnumOptions.RegisterExtension(nanopb_enumopt) +nanopb.message_type = _NANOPBOPTIONS +google_dot_protobuf_dot_descriptor__pb2.FieldOptions.RegisterExtension(nanopb) + +DESCRIPTOR._options = None +# @@protoc_insertion_point(module_scope) diff --git a/python/order_pb2.py b/python/order_pb2.py new file mode 100644 index 00000000..2feffdd0 --- /dev/null +++ b/python/order_pb2.py @@ -0,0 +1,221 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: order.proto + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import amount_pb2 as amount__pb2 + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='order.proto', + package='waves', + syntax='proto3', + serialized_options=b'\n com.wavesplatform.protobuf.order\252\002\005Waves', + serialized_pb=b'\n\x0border.proto\x12\x05waves\x1a\x0c\x61mount.proto\"<\n\tAssetPair\x12\x17\n\x0f\x61mount_asset_id\x18\x01 \x01(\x0c\x12\x16\n\x0eprice_asset_id\x18\x02 \x01(\x0c\"\xc3\x02\n\x05Order\x12\x10\n\x08\x63hain_id\x18\x01 \x01(\x05\x12\x19\n\x11sender_public_key\x18\x02 \x01(\x0c\x12\x1a\n\x12matcher_public_key\x18\x03 \x01(\x0c\x12$\n\nasset_pair\x18\x04 \x01(\x0b\x32\x10.waves.AssetPair\x12%\n\norder_side\x18\x05 \x01(\x0e\x32\x11.waves.Order.Side\x12\x0e\n\x06\x61mount\x18\x06 \x01(\x03\x12\r\n\x05price\x18\x07 \x01(\x03\x12\x11\n\ttimestamp\x18\x08 \x01(\x03\x12\x12\n\nexpiration\x18\t \x01(\x03\x12\"\n\x0bmatcher_fee\x18\n \x01(\x0b\x32\r.waves.Amount\x12\x0f\n\x07version\x18\x0b \x01(\x05\x12\x0e\n\x06proofs\x18\x0c \x03(\x0c\"\x19\n\x04Side\x12\x07\n\x03\x42UY\x10\x00\x12\x08\n\x04SELL\x10\x01\x42*\n com.wavesplatform.protobuf.order\xaa\x02\x05Wavesb\x06proto3' + , + dependencies=[amount__pb2.DESCRIPTOR,]) + + + +_ORDER_SIDE = _descriptor.EnumDescriptor( + name='Side', + full_name='waves.Order.Side', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='BUY', index=0, number=0, + serialized_options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='SELL', index=1, number=1, + serialized_options=None, + type=None), + ], + containing_type=None, + serialized_options=None, + serialized_start=397, + serialized_end=422, +) +_sym_db.RegisterEnumDescriptor(_ORDER_SIDE) + + +_ASSETPAIR = _descriptor.Descriptor( + name='AssetPair', + full_name='waves.AssetPair', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='amount_asset_id', full_name='waves.AssetPair.amount_asset_id', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='price_asset_id', full_name='waves.AssetPair.price_asset_id', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=36, + serialized_end=96, +) + + +_ORDER = _descriptor.Descriptor( + name='Order', + full_name='waves.Order', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='chain_id', full_name='waves.Order.chain_id', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='sender_public_key', full_name='waves.Order.sender_public_key', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='matcher_public_key', full_name='waves.Order.matcher_public_key', index=2, + number=3, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='asset_pair', full_name='waves.Order.asset_pair', index=3, + number=4, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='order_side', full_name='waves.Order.order_side', index=4, + number=5, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='amount', full_name='waves.Order.amount', index=5, + number=6, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='price', full_name='waves.Order.price', index=6, + number=7, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='timestamp', full_name='waves.Order.timestamp', index=7, + number=8, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='expiration', full_name='waves.Order.expiration', index=8, + number=9, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='matcher_fee', full_name='waves.Order.matcher_fee', index=9, + number=10, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='version', full_name='waves.Order.version', index=10, + number=11, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='proofs', full_name='waves.Order.proofs', index=11, + number=12, type=12, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _ORDER_SIDE, + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=99, + serialized_end=422, +) + +_ORDER.fields_by_name['asset_pair'].message_type = _ASSETPAIR +_ORDER.fields_by_name['order_side'].enum_type = _ORDER_SIDE +_ORDER.fields_by_name['matcher_fee'].message_type = amount__pb2._AMOUNT +_ORDER_SIDE.containing_type = _ORDER +DESCRIPTOR.message_types_by_name['AssetPair'] = _ASSETPAIR +DESCRIPTOR.message_types_by_name['Order'] = _ORDER +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +AssetPair = _reflection.GeneratedProtocolMessageType('AssetPair', (_message.Message,), { + 'DESCRIPTOR' : _ASSETPAIR, + '__module__' : 'order_pb2' + # @@protoc_insertion_point(class_scope:waves.AssetPair) + }) +_sym_db.RegisterMessage(AssetPair) + +Order = _reflection.GeneratedProtocolMessageType('Order', (_message.Message,), { + 'DESCRIPTOR' : _ORDER, + '__module__' : 'order_pb2' + # @@protoc_insertion_point(class_scope:waves.Order) + }) +_sym_db.RegisterMessage(Order) + + +DESCRIPTOR._options = None +# @@protoc_insertion_point(module_scope) diff --git a/python/recipient_pb2.py b/python/recipient_pb2.py new file mode 100644 index 00000000..3bea0040 --- /dev/null +++ b/python/recipient_pb2.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: recipient.proto + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='recipient.proto', + package='waves', + syntax='proto3', + serialized_options=b'\n&com.wavesplatform.protobuf.transaction\252\002\005Waves', + serialized_pb=b'\n\x0frecipient.proto\x12\x05waves\"D\n\tRecipient\x12\x19\n\x0fpublic_key_hash\x18\x01 \x01(\x0cH\x00\x12\x0f\n\x05\x61lias\x18\x02 \x01(\tH\x00\x42\x0b\n\trecipientB0\n&com.wavesplatform.protobuf.transaction\xaa\x02\x05Wavesb\x06proto3' +) + + + + +_RECIPIENT = _descriptor.Descriptor( + name='Recipient', + full_name='waves.Recipient', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='public_key_hash', full_name='waves.Recipient.public_key_hash', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='alias', full_name='waves.Recipient.alias', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + _descriptor.OneofDescriptor( + name='recipient', full_name='waves.Recipient.recipient', + index=0, containing_type=None, fields=[]), + ], + serialized_start=26, + serialized_end=94, +) + +_RECIPIENT.oneofs_by_name['recipient'].fields.append( + _RECIPIENT.fields_by_name['public_key_hash']) +_RECIPIENT.fields_by_name['public_key_hash'].containing_oneof = _RECIPIENT.oneofs_by_name['recipient'] +_RECIPIENT.oneofs_by_name['recipient'].fields.append( + _RECIPIENT.fields_by_name['alias']) +_RECIPIENT.fields_by_name['alias'].containing_oneof = _RECIPIENT.oneofs_by_name['recipient'] +DESCRIPTOR.message_types_by_name['Recipient'] = _RECIPIENT +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +Recipient = _reflection.GeneratedProtocolMessageType('Recipient', (_message.Message,), { + 'DESCRIPTOR' : _RECIPIENT, + '__module__' : 'recipient_pb2' + # @@protoc_insertion_point(class_scope:waves.Recipient) + }) +_sym_db.RegisterMessage(Recipient) + + +DESCRIPTOR._options = None +# @@protoc_insertion_point(module_scope) diff --git a/python/transaction_pb2.py b/python/transaction_pb2.py new file mode 100644 index 00000000..1d2ad681 --- /dev/null +++ b/python/transaction_pb2.py @@ -0,0 +1,1300 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: transaction.proto + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +import nanopb_pb2 as nanopb__pb2 +import amount_pb2 as amount__pb2 +import recipient_pb2 as recipient__pb2 +import order_pb2 as order__pb2 + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='transaction.proto', + package='waves', + syntax='proto3', + serialized_options=b'\n&com.wavesplatform.protobuf.transaction\252\002\005Waves', + serialized_pb=b'\n\x11transaction.proto\x12\x05waves\x1a\x0cnanopb.proto\x1a\x0c\x61mount.proto\x1a\x0frecipient.proto\x1a\x0border.proto\"L\n\x11SignedTransaction\x12\'\n\x0btransaction\x18\x01 \x01(\x0b\x32\x12.waves.Transaction\x12\x0e\n\x06proofs\x18\x02 \x03(\x0c\"\xae\x08\n\x0bTransaction\x12\x10\n\x08\x63hain_id\x18\x01 \x01(\x05\x12\x19\n\x11sender_public_key\x18\x02 \x01(\x0c\x12\x1a\n\x03\x66\x65\x65\x18\x03 \x01(\x0b\x32\r.waves.Amount\x12\x11\n\ttimestamp\x18\x04 \x01(\x03\x12\x0f\n\x07version\x18\x05 \x01(\x05\x12\x30\n\x07genesis\x18\x65 \x01(\x0b\x32\x1d.waves.GenesisTransactionDataH\x00\x12\x30\n\x07payment\x18\x66 \x01(\x0b\x32\x1d.waves.PaymentTransactionDataH\x00\x12,\n\x05issue\x18g \x01(\x0b\x32\x1b.waves.IssueTransactionDataH\x00\x12\x32\n\x08transfer\x18h \x01(\x0b\x32\x1e.waves.TransferTransactionDataH\x00\x12\x30\n\x07reissue\x18i \x01(\x0b\x32\x1d.waves.ReissueTransactionDataH\x00\x12*\n\x04\x62urn\x18j \x01(\x0b\x32\x1a.waves.BurnTransactionDataH\x00\x12\x32\n\x08\x65xchange\x18k \x01(\x0b\x32\x1e.waves.ExchangeTransactionDataH\x00\x12,\n\x05lease\x18l \x01(\x0b\x32\x1b.waves.LeaseTransactionDataH\x00\x12\x39\n\x0clease_cancel\x18m \x01(\x0b\x32!.waves.LeaseCancelTransactionDataH\x00\x12\x39\n\x0c\x63reate_alias\x18n \x01(\x0b\x32!.waves.CreateAliasTransactionDataH\x00\x12;\n\rmass_transfer\x18o \x01(\x0b\x32\".waves.MassTransferTransactionDataH\x00\x12\x36\n\x10\x64\x61ta_transaction\x18p \x01(\x0b\x32\x1a.waves.DataTransactionDataH\x00\x12\x35\n\nset_script\x18q \x01(\x0b\x32\x1f.waves.SetScriptTransactionDataH\x00\x12\x37\n\x0bsponsor_fee\x18r \x01(\x0b\x32 .waves.SponsorFeeTransactionDataH\x00\x12@\n\x10set_asset_script\x18s \x01(\x0b\x32$.waves.SetAssetScriptTransactionDataH\x00\x12;\n\rinvoke_script\x18t \x01(\x0b\x32\".waves.InvokeScriptTransactionDataH\x00\x12\x42\n\x11update_asset_info\x18u \x01(\x0b\x32%.waves.UpdateAssetInfoTransactionDataH\x00:\x06\x92?\x03\xb0\x01\x01\x42\x06\n\x04\x64\x61ta\"C\n\x16GenesisTransactionData\x12\x19\n\x11recipient_address\x18\x01 \x01(\x0c\x12\x0e\n\x06\x61mount\x18\x02 \x01(\x03\"C\n\x16PaymentTransactionData\x12\x19\n\x11recipient_address\x18\x01 \x01(\x0c\x12\x0e\n\x06\x61mount\x18\x02 \x01(\x03\"q\n\x17TransferTransactionData\x12#\n\trecipient\x18\x01 \x01(\x0b\x32\x10.waves.Recipient\x12\x1d\n\x06\x61mount\x18\x02 \x01(\x0b\x32\r.waves.Amount\x12\x12\n\nattachment\x18\x03 \x01(\x0c\"+\n\x1a\x43reateAliasTransactionData\x12\r\n\x05\x61lias\x18\x01 \x01(\t\"\xcf\x01\n\x13\x44\x61taTransactionData\x12\x32\n\x04\x64\x61ta\x18\x01 \x03(\x0b\x32$.waves.DataTransactionData.DataEntry\x1a\x83\x01\n\tDataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x13\n\tint_value\x18\n \x01(\x03H\x00\x12\x14\n\nbool_value\x18\x0b \x01(\x08H\x00\x12\x16\n\x0c\x62inary_value\x18\x0c \x01(\x0cH\x00\x12\x16\n\x0cstring_value\x18\r \x01(\tH\x00:\x05\x92?\x02\x30\x01\x42\x07\n\x05value\"\xcb\x01\n\x1bMassTransferTransactionData\x12\x10\n\x08\x61sset_id\x18\x01 \x01(\x0c\x12>\n\ttransfers\x18\x02 \x03(\x0b\x32+.waves.MassTransferTransactionData.Transfer\x12\x12\n\nattachment\x18\x03 \x01(\x0c\x1a\x46\n\x08Transfer\x12#\n\trecipient\x18\x01 \x01(\x0b\x32\x10.waves.Recipient\x12\x0e\n\x06\x61mount\x18\x02 \x01(\x03:\x05\x92?\x02\x30\x01\"K\n\x14LeaseTransactionData\x12#\n\trecipient\x18\x01 \x01(\x0b\x32\x10.waves.Recipient\x12\x0e\n\x06\x61mount\x18\x02 \x01(\x03\".\n\x1aLeaseCancelTransactionData\x12\x10\n\x08lease_id\x18\x01 \x01(\x0c\":\n\x13\x42urnTransactionData\x12#\n\x0c\x61sset_amount\x18\x01 \x01(\x0b\x32\r.waves.Amount\"\x7f\n\x14IssueTransactionData\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x0e\n\x06\x61mount\x18\x03 \x01(\x03\x12\x10\n\x08\x64\x65\x63imals\x18\x04 \x01(\x05\x12\x12\n\nreissuable\x18\x05 \x01(\x08\x12\x0e\n\x06script\x18\x06 \x01(\x0c\"Q\n\x16ReissueTransactionData\x12#\n\x0c\x61sset_amount\x18\x01 \x01(\x0b\x32\r.waves.Amount\x12\x12\n\nreissuable\x18\x02 \x01(\x08\"A\n\x1dSetAssetScriptTransactionData\x12\x10\n\x08\x61sset_id\x18\x01 \x01(\x0c\x12\x0e\n\x06script\x18\x02 \x01(\x0c\"*\n\x18SetScriptTransactionData\x12\x0e\n\x06script\x18\x01 \x01(\x0c\"\x89\x01\n\x17\x45xchangeTransactionData\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x03\x12\r\n\x05price\x18\x02 \x01(\x03\x12\x17\n\x0f\x62uy_matcher_fee\x18\x03 \x01(\x03\x12\x18\n\x10sell_matcher_fee\x18\x04 \x01(\x03\x12\x1c\n\x06orders\x18\x05 \x03(\x0b\x32\x0c.waves.Order\";\n\x19SponsorFeeTransactionData\x12\x1e\n\x07min_fee\x18\x01 \x01(\x0b\x32\r.waves.Amount\"v\n\x1bInvokeScriptTransactionData\x12\x1f\n\x05\x64_app\x18\x01 \x01(\x0b\x32\x10.waves.Recipient\x12\x15\n\rfunction_call\x18\x02 \x01(\x0c\x12\x1f\n\x08payments\x18\x03 \x03(\x0b\x32\r.waves.Amount\"U\n\x1eUpdateAssetInfoTransactionData\x12\x10\n\x08\x61sset_id\x18\x01 \x01(\x0c\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\tB0\n&com.wavesplatform.protobuf.transaction\xaa\x02\x05Wavesb\x06proto3' + , + dependencies=[nanopb__pb2.DESCRIPTOR,amount__pb2.DESCRIPTOR,recipient__pb2.DESCRIPTOR,order__pb2.DESCRIPTOR,]) + + + + +_SIGNEDTRANSACTION = _descriptor.Descriptor( + name='SignedTransaction', + full_name='waves.SignedTransaction', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='transaction', full_name='waves.SignedTransaction.transaction', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='proofs', full_name='waves.SignedTransaction.proofs', index=1, + number=2, type=12, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=86, + serialized_end=162, +) + + +_TRANSACTION = _descriptor.Descriptor( + name='Transaction', + full_name='waves.Transaction', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='chain_id', full_name='waves.Transaction.chain_id', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='sender_public_key', full_name='waves.Transaction.sender_public_key', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='fee', full_name='waves.Transaction.fee', index=2, + number=3, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='timestamp', full_name='waves.Transaction.timestamp', index=3, + number=4, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='version', full_name='waves.Transaction.version', index=4, + number=5, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='genesis', full_name='waves.Transaction.genesis', index=5, + number=101, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='payment', full_name='waves.Transaction.payment', index=6, + number=102, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='issue', full_name='waves.Transaction.issue', index=7, + number=103, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='transfer', full_name='waves.Transaction.transfer', index=8, + number=104, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='reissue', full_name='waves.Transaction.reissue', index=9, + number=105, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='burn', full_name='waves.Transaction.burn', index=10, + number=106, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='exchange', full_name='waves.Transaction.exchange', index=11, + number=107, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='lease', full_name='waves.Transaction.lease', index=12, + number=108, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='lease_cancel', full_name='waves.Transaction.lease_cancel', index=13, + number=109, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='create_alias', full_name='waves.Transaction.create_alias', index=14, + number=110, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='mass_transfer', full_name='waves.Transaction.mass_transfer', index=15, + number=111, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='data_transaction', full_name='waves.Transaction.data_transaction', index=16, + number=112, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='set_script', full_name='waves.Transaction.set_script', index=17, + number=113, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='sponsor_fee', full_name='waves.Transaction.sponsor_fee', index=18, + number=114, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='set_asset_script', full_name='waves.Transaction.set_asset_script', index=19, + number=115, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='invoke_script', full_name='waves.Transaction.invoke_script', index=20, + number=116, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='update_asset_info', full_name='waves.Transaction.update_asset_info', index=21, + number=117, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=b'\222?\003\260\001\001', + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + _descriptor.OneofDescriptor( + name='data', full_name='waves.Transaction.data', + index=0, containing_type=None, fields=[]), + ], + serialized_start=165, + serialized_end=1235, +) + + +_GENESISTRANSACTIONDATA = _descriptor.Descriptor( + name='GenesisTransactionData', + full_name='waves.GenesisTransactionData', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='recipient_address', full_name='waves.GenesisTransactionData.recipient_address', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='amount', full_name='waves.GenesisTransactionData.amount', index=1, + number=2, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1237, + serialized_end=1304, +) + + +_PAYMENTTRANSACTIONDATA = _descriptor.Descriptor( + name='PaymentTransactionData', + full_name='waves.PaymentTransactionData', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='recipient_address', full_name='waves.PaymentTransactionData.recipient_address', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='amount', full_name='waves.PaymentTransactionData.amount', index=1, + number=2, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1306, + serialized_end=1373, +) + + +_TRANSFERTRANSACTIONDATA = _descriptor.Descriptor( + name='TransferTransactionData', + full_name='waves.TransferTransactionData', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='recipient', full_name='waves.TransferTransactionData.recipient', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='amount', full_name='waves.TransferTransactionData.amount', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='attachment', full_name='waves.TransferTransactionData.attachment', index=2, + number=3, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1375, + serialized_end=1488, +) + + +_CREATEALIASTRANSACTIONDATA = _descriptor.Descriptor( + name='CreateAliasTransactionData', + full_name='waves.CreateAliasTransactionData', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='alias', full_name='waves.CreateAliasTransactionData.alias', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1490, + serialized_end=1533, +) + + +_DATATRANSACTIONDATA_DATAENTRY = _descriptor.Descriptor( + name='DataEntry', + full_name='waves.DataTransactionData.DataEntry', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='key', full_name='waves.DataTransactionData.DataEntry.key', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='int_value', full_name='waves.DataTransactionData.DataEntry.int_value', index=1, + number=10, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='bool_value', full_name='waves.DataTransactionData.DataEntry.bool_value', index=2, + number=11, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='binary_value', full_name='waves.DataTransactionData.DataEntry.binary_value', index=3, + number=12, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='string_value', full_name='waves.DataTransactionData.DataEntry.string_value', index=4, + number=13, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=b'\222?\0020\001', + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + _descriptor.OneofDescriptor( + name='value', full_name='waves.DataTransactionData.DataEntry.value', + index=0, containing_type=None, fields=[]), + ], + serialized_start=1612, + serialized_end=1743, +) + +_DATATRANSACTIONDATA = _descriptor.Descriptor( + name='DataTransactionData', + full_name='waves.DataTransactionData', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='data', full_name='waves.DataTransactionData.data', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[_DATATRANSACTIONDATA_DATAENTRY, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1536, + serialized_end=1743, +) + + +_MASSTRANSFERTRANSACTIONDATA_TRANSFER = _descriptor.Descriptor( + name='Transfer', + full_name='waves.MassTransferTransactionData.Transfer', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='recipient', full_name='waves.MassTransferTransactionData.Transfer.recipient', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='amount', full_name='waves.MassTransferTransactionData.Transfer.amount', index=1, + number=2, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=b'\222?\0020\001', + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1879, + serialized_end=1949, +) + +_MASSTRANSFERTRANSACTIONDATA = _descriptor.Descriptor( + name='MassTransferTransactionData', + full_name='waves.MassTransferTransactionData', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='asset_id', full_name='waves.MassTransferTransactionData.asset_id', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='transfers', full_name='waves.MassTransferTransactionData.transfers', index=1, + number=2, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='attachment', full_name='waves.MassTransferTransactionData.attachment', index=2, + number=3, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[_MASSTRANSFERTRANSACTIONDATA_TRANSFER, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1746, + serialized_end=1949, +) + + +_LEASETRANSACTIONDATA = _descriptor.Descriptor( + name='LeaseTransactionData', + full_name='waves.LeaseTransactionData', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='recipient', full_name='waves.LeaseTransactionData.recipient', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='amount', full_name='waves.LeaseTransactionData.amount', index=1, + number=2, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=1951, + serialized_end=2026, +) + + +_LEASECANCELTRANSACTIONDATA = _descriptor.Descriptor( + name='LeaseCancelTransactionData', + full_name='waves.LeaseCancelTransactionData', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='lease_id', full_name='waves.LeaseCancelTransactionData.lease_id', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2028, + serialized_end=2074, +) + + +_BURNTRANSACTIONDATA = _descriptor.Descriptor( + name='BurnTransactionData', + full_name='waves.BurnTransactionData', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='asset_amount', full_name='waves.BurnTransactionData.asset_amount', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2076, + serialized_end=2134, +) + + +_ISSUETRANSACTIONDATA = _descriptor.Descriptor( + name='IssueTransactionData', + full_name='waves.IssueTransactionData', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='waves.IssueTransactionData.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='description', full_name='waves.IssueTransactionData.description', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='amount', full_name='waves.IssueTransactionData.amount', index=2, + number=3, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='decimals', full_name='waves.IssueTransactionData.decimals', index=3, + number=4, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='reissuable', full_name='waves.IssueTransactionData.reissuable', index=4, + number=5, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='script', full_name='waves.IssueTransactionData.script', index=5, + number=6, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2136, + serialized_end=2263, +) + + +_REISSUETRANSACTIONDATA = _descriptor.Descriptor( + name='ReissueTransactionData', + full_name='waves.ReissueTransactionData', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='asset_amount', full_name='waves.ReissueTransactionData.asset_amount', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='reissuable', full_name='waves.ReissueTransactionData.reissuable', index=1, + number=2, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2265, + serialized_end=2346, +) + + +_SETASSETSCRIPTTRANSACTIONDATA = _descriptor.Descriptor( + name='SetAssetScriptTransactionData', + full_name='waves.SetAssetScriptTransactionData', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='asset_id', full_name='waves.SetAssetScriptTransactionData.asset_id', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='script', full_name='waves.SetAssetScriptTransactionData.script', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2348, + serialized_end=2413, +) + + +_SETSCRIPTTRANSACTIONDATA = _descriptor.Descriptor( + name='SetScriptTransactionData', + full_name='waves.SetScriptTransactionData', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='script', full_name='waves.SetScriptTransactionData.script', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2415, + serialized_end=2457, +) + + +_EXCHANGETRANSACTIONDATA = _descriptor.Descriptor( + name='ExchangeTransactionData', + full_name='waves.ExchangeTransactionData', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='amount', full_name='waves.ExchangeTransactionData.amount', index=0, + number=1, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='price', full_name='waves.ExchangeTransactionData.price', index=1, + number=2, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='buy_matcher_fee', full_name='waves.ExchangeTransactionData.buy_matcher_fee', index=2, + number=3, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='sell_matcher_fee', full_name='waves.ExchangeTransactionData.sell_matcher_fee', index=3, + number=4, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='orders', full_name='waves.ExchangeTransactionData.orders', index=4, + number=5, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2460, + serialized_end=2597, +) + + +_SPONSORFEETRANSACTIONDATA = _descriptor.Descriptor( + name='SponsorFeeTransactionData', + full_name='waves.SponsorFeeTransactionData', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='min_fee', full_name='waves.SponsorFeeTransactionData.min_fee', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2599, + serialized_end=2658, +) + + +_INVOKESCRIPTTRANSACTIONDATA = _descriptor.Descriptor( + name='InvokeScriptTransactionData', + full_name='waves.InvokeScriptTransactionData', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='d_app', full_name='waves.InvokeScriptTransactionData.d_app', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='function_call', full_name='waves.InvokeScriptTransactionData.function_call', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='payments', full_name='waves.InvokeScriptTransactionData.payments', index=2, + number=3, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2660, + serialized_end=2778, +) + + +_UPDATEASSETINFOTRANSACTIONDATA = _descriptor.Descriptor( + name='UpdateAssetInfoTransactionData', + full_name='waves.UpdateAssetInfoTransactionData', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='asset_id', full_name='waves.UpdateAssetInfoTransactionData.asset_id', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='name', full_name='waves.UpdateAssetInfoTransactionData.name', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='description', full_name='waves.UpdateAssetInfoTransactionData.description', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=2780, + serialized_end=2865, +) + +_SIGNEDTRANSACTION.fields_by_name['transaction'].message_type = _TRANSACTION +_TRANSACTION.fields_by_name['fee'].message_type = amount__pb2._AMOUNT +_TRANSACTION.fields_by_name['genesis'].message_type = _GENESISTRANSACTIONDATA +_TRANSACTION.fields_by_name['payment'].message_type = _PAYMENTTRANSACTIONDATA +_TRANSACTION.fields_by_name['issue'].message_type = _ISSUETRANSACTIONDATA +_TRANSACTION.fields_by_name['transfer'].message_type = _TRANSFERTRANSACTIONDATA +_TRANSACTION.fields_by_name['reissue'].message_type = _REISSUETRANSACTIONDATA +_TRANSACTION.fields_by_name['burn'].message_type = _BURNTRANSACTIONDATA +_TRANSACTION.fields_by_name['exchange'].message_type = _EXCHANGETRANSACTIONDATA +_TRANSACTION.fields_by_name['lease'].message_type = _LEASETRANSACTIONDATA +_TRANSACTION.fields_by_name['lease_cancel'].message_type = _LEASECANCELTRANSACTIONDATA +_TRANSACTION.fields_by_name['create_alias'].message_type = _CREATEALIASTRANSACTIONDATA +_TRANSACTION.fields_by_name['mass_transfer'].message_type = _MASSTRANSFERTRANSACTIONDATA +_TRANSACTION.fields_by_name['data_transaction'].message_type = _DATATRANSACTIONDATA +_TRANSACTION.fields_by_name['set_script'].message_type = _SETSCRIPTTRANSACTIONDATA +_TRANSACTION.fields_by_name['sponsor_fee'].message_type = _SPONSORFEETRANSACTIONDATA +_TRANSACTION.fields_by_name['set_asset_script'].message_type = _SETASSETSCRIPTTRANSACTIONDATA +_TRANSACTION.fields_by_name['invoke_script'].message_type = _INVOKESCRIPTTRANSACTIONDATA +_TRANSACTION.fields_by_name['update_asset_info'].message_type = _UPDATEASSETINFOTRANSACTIONDATA +_TRANSACTION.oneofs_by_name['data'].fields.append( + _TRANSACTION.fields_by_name['genesis']) +_TRANSACTION.fields_by_name['genesis'].containing_oneof = _TRANSACTION.oneofs_by_name['data'] +_TRANSACTION.oneofs_by_name['data'].fields.append( + _TRANSACTION.fields_by_name['payment']) +_TRANSACTION.fields_by_name['payment'].containing_oneof = _TRANSACTION.oneofs_by_name['data'] +_TRANSACTION.oneofs_by_name['data'].fields.append( + _TRANSACTION.fields_by_name['issue']) +_TRANSACTION.fields_by_name['issue'].containing_oneof = _TRANSACTION.oneofs_by_name['data'] +_TRANSACTION.oneofs_by_name['data'].fields.append( + _TRANSACTION.fields_by_name['transfer']) +_TRANSACTION.fields_by_name['transfer'].containing_oneof = _TRANSACTION.oneofs_by_name['data'] +_TRANSACTION.oneofs_by_name['data'].fields.append( + _TRANSACTION.fields_by_name['reissue']) +_TRANSACTION.fields_by_name['reissue'].containing_oneof = _TRANSACTION.oneofs_by_name['data'] +_TRANSACTION.oneofs_by_name['data'].fields.append( + _TRANSACTION.fields_by_name['burn']) +_TRANSACTION.fields_by_name['burn'].containing_oneof = _TRANSACTION.oneofs_by_name['data'] +_TRANSACTION.oneofs_by_name['data'].fields.append( + _TRANSACTION.fields_by_name['exchange']) +_TRANSACTION.fields_by_name['exchange'].containing_oneof = _TRANSACTION.oneofs_by_name['data'] +_TRANSACTION.oneofs_by_name['data'].fields.append( + _TRANSACTION.fields_by_name['lease']) +_TRANSACTION.fields_by_name['lease'].containing_oneof = _TRANSACTION.oneofs_by_name['data'] +_TRANSACTION.oneofs_by_name['data'].fields.append( + _TRANSACTION.fields_by_name['lease_cancel']) +_TRANSACTION.fields_by_name['lease_cancel'].containing_oneof = _TRANSACTION.oneofs_by_name['data'] +_TRANSACTION.oneofs_by_name['data'].fields.append( + _TRANSACTION.fields_by_name['create_alias']) +_TRANSACTION.fields_by_name['create_alias'].containing_oneof = _TRANSACTION.oneofs_by_name['data'] +_TRANSACTION.oneofs_by_name['data'].fields.append( + _TRANSACTION.fields_by_name['mass_transfer']) +_TRANSACTION.fields_by_name['mass_transfer'].containing_oneof = _TRANSACTION.oneofs_by_name['data'] +_TRANSACTION.oneofs_by_name['data'].fields.append( + _TRANSACTION.fields_by_name['data_transaction']) +_TRANSACTION.fields_by_name['data_transaction'].containing_oneof = _TRANSACTION.oneofs_by_name['data'] +_TRANSACTION.oneofs_by_name['data'].fields.append( + _TRANSACTION.fields_by_name['set_script']) +_TRANSACTION.fields_by_name['set_script'].containing_oneof = _TRANSACTION.oneofs_by_name['data'] +_TRANSACTION.oneofs_by_name['data'].fields.append( + _TRANSACTION.fields_by_name['sponsor_fee']) +_TRANSACTION.fields_by_name['sponsor_fee'].containing_oneof = _TRANSACTION.oneofs_by_name['data'] +_TRANSACTION.oneofs_by_name['data'].fields.append( + _TRANSACTION.fields_by_name['set_asset_script']) +_TRANSACTION.fields_by_name['set_asset_script'].containing_oneof = _TRANSACTION.oneofs_by_name['data'] +_TRANSACTION.oneofs_by_name['data'].fields.append( + _TRANSACTION.fields_by_name['invoke_script']) +_TRANSACTION.fields_by_name['invoke_script'].containing_oneof = _TRANSACTION.oneofs_by_name['data'] +_TRANSACTION.oneofs_by_name['data'].fields.append( + _TRANSACTION.fields_by_name['update_asset_info']) +_TRANSACTION.fields_by_name['update_asset_info'].containing_oneof = _TRANSACTION.oneofs_by_name['data'] +_TRANSFERTRANSACTIONDATA.fields_by_name['recipient'].message_type = recipient__pb2._RECIPIENT +_TRANSFERTRANSACTIONDATA.fields_by_name['amount'].message_type = amount__pb2._AMOUNT +_DATATRANSACTIONDATA_DATAENTRY.containing_type = _DATATRANSACTIONDATA +_DATATRANSACTIONDATA_DATAENTRY.oneofs_by_name['value'].fields.append( + _DATATRANSACTIONDATA_DATAENTRY.fields_by_name['int_value']) +_DATATRANSACTIONDATA_DATAENTRY.fields_by_name['int_value'].containing_oneof = _DATATRANSACTIONDATA_DATAENTRY.oneofs_by_name['value'] +_DATATRANSACTIONDATA_DATAENTRY.oneofs_by_name['value'].fields.append( + _DATATRANSACTIONDATA_DATAENTRY.fields_by_name['bool_value']) +_DATATRANSACTIONDATA_DATAENTRY.fields_by_name['bool_value'].containing_oneof = _DATATRANSACTIONDATA_DATAENTRY.oneofs_by_name['value'] +_DATATRANSACTIONDATA_DATAENTRY.oneofs_by_name['value'].fields.append( + _DATATRANSACTIONDATA_DATAENTRY.fields_by_name['binary_value']) +_DATATRANSACTIONDATA_DATAENTRY.fields_by_name['binary_value'].containing_oneof = _DATATRANSACTIONDATA_DATAENTRY.oneofs_by_name['value'] +_DATATRANSACTIONDATA_DATAENTRY.oneofs_by_name['value'].fields.append( + _DATATRANSACTIONDATA_DATAENTRY.fields_by_name['string_value']) +_DATATRANSACTIONDATA_DATAENTRY.fields_by_name['string_value'].containing_oneof = _DATATRANSACTIONDATA_DATAENTRY.oneofs_by_name['value'] +_DATATRANSACTIONDATA.fields_by_name['data'].message_type = _DATATRANSACTIONDATA_DATAENTRY +_MASSTRANSFERTRANSACTIONDATA_TRANSFER.fields_by_name['recipient'].message_type = recipient__pb2._RECIPIENT +_MASSTRANSFERTRANSACTIONDATA_TRANSFER.containing_type = _MASSTRANSFERTRANSACTIONDATA +_MASSTRANSFERTRANSACTIONDATA.fields_by_name['transfers'].message_type = _MASSTRANSFERTRANSACTIONDATA_TRANSFER +_LEASETRANSACTIONDATA.fields_by_name['recipient'].message_type = recipient__pb2._RECIPIENT +_BURNTRANSACTIONDATA.fields_by_name['asset_amount'].message_type = amount__pb2._AMOUNT +_REISSUETRANSACTIONDATA.fields_by_name['asset_amount'].message_type = amount__pb2._AMOUNT +_EXCHANGETRANSACTIONDATA.fields_by_name['orders'].message_type = order__pb2._ORDER +_SPONSORFEETRANSACTIONDATA.fields_by_name['min_fee'].message_type = amount__pb2._AMOUNT +_INVOKESCRIPTTRANSACTIONDATA.fields_by_name['d_app'].message_type = recipient__pb2._RECIPIENT +_INVOKESCRIPTTRANSACTIONDATA.fields_by_name['payments'].message_type = amount__pb2._AMOUNT +DESCRIPTOR.message_types_by_name['SignedTransaction'] = _SIGNEDTRANSACTION +DESCRIPTOR.message_types_by_name['Transaction'] = _TRANSACTION +DESCRIPTOR.message_types_by_name['GenesisTransactionData'] = _GENESISTRANSACTIONDATA +DESCRIPTOR.message_types_by_name['PaymentTransactionData'] = _PAYMENTTRANSACTIONDATA +DESCRIPTOR.message_types_by_name['TransferTransactionData'] = _TRANSFERTRANSACTIONDATA +DESCRIPTOR.message_types_by_name['CreateAliasTransactionData'] = _CREATEALIASTRANSACTIONDATA +DESCRIPTOR.message_types_by_name['DataTransactionData'] = _DATATRANSACTIONDATA +DESCRIPTOR.message_types_by_name['MassTransferTransactionData'] = _MASSTRANSFERTRANSACTIONDATA +DESCRIPTOR.message_types_by_name['LeaseTransactionData'] = _LEASETRANSACTIONDATA +DESCRIPTOR.message_types_by_name['LeaseCancelTransactionData'] = _LEASECANCELTRANSACTIONDATA +DESCRIPTOR.message_types_by_name['BurnTransactionData'] = _BURNTRANSACTIONDATA +DESCRIPTOR.message_types_by_name['IssueTransactionData'] = _ISSUETRANSACTIONDATA +DESCRIPTOR.message_types_by_name['ReissueTransactionData'] = _REISSUETRANSACTIONDATA +DESCRIPTOR.message_types_by_name['SetAssetScriptTransactionData'] = _SETASSETSCRIPTTRANSACTIONDATA +DESCRIPTOR.message_types_by_name['SetScriptTransactionData'] = _SETSCRIPTTRANSACTIONDATA +DESCRIPTOR.message_types_by_name['ExchangeTransactionData'] = _EXCHANGETRANSACTIONDATA +DESCRIPTOR.message_types_by_name['SponsorFeeTransactionData'] = _SPONSORFEETRANSACTIONDATA +DESCRIPTOR.message_types_by_name['InvokeScriptTransactionData'] = _INVOKESCRIPTTRANSACTIONDATA +DESCRIPTOR.message_types_by_name['UpdateAssetInfoTransactionData'] = _UPDATEASSETINFOTRANSACTIONDATA +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +SignedTransaction = _reflection.GeneratedProtocolMessageType('SignedTransaction', (_message.Message,), { + 'DESCRIPTOR' : _SIGNEDTRANSACTION, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.SignedTransaction) + }) +_sym_db.RegisterMessage(SignedTransaction) + +Transaction = _reflection.GeneratedProtocolMessageType('Transaction', (_message.Message,), { + 'DESCRIPTOR' : _TRANSACTION, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.Transaction) + }) +_sym_db.RegisterMessage(Transaction) + +GenesisTransactionData = _reflection.GeneratedProtocolMessageType('GenesisTransactionData', (_message.Message,), { + 'DESCRIPTOR' : _GENESISTRANSACTIONDATA, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.GenesisTransactionData) + }) +_sym_db.RegisterMessage(GenesisTransactionData) + +PaymentTransactionData = _reflection.GeneratedProtocolMessageType('PaymentTransactionData', (_message.Message,), { + 'DESCRIPTOR' : _PAYMENTTRANSACTIONDATA, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.PaymentTransactionData) + }) +_sym_db.RegisterMessage(PaymentTransactionData) + +TransferTransactionData = _reflection.GeneratedProtocolMessageType('TransferTransactionData', (_message.Message,), { + 'DESCRIPTOR' : _TRANSFERTRANSACTIONDATA, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.TransferTransactionData) + }) +_sym_db.RegisterMessage(TransferTransactionData) + +CreateAliasTransactionData = _reflection.GeneratedProtocolMessageType('CreateAliasTransactionData', (_message.Message,), { + 'DESCRIPTOR' : _CREATEALIASTRANSACTIONDATA, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.CreateAliasTransactionData) + }) +_sym_db.RegisterMessage(CreateAliasTransactionData) + +DataTransactionData = _reflection.GeneratedProtocolMessageType('DataTransactionData', (_message.Message,), { + + 'DataEntry' : _reflection.GeneratedProtocolMessageType('DataEntry', (_message.Message,), { + 'DESCRIPTOR' : _DATATRANSACTIONDATA_DATAENTRY, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.DataTransactionData.DataEntry) + }) + , + 'DESCRIPTOR' : _DATATRANSACTIONDATA, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.DataTransactionData) + }) +_sym_db.RegisterMessage(DataTransactionData) +_sym_db.RegisterMessage(DataTransactionData.DataEntry) + +MassTransferTransactionData = _reflection.GeneratedProtocolMessageType('MassTransferTransactionData', (_message.Message,), { + + 'Transfer' : _reflection.GeneratedProtocolMessageType('Transfer', (_message.Message,), { + 'DESCRIPTOR' : _MASSTRANSFERTRANSACTIONDATA_TRANSFER, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.MassTransferTransactionData.Transfer) + }) + , + 'DESCRIPTOR' : _MASSTRANSFERTRANSACTIONDATA, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.MassTransferTransactionData) + }) +_sym_db.RegisterMessage(MassTransferTransactionData) +_sym_db.RegisterMessage(MassTransferTransactionData.Transfer) + +LeaseTransactionData = _reflection.GeneratedProtocolMessageType('LeaseTransactionData', (_message.Message,), { + 'DESCRIPTOR' : _LEASETRANSACTIONDATA, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.LeaseTransactionData) + }) +_sym_db.RegisterMessage(LeaseTransactionData) + +LeaseCancelTransactionData = _reflection.GeneratedProtocolMessageType('LeaseCancelTransactionData', (_message.Message,), { + 'DESCRIPTOR' : _LEASECANCELTRANSACTIONDATA, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.LeaseCancelTransactionData) + }) +_sym_db.RegisterMessage(LeaseCancelTransactionData) + +BurnTransactionData = _reflection.GeneratedProtocolMessageType('BurnTransactionData', (_message.Message,), { + 'DESCRIPTOR' : _BURNTRANSACTIONDATA, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.BurnTransactionData) + }) +_sym_db.RegisterMessage(BurnTransactionData) + +IssueTransactionData = _reflection.GeneratedProtocolMessageType('IssueTransactionData', (_message.Message,), { + 'DESCRIPTOR' : _ISSUETRANSACTIONDATA, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.IssueTransactionData) + }) +_sym_db.RegisterMessage(IssueTransactionData) + +ReissueTransactionData = _reflection.GeneratedProtocolMessageType('ReissueTransactionData', (_message.Message,), { + 'DESCRIPTOR' : _REISSUETRANSACTIONDATA, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.ReissueTransactionData) + }) +_sym_db.RegisterMessage(ReissueTransactionData) + +SetAssetScriptTransactionData = _reflection.GeneratedProtocolMessageType('SetAssetScriptTransactionData', (_message.Message,), { + 'DESCRIPTOR' : _SETASSETSCRIPTTRANSACTIONDATA, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.SetAssetScriptTransactionData) + }) +_sym_db.RegisterMessage(SetAssetScriptTransactionData) + +SetScriptTransactionData = _reflection.GeneratedProtocolMessageType('SetScriptTransactionData', (_message.Message,), { + 'DESCRIPTOR' : _SETSCRIPTTRANSACTIONDATA, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.SetScriptTransactionData) + }) +_sym_db.RegisterMessage(SetScriptTransactionData) + +ExchangeTransactionData = _reflection.GeneratedProtocolMessageType('ExchangeTransactionData', (_message.Message,), { + 'DESCRIPTOR' : _EXCHANGETRANSACTIONDATA, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.ExchangeTransactionData) + }) +_sym_db.RegisterMessage(ExchangeTransactionData) + +SponsorFeeTransactionData = _reflection.GeneratedProtocolMessageType('SponsorFeeTransactionData', (_message.Message,), { + 'DESCRIPTOR' : _SPONSORFEETRANSACTIONDATA, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.SponsorFeeTransactionData) + }) +_sym_db.RegisterMessage(SponsorFeeTransactionData) + +InvokeScriptTransactionData = _reflection.GeneratedProtocolMessageType('InvokeScriptTransactionData', (_message.Message,), { + 'DESCRIPTOR' : _INVOKESCRIPTTRANSACTIONDATA, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.InvokeScriptTransactionData) + }) +_sym_db.RegisterMessage(InvokeScriptTransactionData) + +UpdateAssetInfoTransactionData = _reflection.GeneratedProtocolMessageType('UpdateAssetInfoTransactionData', (_message.Message,), { + 'DESCRIPTOR' : _UPDATEASSETINFOTRANSACTIONDATA, + '__module__' : 'transaction_pb2' + # @@protoc_insertion_point(class_scope:waves.UpdateAssetInfoTransactionData) + }) +_sym_db.RegisterMessage(UpdateAssetInfoTransactionData) + + +DESCRIPTOR._options = None +_TRANSACTION._options = None +_DATATRANSACTIONDATA_DATAENTRY._options = None +_MASSTRANSFERTRANSACTIONDATA_TRANSFER._options = None +# @@protoc_insertion_point(module_scope) diff --git a/src/crypto/ledger_crypto.c b/src/crypto/ledger_crypto.c index 4cbf86a9..8029f017 100644 --- a/src/crypto/ledger_crypto.c +++ b/src/crypto/ledger_crypto.c @@ -37,8 +37,8 @@ void public_key_le_to_be(cx_ecfp_public_key_t *public_key) { if ((public_key->W[32] & 1) != 0) { public_key_be[31] |= 0x80; } - os_memset(public_key->W, 0, 65); - os_memmove(public_key->W, public_key_be, 32); + memset(public_key->W, 0, 65); + memmove(public_key->W, public_key_be, 32); } void get_keypair_by_path(const uint32_t *path, cx_ecfp_public_key_t *public_key, @@ -63,7 +63,7 @@ bool get_curve25519_public_key_for_path(const uint32_t *path, // derive the ed25519 keys by that BIP32 path from the device get_keypair_by_path(path, public_key, &private_key); // clean private key - os_memset(&private_key, 0, sizeof(cx_ecfp_private_key_t)); + memset(&private_key, 0, sizeof(cx_ecfp_private_key_t)); public_key_le_to_be(public_key); diff --git a/src/crypto/stream_eddsa_sign.c b/src/crypto/stream_eddsa_sign.c index 48a3c1d7..ed3a849c 100644 --- a/src/crypto/stream_eddsa_sign.c +++ b/src/crypto/stream_eddsa_sign.c @@ -19,70 +19,55 @@ ********************************************************************************/ #include "stream_eddsa_sign.h" +#include "string.h" +#include "../main.h" -static uint8_t const C_cx_Ed25519_a[] = { - 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xec}; +static uint8_t const C_cx_Ed25519_a[] = {0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xec}; static uint8_t const C_cx_Ed25519_d[] = { // d: 0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3 - 0x52, 0x03, 0x6c, 0xee, 0x2b, 0x6f, 0xfe, 0x73, 0x8c, 0xc7, 0x40, - 0x79, 0x77, 0x79, 0xe8, 0x98, 0x00, 0x70, 0x0a, 0x4d, 0x41, 0x41, - 0xd8, 0xab, 0x75, 0xeb, 0x4d, 0xca, 0x13, 0x59, 0x78, 0xa3}; + 0x52, 0x03, 0x6c, 0xee, 0x2b, 0x6f, 0xfe, 0x73, 0x8c, 0xc7, 0x40, 0x79, 0x77, 0x79, 0xe8, 0x98, + 0x00, 0x70, 0x0a, 0x4d, 0x41, 0x41, 0xd8, 0xab, 0x75, 0xeb, 0x4d, 0xca, 0x13, 0x59, 0x78, 0xa3}; static uint8_t const C_cx_Ed25519_q[] = { // q: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed - 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed}; + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed}; static uint8_t const C_cx_Ed25519_Hq[] = { // Hq: 0x00000000000000000000000000000000000000000000000000000000000005a4 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xa4}; -static uint8_t const C_cx_Ed25519_Bx[] = { - 0x21, 0x69, 0x36, 0xd3, 0xcd, 0x6e, 0x53, 0xfe, 0xc0, 0xa4, 0xe2, - 0x31, 0xfd, 0xd6, 0xdc, 0x5c, 0x69, 0x2c, 0xc7, 0x60, 0x95, 0x25, - 0xa7, 0xb2, 0xc9, 0x56, 0x2d, 0x60, 0x8f, 0x25, 0xd5, 0x1a}; -static uint8_t const C_cx_Ed25519_By[] = { - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x58}; -static uint8_t const C_cx_Ed25519_l[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xa4}; +static uint8_t const C_cx_Ed25519_Bx[] = {0x21, 0x69, 0x36, 0xd3, 0xcd, 0x6e, 0x53, 0xfe, 0xc0, 0xa4, 0xe2, + 0x31, 0xfd, 0xd6, 0xdc, 0x5c, 0x69, 0x2c, 0xc7, 0x60, 0x95, 0x25, + 0xa7, 0xb2, 0xc9, 0x56, 0x2d, 0x60, 0x8f, 0x25, 0xd5, 0x1a}; +static uint8_t const C_cx_Ed25519_By[] = {0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x58}; +static uint8_t const C_cx_Ed25519_l[] = { // l: 0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, - 0x9C, 0xD6, 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED}; + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6, 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED}; static uint8_t const C_cx_Ed25519_Hl[] = { // Hl: 0x0399411b7c309a3dceec73d217f5be65d00e1ba768859347a40611e3449c0f01 - 0x03, 0x99, 0x41, 0x1b, 0x7c, 0x30, 0x9a, 0x3d, 0xce, 0xec, 0x73, - 0xd2, 0x17, 0xf5, 0xbe, 0x65, 0xd0, 0x0e, 0x1b, 0xa7, 0x68, 0x85, - 0x93, 0x47, 0xa4, 0x06, 0x11, 0xe3, 0x44, 0x9c, 0x0f, 0x01}; -static uint8_t const C_cx_Ed25519_I[] = { - // I: 0x2b8324804fc1df0b2b4d00993dfbd7a72f431806ad2fe478c4ee1b274a0ea0b0 - 0x2b, 0x83, 0x24, 0x80, 0x4f, 0xc1, 0xdf, 0x0b, 0x2b, 0x4d, 0x00, - 0x99, 0x3d, 0xfb, 0xd7, 0xa7, 0x2f, 0x43, 0x18, 0x06, 0xad, 0x2f, - 0xe4, 0x78, 0xc4, 0xee, 0x1b, 0x27, 0x4a, 0x0e, 0xa0, 0xb0}; -static uint8_t const C_cx_Ed25519_Qplus3div8[] = { - // q3: 0x0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe - 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}; + 0x03, 0x99, 0x41, 0x1b, 0x7c, 0x30, 0x9a, 0x3d, 0xce, 0xec, 0x73, 0xd2, 0x17, 0xf5, 0xbe, 0x65, + 0xd0, 0x0e, 0x1b, 0xa7, 0x68, 0x85, 0x93, 0x47, 0xa4, 0x06, 0x11, 0xe3, 0x44, 0x9c, 0x0f, 0x01}; + #define C_cx_Ed25519_h 8 -cx_curve_twisted_edward_t const C_cx_Ed25519 = { - CX_CURVE_Ed25519, - 256, - 32, - (uint8_t *)C_cx_Ed25519_q, - (uint8_t *)C_cx_Ed25519_Hq, - (uint8_t *)C_cx_Ed25519_Bx, - (uint8_t *)C_cx_Ed25519_By, - (uint8_t *)C_cx_Ed25519_l, - (uint8_t *)C_cx_Ed25519_Hl, - C_cx_Ed25519_h, - (uint8_t *)C_cx_Ed25519_a, - (uint8_t *)C_cx_Ed25519_d, - (uint8_t *)C_cx_Ed25519_I, - (uint8_t *)C_cx_Ed25519_Qplus3div8, + +cx_curve_twisted_edwards_t const C_cx_Ed25519 = { + .curve = CX_CURVE_Ed25519, + .bit_size = 256, + .length = 32, + + .a = C_cx_Ed25519_a, + .b = C_cx_Ed25519_d, + .p = C_cx_Ed25519_q, + .Gx = C_cx_Ed25519_Bx, + .Gy = C_cx_Ed25519_By, + .n = C_cx_Ed25519_l, + .h = C_cx_Ed25519_h, + .Hp = C_cx_Ed25519_Hq, + .Hn = C_cx_Ed25519_Hl, }; /* ----------------------------------------------------------------------- */ @@ -124,8 +109,8 @@ static void cx_eddsa_get_public_key_internal( const cx_ecfp_private_key_t *pv_key, cx_md_t hashID, cx_ecfp_public_key_t *pu_key, unsigned char *a, unsigned int a_len, unsigned char *h, unsigned int h_len, unsigned char *scal /*tmp*/) { - cx_curve_twisted_edward_t *domain = - (cx_curve_twisted_edward_t *)&C_cx_Ed25519; + cx_curve_twisted_edwards_t *domain = + (cx_curve_twisted_edwards_t *)&C_cx_Ed25519; cx_sha512_t hash_ctx; unsigned int size; @@ -154,7 +139,7 @@ static void cx_eddsa_get_public_key_internal( scal[31] = (scal[31] & 0x7F) | 0x40; } else { - os_memmove(scal, pv_key->d, pv_key->d_len); + memmove(scal, pv_key->d, pv_key->d_len); } /* 3. Interpret the buffer as the little-endian integer, forming a @@ -163,24 +148,24 @@ static void cx_eddsa_get_public_key_internal( */ cx_decode_int(scal, size); if (a) { - os_memmove(a, scal, size); + memmove(a, scal, size); } if (h) { - os_memmove(h, scal + size, size); + memmove(h, scal + size, size); } pu_key->curve = pv_key->curve; pu_key->W_len = 1 + size * 2; pu_key->W[0] = 0x04; - os_memmove(pu_key->W + 1, domain->Gx, size); - os_memmove(pu_key->W + 1 + size, domain->Gy, size); + memmove(pu_key->W + 1, domain->Gx, size); + memmove(pu_key->W + 1 + size, domain->Gy, size); cx_ecfp_scalar_mult(domain->curve, pu_key->W, pu_key->W_len, scal, size); } void stream_eddsa_sign_step1(streamEddsaContext_t *eddsa_context, const cx_ecfp_private_key_t *pv_key) { - os_memset((unsigned char *)eddsa_context, 0, sizeof(streamEddsaContext_t)); - cx_curve_twisted_edward_t *domain = - (cx_curve_twisted_edward_t *)&C_cx_Ed25519; + memset((unsigned char *)eddsa_context, 0, sizeof(streamEddsaContext_t)); + cx_curve_twisted_edwards_t *domain = + (cx_curve_twisted_edwards_t *)&C_cx_Ed25519; unsigned int size = domain->length; @@ -196,7 +181,7 @@ void stream_eddsa_sign_step1(streamEddsaContext_t *eddsa_context, cx_edward_compress_point(domain->curve, &eddsa_context->u.internal_pu_key.W[0], eddsa_context->u.internal_pu_key.W_len); - os_memmove(eddsa_context->Y, &eddsa_context->u.internal_pu_key.W[1], size); + memmove(eddsa_context->Y, &eddsa_context->u.internal_pu_key.W[1], size); // compute r // - last size (32/57) bytes of H(sk), h, as big endian bytes ordered. stored @@ -223,26 +208,26 @@ void stream_eddsa_sign_step2(streamEddsaContext_t *eddsa_context, void stream_eddsa_sign_step3(streamEddsaContext_t *eddsa_context) { unsigned char scal[64]; - cx_curve_twisted_edward_t *domain = - (cx_curve_twisted_edward_t *)&C_cx_Ed25519; + cx_curve_twisted_edwards_t *domain = + (cx_curve_twisted_edwards_t *)&C_cx_Ed25519; unsigned int size = domain->length; unsigned int hsize = 2 * size; cx_hash(&eddsa_context->data_hash_ctx.header, CX_LAST, NULL, 0, - eddsa_context->first_data_hash, 32); + tmp_ctx.signing_context.first_data_hash, 32); cx_hash(&eddsa_context->hash_ctx.header, CX_LAST, NULL, 0, scal, 64); cx_encode_int(scal, hsize); cx_math_modm(scal, hsize, domain->n, size); - os_memmove(eddsa_context->r, scal + size, size); // r + memmove(eddsa_context->r, scal + size, size); // r // compute R = r.B eddsa_context->u.Q[0] = 0x04; - os_memmove(eddsa_context->u.Q + 1, domain->Gx, size); - os_memmove(eddsa_context->u.Q + 1 + size, domain->Gy, size); + memmove(eddsa_context->u.Q + 1, domain->Gx, size); + memmove(eddsa_context->u.Q + 1 + size, domain->Gy, size); cx_ecfp_scalar_mult(CX_CURVE_Ed25519, eddsa_context->u.Q, 1 + 2 * domain->length, eddsa_context->r, size); cx_compress(eddsa_context->u.Q + 1, size); - os_memmove(eddsa_context->sig, eddsa_context->u.Q + 1 + size, + memmove(eddsa_context->sig, eddsa_context->u.Q + 1 + size, size); // sig <- R // compute S = r+H(R,A,M).a @@ -266,15 +251,16 @@ void stream_eddsa_sign_step4(streamEddsaContext_t *eddsa_context, int stream_eddsa_sign_step5(streamEddsaContext_t *eddsa_context, unsigned char *sig) { unsigned char scal[64]; - cx_curve_twisted_edward_t *domain = - (cx_curve_twisted_edward_t *)&C_cx_Ed25519; + cx_curve_twisted_edwards_t *domain = + (cx_curve_twisted_edwards_t *)&C_cx_Ed25519; unsigned int size = domain->length; unsigned int hsize = 2 * size; unsigned char second_data_hash[64]; cx_hash(&eddsa_context->data_hash_ctx.header, CX_LAST, NULL, 0, second_data_hash, 32); - if (os_memcmp(&eddsa_context->first_data_hash, &second_data_hash, 32) != 0) { + if (memcmp(&tmp_ctx.signing_context.first_data_hash, &second_data_hash, + 32) != 0) { THROW(SW_SIGN_DATA_NOT_MATCH); } cx_hash(&eddsa_context->hash_ctx.header, CX_LAST, NULL, 0, scal, 64); @@ -289,8 +275,8 @@ int stream_eddsa_sign_step5(streamEddsaContext_t *eddsa_context, eddsa_context->r, domain->n, size); cx_encode_int(eddsa_context->sig + size, size); - os_memmove(sig, eddsa_context->sig, 64); - os_memset((unsigned char *)eddsa_context, 0, sizeof(streamEddsaContext_t)); + memmove(sig, eddsa_context->sig, 64); + memset((unsigned char *)eddsa_context, 0, sizeof(streamEddsaContext_t)); return 2 * size; } \ No newline at end of file diff --git a/src/crypto/stream_eddsa_sign.h b/src/crypto/stream_eddsa_sign.h index 6ee71c51..461360a4 100644 --- a/src/crypto/stream_eddsa_sign.h +++ b/src/crypto/stream_eddsa_sign.h @@ -38,7 +38,6 @@ typedef struct streamEddsaContext_t { } u; cx_sha512_t hash_ctx; cx_blake2b_t data_hash_ctx; - unsigned char first_data_hash[32]; } streamEddsaContext_t; void stream_eddsa_sign_step1(streamEddsaContext_t *eddsa_context, diff --git a/src/crypto/waves.c b/src/crypto/waves.c index 89669464..85bded27 100644 --- a/src/crypto/waves.c +++ b/src/crypto/waves.c @@ -17,10 +17,11 @@ * See the License for the specific language governing permissions and * limitations under the License. ********************************************************************************/ - +#include "main.h" #include "waves.h" #include "ledger_crypto.h" #include "stream_eddsa_sign.h" +#include "string.h" void waves_secure_hash(const uint8_t *message, size_t message_len, uint8_t hash[32]) { @@ -29,7 +30,7 @@ void waves_secure_hash(const uint8_t *message, size_t message_len, } // Build waves address from the curve25519 public key, check -// https://github.com/wavesplatform/Waves/wiki/Data-Structures#address +// https://docs.wavesprotocol.org/ru/blockchain/binary-format/address-binary-format void waves_public_key_to_address(const ed25519_public_key public_key, const unsigned char network_byte, unsigned char *output) { @@ -40,12 +41,26 @@ void waves_public_key_to_address(const ed25519_public_key public_key, address[0] = 0x01; address[1] = network_byte; - os_memmove(&address[2], public_key_hash, 20); + memmove(&address[2], public_key_hash, 20); waves_secure_hash(address, 22, checksum); - os_memmove(&address[22], checksum, 4); + memmove(&address[22], checksum, 4); + + size_t length = 36; + b58enc((char *)output, &length, address, 26); +} +void waves_public_key_hash_to_address( + const ed25519_public_key_hash public_key_hash, + const unsigned char network_byte, unsigned char *output) { + uint8_t address[26]; + uint8_t checksum[32]; + address[0] = 0x01; + address[1] = network_byte; + memmove(&address[2], public_key_hash, 20); + waves_secure_hash(address, 22, checksum); + memmove(&address[22], checksum, 4); size_t length = 36; b58enc((char *)output, &length, address, 26); } diff --git a/src/crypto/waves.h b/src/crypto/waves.h index 8609b3df..29023f38 100644 --- a/src/crypto/waves.h +++ b/src/crypto/waves.h @@ -30,13 +30,16 @@ #include "stream_eddsa_sign.h" typedef unsigned char ed25519_signature[64]; +typedef unsigned char ed25519_public_key_hash[20]; typedef unsigned char ed25519_public_key[32]; typedef unsigned char ed25519_secret_key[32]; void waves_public_key_to_address(const ed25519_public_key public_key, const unsigned char network_byte, unsigned char *output); +void waves_public_key_hash_to_address( + const ed25519_public_key_hash public_key_hash, + const unsigned char network_byte, unsigned char *output); void copy_in_reverse_order(unsigned char *to, const unsigned char *from, const unsigned int len); - #endif diff --git a/src/main.c b/src/main.c index 55bb5ca4..24ed9bc9 100644 --- a/src/main.c +++ b/src/main.c @@ -23,17 +23,16 @@ #include "main.h" #include "crypto/waves.h" #include "crypto/ledger_crypto.h" -#include "os_io_seproxyhal.h" // Ledger Stuff #include "ui/ui.h" #include "os.h" #include "cx.h" -#include "os_io_seproxyhal.h" +#include "ux.h" +uint8_t G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B]; // Temporary area to store stuff and reuse the same memory tmpContext_t tmp_ctx; -uiContext_t ui_context; // Non-volatile storage for the wallet app's stuff internal_storage_t const N_storage_real; @@ -41,9 +40,6 @@ internal_storage_t const N_storage_real; // SPI Buffer for io_event unsigned char G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B]; -#if !defined(TARGET_NANOS) && !defined(TARGET_BLUE) && !defined(TARGET_NANOX) -#error This application only supports the Ledger Nano S, Nano X and the Ledger Blue -#endif unsigned short io_exchange_al(unsigned char channel, unsigned short tx_len) { switch (channel & ~(IO_FLAGS)) { @@ -114,7 +110,6 @@ void hash_stream_data(uint8_t chunk_data_size, uint8_t chunk_data_start_index) { // from the button handler after the user verifies the transaction. void make_sign_step(uint8_t chunk_data_start_index, uint8_t chunk_data_size) { - PRINTF("make_sign_step start step: %d\n", tmp_ctx.signing_context.step); if (tmp_ctx.signing_context.step == 1) { cx_ecfp_public_key_t public_key; cx_ecfp_private_key_t private_key; @@ -124,8 +119,8 @@ void make_sign_step(uint8_t chunk_data_start_index, uint8_t chunk_data_size) { &private_key); public_key_le_to_be(&public_key); tmp_ctx.signing_context.sign_bit = public_key.W[31] & 0x80; - os_memset(&private_key, 0, sizeof(cx_ecfp_private_key_t)); - os_memset(&public_key, 0, sizeof(cx_ecfp_public_key_t)); + memset(&private_key, 0, sizeof(cx_ecfp_private_key_t)); + memset(&public_key, 0, sizeof(cx_ecfp_public_key_t)); tmp_ctx.signing_context.step = 2; } else if (tmp_ctx.signing_context.step == 2) { if (tmp_ctx.signing_context.data_read < tmp_ctx.signing_context.data_size) { @@ -142,36 +137,43 @@ void make_sign_step(uint8_t chunk_data_start_index, uint8_t chunk_data_size) { // chunk_data_size will be false if (tmp_ctx.signing_context.data_read == tmp_ctx.signing_context.data_size) { - os_memmove(ui_context.id, - tmp_ctx.signing_context.eddsa_context.first_data_hash, 32); tmp_ctx.signing_context.step = 5; + return; } } } - PRINTF("make_sign_step end step: %d\n", tmp_ctx.signing_context.step); } - void make_allowed_sign_steps() { uint8_t chunk_data_start_index = 5; uint8_t chunk_data_size = G_io_apdu_buffer[4]; if (tmp_ctx.signing_context.chunk == 0) { - chunk_data_start_index += 28; - chunk_data_size -= 28; + chunk_data_start_index += 29; + chunk_data_size -= 29; // then there is the bip32 path in the first chunk - first 20 bytes of data read_path_from_bytes(G_io_apdu_buffer + 5, (uint32_t *)tmp_ctx.signing_context.bip32); tmp_ctx.signing_context.amount_decimals = G_io_apdu_buffer[25]; - tmp_ctx.signing_context.fee_decimals = G_io_apdu_buffer[26]; - tmp_ctx.signing_context.data_type = G_io_apdu_buffer[27]; - tmp_ctx.signing_context.data_version = G_io_apdu_buffer[28]; + tmp_ctx.signing_context.amount2_decimals = G_io_apdu_buffer[26]; + tmp_ctx.signing_context.fee_decimals = G_io_apdu_buffer[27]; + tmp_ctx.signing_context.data_type = G_io_apdu_buffer[28]; + tmp_ctx.signing_context.data_version = G_io_apdu_buffer[29]; tmp_ctx.signing_context.data_size = - deserialize_uint32_t(&G_io_apdu_buffer[29]); + deserialize_uint32_t(&G_io_apdu_buffer[30]); + // getting message type based on tx type and varsion + tmp_ctx.signing_context.message_type = getMessageType(); + if(tmp_ctx.signing_context.amount_decimals < 0 || tmp_ctx.signing_context.amount_decimals > 8 ) { + THROW(SW_INCORRECT_PRECISION_VALUE); + } + if(tmp_ctx.signing_context.amount2_decimals < 0 || tmp_ctx.signing_context.amount2_decimals > 8) { + THROW(SW_INCORRECT_PRECISION_VALUE); + } } - while (tmp_ctx.signing_context.chunk_used < chunk_data_size) { + while (tmp_ctx.signing_context.chunk_used < chunk_data_size && + tmp_ctx.signing_context.step < 5) { make_sign_step(chunk_data_start_index, chunk_data_size); } // else wait for next chunk @@ -180,14 +182,11 @@ void make_allowed_sign_steps() { // like // https://github.com/lenondupe/ledger-app-stellar/blob/master/src/main.c#L1784 uint32_t set_result_sign() { - uint8_t signature[64]; - - stream_eddsa_sign_step5(&tmp_ctx.signing_context.eddsa_context, signature); + tmp_ctx.signing_context.signature[63] |= tmp_ctx.signing_context.sign_bit; + memmove((char *)G_io_apdu_buffer, tmp_ctx.signing_context.signature, + sizeof(tmp_ctx.signing_context.signature)); - signature[63] |= tmp_ctx.signing_context.sign_bit; - os_memmove((char *)G_io_apdu_buffer, signature, sizeof(signature)); - - PRINTF("Signature:\n%.*H\n", 64, signature); + PRINTF("Signature:\n%.*H\n", 64, tmp_ctx.signing_context.signature); init_context(); @@ -195,9 +194,9 @@ uint32_t set_result_sign() { } uint32_t set_result_get_address() { - os_memmove((char *)G_io_apdu_buffer, + memmove((char *)G_io_apdu_buffer, (char *)tmp_ctx.address_context.public_key, 32); - os_memmove((char *)G_io_apdu_buffer + 32, + memmove((char *)G_io_apdu_buffer + 32, (char *)tmp_ctx.address_context.address, 35); init_context(); return 67; @@ -217,7 +216,7 @@ void handle_apdu(volatile unsigned int *flags, volatile unsigned int *tx, BEGIN_TRY { TRY { - if (os_global_pin_is_validated() == 0) { + if (os_global_pin_is_validated() != BOLOS_UX_OK) { THROW(SW_DEVICE_IS_LOCKED); } @@ -236,37 +235,60 @@ void handle_apdu(volatile unsigned int *flags, volatile unsigned int *tx, (G_io_apdu_buffer[2] != P1_LAST)) { THROW(SW_INCORRECT_P1_P2); } - - if (tmp_ctx.signing_context.step == 5) { - THROW(SW_INCORRECT_P1_P2); - } - - if (tmp_ctx.signing_context.step > 0) { - tmp_ctx.signing_context.chunk += 1; - } else { - show_processing(); - os_memset((unsigned char *)&ui_context, 0, sizeof(uiContext_t)); - tmp_ctx.signing_context.step = 1; - tmp_ctx.signing_context.network_byte = G_io_apdu_buffer[3]; - } - - tmp_ctx.signing_context.chunk_used = 0; - ui_context.chunk_used = 0; - if (G_io_apdu_buffer[2] == P1_LAST) { + if (tmp_ctx.signing_context.step <= 5) { + if (tmp_ctx.signing_context.step > 0) { + tmp_ctx.signing_context.chunk += 1; + } else { + PRINTF("make_sign_steps start\n"); + show_processing(); + tmp_ctx.signing_context.step = 1; + tmp_ctx.signing_context.network_byte = G_io_apdu_buffer[3]; + } + tmp_ctx.signing_context.chunk_used = 0; make_allowed_sign_steps(); if (tmp_ctx.signing_context.step == 5) { - make_allowed_ui_steps(true); - show_sign_ui(); - *flags |= IO_ASYNCH_REPLY; + stream_eddsa_sign_step5(&tmp_ctx.signing_context.eddsa_context, + tmp_ctx.signing_context.signature); + tmp_ctx.signing_context.step = 6; + PRINTF("make_sign_steps end\n"); + memset(&tmp_ctx.signing_context.ui, 0, + sizeof(tmp_ctx.signing_context.ui)); + cx_blake2b_init(&tmp_ctx.signing_context.ui.hash_ctx, 256); } else { + THROW(SW_OK); + // wait for next chunk for sign + } + } + if (G_io_apdu_buffer[2] == P1_LAST) { + make_allowed_ui_steps(true); + if (tmp_ctx.signing_context.step != 8) { THROW(SW_DEPRECATED_SIGN_PROTOCOL); } } else { - make_allowed_sign_steps(); make_allowed_ui_steps(false); - THROW(SW_OK); } - + // all data parsed and prepeared to view + if (tmp_ctx.signing_context.step == 8) { + size_t length = 45; + if (!b58enc((char *)tmp_ctx.signing_context.first_data_hash, &length, + (const void *)&tmp_ctx.signing_context.first_data_hash, + 32)) { + THROW(SW_CONDITIONS_NOT_SATISFIED); + } + // convert sender public key to address + waves_public_key_to_address(tmp_ctx.signing_context.ui.from, + tmp_ctx.signing_context.network_byte, + tmp_ctx.signing_context.ui.from); + // if transaction has from field and it is pubkey hash will convert to + // address + if (tmp_ctx.signing_context.message_type == PROTOBUF_DATA) { + show_sign_protobuf_ui(); + } else { + show_sign_ui(); + } + *flags |= IO_ASYNCH_REPLY; + } + THROW(SW_OK); } break; case INS_GET_PUBLIC_KEY: { @@ -291,9 +313,9 @@ void handle_apdu(volatile unsigned int *flags, volatile unsigned int *tx, unsigned char address[35]; waves_public_key_to_address(public_key.W, G_io_apdu_buffer[3], address); - os_memmove((char *)tmp_ctx.address_context.public_key, public_key.W, + memmove((char *)tmp_ctx.address_context.public_key, public_key.W, 32); - os_memmove((char *)tmp_ctx.address_context.address, address, 35); + memmove((char *)tmp_ctx.address_context.address, address, 35); // term byte for string shown tmp_ctx.address_context.address[35] = '\0'; @@ -347,7 +369,7 @@ void handle_apdu(volatile unsigned int *flags, volatile unsigned int *tx, } } -void init_context() { os_memset(&tmp_ctx, 0, sizeof(tmp_ctx)); } +void init_context() { memset(&tmp_ctx, 0, sizeof(tmp_ctx)); } static void waves_main(void) { volatile unsigned int rx = 0; diff --git a/src/main.h b/src/main.h index 813ca30f..2084d02d 100644 --- a/src/main.h +++ b/src/main.h @@ -38,8 +38,12 @@ #define SW_OK 0x9000 #define SW_USER_CANCELLED 0x9100 #define SW_DEPRECATED_SIGN_PROTOCOL 0x9102 -#define SW_DEVICE_IS_LOCKED 0x6986 +#define SW_INCORRECT_PRECISION_VALUE 0x9103 +#define SW_INCORRECT_TRANSACTION_TYPE_VERSION 0x9104 +#define SW_PROTOBUF_DECODING_FAILED 0x9105 +#define SW_BYTE_DECODING_FAILED 0x9106 #define SW_CONDITIONS_NOT_SATISFIED 0x6985 +#define SW_DEVICE_IS_LOCKED 0x6986 #define SW_BUFFER_OVERFLOW 0x6990 #define SW_INCORRECT_P1_P2 0x6A86 #define SW_INS_NOT_SUPPORTED 0x6D00 @@ -50,6 +54,9 @@ #define COLOR_APP 0x0055FF #define COLOR_APP_LIGHT 0x87dee6 +#define BYTE_DATA 1 +#define PROTOBUF_DATA 2 + typedef struct internal_storage_t { uint8_t fido_transport; uint8_t initialized; @@ -58,46 +65,76 @@ typedef struct internal_storage_t { extern internal_storage_t const N_storage_real; #define N_storage (*(volatile internal_storage_t *)PIC(&N_storage_real)) +// A place to store information and parser state of the byte message +typedef struct uiByte_t { + unsigned char buffer[150]; + uint8_t step; + uint8_t wait_in_buffer; + uint8_t buffer_used; + uint32_t chunk_used; + uint32_t total_received; + uint16_t alias_size; + uint16_t attachment_size; +} uiByte_t; + +// A place to store information and parser state of the protobuf message +typedef struct uiProtobuf_t { + uint16_t read_offset; // nanopb read offset, everything before it has been + // succesfully decoded + uint16_t bytes_stored; // number of bytes currently stored in "data" + uint16_t total_size; // total size of the nanopb structure being received + uint16_t total_received; // number of bytes received since decoding began + uint16_t total_read; // number of bytes readed since decoding began + uint8_t data[160]; // size of the biggest nanopb element serialized +} uiProtobuf_t; + // A place to store information about the transaction // for displaying to the user when requesting approval // 44 for address/id and +1 for \0 typedef struct uiContext_t { + union { + uiByte_t byte; + uiProtobuf_t proto; + }; + unsigned char from[36]; + unsigned char fee_asset[45]; unsigned char line1[45]; unsigned char line2[45]; - unsigned char line3[45]; + unsigned char + line3[36]; // reserved for recipient if transaction has recipient message unsigned char line4[45]; unsigned char line5[45]; - unsigned char line6[45]; - unsigned char line7[45]; - unsigned char line8[45]; - unsigned char id[32]; - unsigned char buffer[150]; - unsigned char tmp[50]; - uint8_t step; - uint8_t wait_in_buffer; - uint8_t buffer_used; - uint32_t chunk_used; - uint16_t alias_size; - uint16_t attachment_size; + unsigned char line6[22]; + unsigned char fee_amount[22]; + unsigned char tmp[22]; + bool pkhash; bool finished; + cx_blake2b_t hash_ctx; } uiContext_t; // A place to store data during the signing typedef struct signingContext_t { - uint32_t bip32[5]; + union { + uiContext_t ui; + streamEddsaContext_t eddsa_context; + }; unsigned char sign_bit; unsigned char amount_decimals; + unsigned char amount2_decimals; unsigned char fee_decimals; unsigned char data_type; unsigned char data_version; + int message_type; unsigned char network_byte; - uint32_t data_size; + unsigned char signature[64]; + unsigned char first_data_hash[45]; + uint8_t step; + uint8_t sign_from; + uint32_t bip32[5]; uint32_t data_read; + uint32_t data_size; uint32_t chunk_used; uint32_t chunk; - uint8_t step; - uint8_t sign_from; - streamEddsaContext_t eddsa_context; } signingContext_t; // A place to store data during the confirming the address @@ -111,15 +148,16 @@ typedef union { addressesContext_t address_context; } tmpContext_t; -extern uiContext_t ui_context; - extern tmpContext_t tmp_ctx; // Temporary area to store stuff bool get_curve25519_public_key_for_path(const uint32_t *path, cx_ecfp_public_key_t *public_key); void init_context(); +void init_sign(); +void make_allowed_sign_steps(); uint32_t set_result_get_address(); uint32_t set_result_sign(); +uint32_t deserialize_uint32_t(unsigned char *buffer); -#endif +#endif \ No newline at end of file diff --git a/src/nanopb/pb.h b/src/nanopb/pb.h new file mode 100644 index 00000000..7f5b6433 --- /dev/null +++ b/src/nanopb/pb.h @@ -0,0 +1,952 @@ +/* Common parts of the nanopb library. Most of these are quite low-level + * stuff. For the high-level interface, see pb_encode.h and pb_decode.h. + */ + +#ifndef PB_H_INCLUDED +#define PB_H_INCLUDED + +/***************************************************************** + * Nanopb compilation time options. You can change these here by * + * uncommenting the lines, or on the compiler command line. * + *****************************************************************/ + +/* Enable support for dynamically allocated fields */ +/* #define PB_ENABLE_MALLOC 1 */ + +/* Define this if your CPU / compiler combination does not support + * unaligned memory access to packed structures. */ +/* #define PB_NO_PACKED_STRUCTS 1 */ + +/* Increase the number of required fields that are tracked. + * A compiler warning will tell if you need this. */ +/* #define PB_MAX_REQUIRED_FIELDS 256 */ + +/* Add support for tag numbers > 65536 and fields larger than 65536 bytes. */ +/* #define PB_FIELD_32BIT 1 */ + +/* Disable support for error messages in order to save some code space. */ +/* #define PB_NO_ERRMSG 1 */ + +/* Disable support for custom streams (support only memory buffers). */ +/* #define PB_BUFFER_ONLY 1 */ + +/* Disable support for 64-bit datatypes, for compilers without int64_t + or to save some code space. */ +/* #define PB_WITHOUT_64BIT 1 */ + +/* Set the fieldinfo width for all messages using automatic width + * selection. Valid values are 2, 4 and 8. Usually even if you need + * to change the width manually for some reason, it is preferrable + * to do so through the descriptorsize option in .options file. */ +/* #define PB_FIELDINFO_WIDTH 4 */ + +/* Don't encode scalar arrays as packed. This is only to be used when + * the decoder on the receiving side cannot process packed scalar arrays. + * Such example is older protobuf.js. */ +/* #define PB_ENCODE_ARRAYS_UNPACKED 1 */ + +/* Enable conversion of doubles to floats for platforms that do not + * support 64-bit doubles. Most commonly AVR. */ +/* #define PB_CONVERT_DOUBLE_FLOAT 1 */ + +/* Check whether incoming strings are valid UTF-8 sequences. Slows down + * the string processing slightly and slightly increases code size. */ +/* #define PB_VALIDATE_UTF8 1 */ + +/****************************************************************** + * You usually don't need to change anything below this line. * + * Feel free to look around and use the defined macros, though. * + ******************************************************************/ + +/* Version of the nanopb library. Just in case you want to check it in + * your own program. */ +#define NANOPB_VERSION nanopb - 0.4.0 + +/* Include all the system headers needed by nanopb. You will need the + * definitions of the following: + * - strlen, memcpy, memset functions + * - [u]int_least8_t, uint_fast8_t, [u]int_least16_t, [u]int32_t, [u]int64_t + * - size_t + * - bool + * + * If you don't have the standard header files, you can instead provide + * a custom header that defines or includes all this. In that case, + * define PB_SYSTEM_HEADER to the path of this file. + */ +#ifdef PB_SYSTEM_HEADER +#include PB_SYSTEM_HEADER +#else +#include +#include +#include +#include +#include + +#ifdef PB_ENABLE_MALLOC +#include +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Macro for defining packed structures (compiler dependent). + * This just reduces memory requirements, but is not required. + */ +#if defined(PB_NO_PACKED_STRUCTS) +/* Disable struct packing */ +#define PB_PACKED_STRUCT_START +#define PB_PACKED_STRUCT_END +#define pb_packed +#elif defined(__GNUC__) || defined(__clang__) +/* For GCC and clang */ +#define PB_PACKED_STRUCT_START +#define PB_PACKED_STRUCT_END +#define pb_packed __attribute__((packed)) +#elif defined(__ICCARM__) || defined(__CC_ARM) +/* For IAR ARM and Keil MDK-ARM compilers */ +#define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)") +#define PB_PACKED_STRUCT_END _Pragma("pack(pop)") +#define pb_packed +#elif defined(_MSC_VER) && (_MSC_VER >= 1500) +/* For Microsoft Visual C++ */ +#define PB_PACKED_STRUCT_START __pragma(pack(push, 1)) +#define PB_PACKED_STRUCT_END __pragma(pack(pop)) +#define pb_packed +#else +/* Unknown compiler */ +#define PB_PACKED_STRUCT_START +#define PB_PACKED_STRUCT_END +#define pb_packed +#endif + +/* Handly macro for suppressing unreferenced-parameter compiler warnings. */ +#ifndef PB_UNUSED +#define PB_UNUSED(x) (void)(x) +#endif + +/* Harvard-architecture processors may need special attributes for storing + * field information in program memory. */ +#ifndef PB_PROGMEM +#ifdef __AVR__ +#include +#define PB_PROGMEM PROGMEM +#define PB_PROGMEM_READU32(x) pgm_read_dword(&x) +#else +#define PB_PROGMEM +#define PB_PROGMEM_READU32(x) (x) +#endif +#endif + +/* Compile-time assertion, used for checking compatible compilation options. + * If this does not work properly on your compiler, use + * #define PB_NO_STATIC_ASSERT to disable it. + * + * But before doing that, check carefully the error message / place where it + * comes from to see if the error has a real cause. Unfortunately the error + * message is not always very clear to read, but you can see the reason better + * in the place where the PB_STATIC_ASSERT macro was called. + */ +#ifndef PB_NO_STATIC_ASSERT +#ifndef PB_STATIC_ASSERT +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +/* C11 standard _Static_assert mechanism */ +#define PB_STATIC_ASSERT(COND, MSG) _Static_assert(COND, #MSG); +#else +/* Classic negative-size-array static assert mechanism */ +#define PB_STATIC_ASSERT(COND, MSG) \ + typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, \ + __COUNTER__)[(COND) ? 1 : -1]; +#define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) \ + PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) +#define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) \ + pb_static_assertion_##MSG##_##LINE##_##COUNTER +#endif +#endif +#else +/* Static asserts disabled by PB_NO_STATIC_ASSERT */ +#define PB_STATIC_ASSERT(COND, MSG) +#endif + +/* Number of required fields to keep track of. */ +#ifndef PB_MAX_REQUIRED_FIELDS +#define PB_MAX_REQUIRED_FIELDS 64 +#endif + +#if PB_MAX_REQUIRED_FIELDS < 64 +#error You should not lower PB_MAX_REQUIRED_FIELDS from the default value (64). +#endif + +#ifdef PB_WITHOUT_64BIT +#ifdef PB_CONVERT_DOUBLE_FLOAT +/* Cannot use doubles without 64-bit types */ +#undef PB_CONVERT_DOUBLE_FLOAT +#endif +#endif + +/* List of possible field types. These are used in the autogenerated code. + * Least-significant 4 bits tell the scalar type + * Most-significant 4 bits specify repeated/required/packed etc. + */ + +typedef uint_least8_t pb_type_t; + +/**** Field data types ****/ + +/* Numeric types */ +#define PB_LTYPE_BOOL 0x00U /* bool */ +#define PB_LTYPE_VARINT 0x01U /* int32, int64, enum, bool */ +#define PB_LTYPE_UVARINT 0x02U /* uint32, uint64 */ +#define PB_LTYPE_SVARINT 0x03U /* sint32, sint64 */ +#define PB_LTYPE_FIXED32 0x04U /* fixed32, sfixed32, float */ +#define PB_LTYPE_FIXED64 0x05U /* fixed64, sfixed64, double */ + +/* Marker for last packable field type. */ +#define PB_LTYPE_LAST_PACKABLE 0x05U + +/* Byte array with pre-allocated buffer. + * data_size is the length of the allocated PB_BYTES_ARRAY structure. */ +#define PB_LTYPE_BYTES 0x06U + +/* String with pre-allocated buffer. + * data_size is the maximum length. */ +#define PB_LTYPE_STRING 0x07U + +/* Submessage + * submsg_fields is pointer to field descriptions */ +#define PB_LTYPE_SUBMESSAGE 0x08U + +/* Submessage with pre-decoding callback + * The pre-decoding callback is stored as pb_callback_t right before pSize. + * submsg_fields is pointer to field descriptions */ +#define PB_LTYPE_SUBMSG_W_CB 0x09U + +/* Extension pseudo-field + * The field contains a pointer to pb_extension_t */ +#define PB_LTYPE_EXTENSION 0x0AU + +/* Byte array with inline, pre-allocated byffer. + * data_size is the length of the inline, allocated buffer. + * This differs from PB_LTYPE_BYTES by defining the element as + * pb_byte_t[data_size] rather than pb_bytes_array_t. */ +#define PB_LTYPE_FIXED_LENGTH_BYTES 0x0BU + +/* Number of declared LTYPES */ +#define PB_LTYPES_COUNT 0x0CU +#define PB_LTYPE_MASK 0x0FU + +/**** Field repetition rules ****/ + +#define PB_HTYPE_REQUIRED 0x00U +#define PB_HTYPE_OPTIONAL 0x10U +#define PB_HTYPE_SINGULAR 0x10U +#define PB_HTYPE_REPEATED 0x20U +#define PB_HTYPE_FIXARRAY 0x20U +#define PB_HTYPE_ONEOF 0x30U +#define PB_HTYPE_MASK 0x30U + +/**** Field allocation types ****/ + +#define PB_ATYPE_STATIC 0x00U +#define PB_ATYPE_POINTER 0x80U +#define PB_ATYPE_CALLBACK 0x40U +#define PB_ATYPE_MASK 0xC0U + +#define PB_ATYPE(x) ((x)&PB_ATYPE_MASK) +#define PB_HTYPE(x) ((x)&PB_HTYPE_MASK) +#define PB_LTYPE(x) ((x)&PB_LTYPE_MASK) +#define PB_LTYPE_IS_SUBMSG(x) \ + (PB_LTYPE(x) == PB_LTYPE_SUBMESSAGE || PB_LTYPE(x) == PB_LTYPE_SUBMSG_W_CB) + +/* Data type used for storing sizes of struct fields + * and array counts. + */ +#if defined(PB_FIELD_32BIT) +typedef uint32_t pb_size_t; +typedef int32_t pb_ssize_t; +#else +typedef uint_least16_t pb_size_t; +typedef int_least16_t pb_ssize_t; +#endif +#define PB_SIZE_MAX ((pb_size_t)-1) + +/* Data type for storing encoded data and other byte streams. + * This typedef exists to support platforms where uint8_t does not exist. + * You can regard it as equivalent on uint8_t on other platforms. + */ +typedef uint_least8_t pb_byte_t; + +/* Forward declaration of struct types */ +typedef struct pb_istream_s pb_istream_t; +typedef struct pb_ostream_s pb_ostream_t; +typedef struct pb_field_iter_s pb_field_iter_t; + +/* This structure is used in auto-generated constants + * to specify struct fields. + */ +PB_PACKED_STRUCT_START +typedef struct pb_msgdesc_s pb_msgdesc_t; +struct pb_msgdesc_s { + pb_size_t field_count; + const uint32_t *field_info; + const pb_msgdesc_t *const *submsg_info; + const pb_byte_t *default_value; + + bool (*field_callback)(pb_istream_t *istream, pb_ostream_t *ostream, + const pb_field_iter_t *field); +} pb_packed; +PB_PACKED_STRUCT_END + +/* Iterator for message descriptor */ +struct pb_field_iter_s { + const pb_msgdesc_t *descriptor; /* Pointer to message descriptor constant */ + void *message; /* Pointer to start of the structure */ + + pb_size_t index; /* Index of the field */ + pb_size_t field_info_index; /* Index to descriptor->field_info array */ + pb_size_t + required_field_index; /* Index that counts only the required fields */ + pb_size_t submessage_index; /* Index that counts only submessages */ + + pb_size_t tag; /* Tag of current field */ + pb_size_t data_size; /* sizeof() of a single item */ + pb_size_t array_size; /* Number of array entries */ + pb_type_t type; /* Type of current field */ + + void *pField; /* Pointer to current field in struct */ + void *pData; /* Pointer to current data contents. Different than pField for + arrays and pointers. */ + void *pSize; /* Pointer to count/has field */ + + const pb_msgdesc_t *submsg_desc; /* For submessage fields, pointer to field + descriptor for the submessage. */ +}; + +/* For compatibility with legacy code */ +typedef pb_field_iter_t pb_field_t; + +/* Make sure that the standard integer types are of the expected sizes. + * Otherwise fixed32/fixed64 fields can break. + * + * If you get errors here, it probably means that your stdint.h is not + * correct for your platform. + */ +#ifndef PB_WITHOUT_64BIT +PB_STATIC_ASSERT(sizeof(int64_t) == 2 * sizeof(int32_t), INT64_T_WRONG_SIZE) +PB_STATIC_ASSERT(sizeof(uint64_t) == 2 * sizeof(uint32_t), UINT64_T_WRONG_SIZE) +#endif + +/* This structure is used for 'bytes' arrays. + * It has the number of bytes in the beginning, and after that an array. + * Note that actual structs used will have a different length of bytes array. + */ +#define PB_BYTES_ARRAY_T(n) \ + struct { \ + pb_size_t size; \ + pb_byte_t bytes[n]; \ + } +#define PB_BYTES_ARRAY_T_ALLOCSIZE(n) \ + ((size_t)n + offsetof(pb_bytes_array_t, bytes)) + +struct pb_bytes_array_s { + pb_size_t size; + pb_byte_t bytes[1]; +}; +typedef struct pb_bytes_array_s pb_bytes_array_t; + +/* This structure is used for giving the callback function. + * It is stored in the message structure and filled in by the method that + * calls pb_decode. + * + * The decoding callback will be given a limited-length stream + * If the wire type was string, the length is the length of the string. + * If the wire type was a varint/fixed32/fixed64, the length is the length + * of the actual value. + * The function may be called multiple times (especially for repeated types, + * but also otherwise if the message happens to contain the field multiple + * times.) + * + * The encoding callback will receive the actual output stream. + * It should write all the data in one call, including the field tag and + * wire type. It can write multiple fields. + * + * The callback can be null if you want to skip a field. + */ +typedef struct pb_callback_s pb_callback_t; +struct pb_callback_s { + /* Callback functions receive a pointer to the arg field. + * You can access the value of the field as *arg, and modify it if needed. + */ + union { + bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void **arg); + bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, + void *const *arg); + } funcs; + + /* Free arg for use by callback */ + void *arg; +}; + +extern bool pb_default_field_callback(pb_istream_t *istream, + pb_ostream_t *ostream, + const pb_field_t *field); + +/* Wire types. Library user needs these only in encoder callbacks. */ +typedef enum { + PB_WT_VARINT = 0, + PB_WT_64BIT = 1, + PB_WT_STRING = 2, + PB_WT_32BIT = 5 +} pb_wire_type_t; + +/* Structure for defining the handling of unknown/extension fields. + * Usually the pb_extension_type_t structure is automatically generated, + * while the pb_extension_t structure is created by the user. However, + * if you want to catch all unknown fields, you can also create a custom + * pb_extension_type_t with your own callback. + */ +typedef struct pb_extension_type_s pb_extension_type_t; +typedef struct pb_extension_s pb_extension_t; +struct pb_extension_type_s { + /* Called for each unknown field in the message. + * If you handle the field, read off all of its data and return true. + * If you do not handle the field, do not read anything and return true. + * If you run into an error, return false. + * Set to NULL for default handler. + */ + bool (*decode)(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, + pb_wire_type_t wire_type); + + /* Called once after all regular fields have been encoded. + * If you have something to write, do so and return true. + * If you do not have anything to write, just return true. + * If you run into an error, return false. + * Set to NULL for default handler. + */ + bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension); + + /* Free field for use by the callback. */ + const void *arg; +}; + +struct pb_extension_s { + /* Type describing the extension field. Usually you'll initialize + * this to a pointer to the automatically generated structure. */ + const pb_extension_type_t *type; + + /* Destination for the decoded data. This must match the datatype + * of the extension field. */ + void *dest; + + /* Pointer to the next extension handler, or NULL. + * If this extension does not match a field, the next handler is + * automatically called. */ + pb_extension_t *next; + + /* The decoder sets this to true if the extension was found. + * Ignored for encoding. */ + bool found; +}; + +#define pb_extension_init_zero \ + { NULL, NULL, NULL, false } + +/* Memory allocation functions to use. You can define pb_realloc and + * pb_free to custom functions if you want. */ +#ifdef PB_ENABLE_MALLOC +#ifndef pb_realloc +#define pb_realloc(ptr, size) realloc(ptr, size) +#endif +#ifndef pb_free +#define pb_free(ptr) free(ptr) +#endif +#endif + +/* This is used to inform about need to regenerate .pb.h/.pb.c files. */ +#define PB_PROTO_HEADER_VERSION 40 + +/* These macros are used to declare pb_field_t's in the constant array. */ +/* Size of a structure member, in bytes. */ +#define pb_membersize(st, m) (sizeof((st *)0)->m) +/* Number of entries in an array. */ +#define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0])) +/* Delta from start of one member to the start of another member. */ +#define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2)) + +/* Force expansion of macro value */ +#define PB_EXPAND(x) x + +/* Binding of a message field set into a specific structure */ +#define PB_BIND(msgname, structname, width) \ + const uint32_t structname##_field_info[] PB_PROGMEM = { \ + msgname##_FIELDLIST(PB_GEN_FIELD_INFO_##width, structname) 0}; \ + const pb_msgdesc_t *const structname##_submsg_info[] = { \ + msgname##_FIELDLIST(PB_GEN_SUBMSG_INFO, structname) NULL}; \ + const pb_msgdesc_t structname##_msg = { \ + 0 msgname##_FIELDLIST(PB_GEN_FIELD_COUNT, structname), \ + structname##_field_info, \ + structname##_submsg_info, \ + msgname##_DEFAULT, \ + msgname##_CALLBACK, \ + }; \ + msgname##_FIELDLIST(PB_GEN_FIELD_INFO_ASSERT_##width, structname) + +#define PB_GEN_FIELD_COUNT(structname, atype, htype, ltype, fieldname, tag) +1 + +#define PB_GEN_FIELD_INFO_1(structname, atype, htype, ltype, fieldname, tag) \ + PB_GEN_FIELD_INFO(1, structname, atype, htype, ltype, fieldname, tag) + +#define PB_GEN_FIELD_INFO_2(structname, atype, htype, ltype, fieldname, tag) \ + PB_GEN_FIELD_INFO(2, structname, atype, htype, ltype, fieldname, tag) + +#define PB_GEN_FIELD_INFO_4(structname, atype, htype, ltype, fieldname, tag) \ + PB_GEN_FIELD_INFO(4, structname, atype, htype, ltype, fieldname, tag) + +#define PB_GEN_FIELD_INFO_8(structname, atype, htype, ltype, fieldname, tag) \ + PB_GEN_FIELD_INFO(8, structname, atype, htype, ltype, fieldname, tag) + +#define PB_GEN_FIELD_INFO_AUTO(structname, atype, htype, ltype, fieldname, \ + tag) \ + PB_GEN_FIELD_INFO_AUTO2(PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype), \ + structname, atype, htype, ltype, fieldname, tag) + +#define PB_GEN_FIELD_INFO_AUTO2(width, structname, atype, htype, ltype, \ + fieldname, tag) \ + PB_GEN_FIELD_INFO(width, structname, atype, htype, ltype, fieldname, tag) + +#define PB_GEN_FIELD_INFO(width, structname, atype, htype, ltype, fieldname, \ + tag) \ + PB_FIELDINFO_##width( \ + tag, PB_ATYPE_##atype | PB_HTYPE_##htype | PB_LTYPE_MAP_##ltype, \ + PB_DATA_OFFSET_##atype(htype, structname, fieldname), \ + PB_DATA_SIZE_##atype(htype, structname, fieldname), \ + PB_SIZE_OFFSET_##atype(htype, structname, fieldname), \ + PB_ARRAY_SIZE_##atype(htype, structname, fieldname)) + +#define PB_GEN_FIELD_INFO_ASSERT_1(structname, atype, htype, ltype, fieldname, \ + tag) \ + PB_GEN_FIELD_INFO_ASSERT(1, structname, atype, htype, ltype, fieldname, tag) + +#define PB_GEN_FIELD_INFO_ASSERT_2(structname, atype, htype, ltype, fieldname, \ + tag) \ + PB_GEN_FIELD_INFO_ASSERT(2, structname, atype, htype, ltype, fieldname, tag) + +#define PB_GEN_FIELD_INFO_ASSERT_4(structname, atype, htype, ltype, fieldname, \ + tag) \ + PB_GEN_FIELD_INFO_ASSERT(4, structname, atype, htype, ltype, fieldname, tag) + +#define PB_GEN_FIELD_INFO_ASSERT_8(structname, atype, htype, ltype, fieldname, \ + tag) \ + PB_GEN_FIELD_INFO_ASSERT(8, structname, atype, htype, ltype, fieldname, tag) + +#define PB_GEN_FIELD_INFO_ASSERT_AUTO(structname, atype, htype, ltype, \ + fieldname, tag) \ + PB_GEN_FIELD_INFO_ASSERT_AUTO2(PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype), \ + structname, atype, htype, ltype, fieldname, \ + tag) + +#define PB_GEN_FIELD_INFO_ASSERT_AUTO2(width, structname, atype, htype, ltype, \ + fieldname, tag) \ + PB_GEN_FIELD_INFO_ASSERT(width, structname, atype, htype, ltype, fieldname, \ + tag) + +#define PB_GEN_FIELD_INFO_ASSERT(width, structname, atype, htype, ltype, \ + fieldname, tag) \ + PB_FIELDINFO_ASSERT_##width( \ + tag, PB_ATYPE_##atype | PB_HTYPE_##htype | PB_LTYPE_MAP_##ltype, \ + PB_DATA_OFFSET_##atype(htype, structname, fieldname), \ + PB_DATA_SIZE_##atype(htype, structname, fieldname), \ + PB_SIZE_OFFSET_##atype(htype, structname, fieldname), \ + PB_ARRAY_SIZE_##atype(htype, structname, fieldname)) + +#define PB_DATA_OFFSET_STATIC(htype, structname, fieldname) \ + PB_DATA_OFFSET_##htype(structname, fieldname) +#define PB_DATA_OFFSET_POINTER(htype, structname, fieldname) \ + PB_DATA_OFFSET_##htype(structname, fieldname) +#define PB_DATA_OFFSET_CALLBACK(htype, structname, fieldname) \ + PB_DATA_OFFSET_##htype(structname, fieldname) +#define PB_DATA_OFFSET_REQUIRED(structname, fieldname) \ + offsetof(structname, fieldname) +#define PB_DATA_OFFSET_SINGULAR(structname, fieldname) \ + offsetof(structname, fieldname) +#define PB_DATA_OFFSET_ONEOF(structname, fieldname) \ + offsetof(structname, PB_ONEOF_NAME(FULL, fieldname)) +#define PB_DATA_OFFSET_OPTIONAL(structname, fieldname) \ + offsetof(structname, fieldname) +#define PB_DATA_OFFSET_REPEATED(structname, fieldname) \ + offsetof(structname, fieldname) +#define PB_DATA_OFFSET_FIXARRAY(structname, fieldname) \ + offsetof(structname, fieldname) + +#define PB_SIZE_OFFSET_STATIC(htype, structname, fieldname) \ + PB_SIZE_OFFSET_##htype(structname, fieldname) +#define PB_SIZE_OFFSET_POINTER(htype, structname, fieldname) \ + PB_SIZE_OFFSET_PTR_##htype(structname, fieldname) +#define PB_SIZE_OFFSET_CALLBACK(htype, structname, fieldname) \ + PB_SIZE_OFFSET_CB_##htype(structname, fieldname) +#define PB_SIZE_OFFSET_REQUIRED(structname, fieldname) 0 +#define PB_SIZE_OFFSET_SINGULAR(structname, fieldname) 0 +#define PB_SIZE_OFFSET_ONEOF(structname, fieldname) \ + PB_SIZE_OFFSET_ONEOF2(structname, PB_ONEOF_NAME(FULL, fieldname), \ + PB_ONEOF_NAME(UNION, fieldname)) +#define PB_SIZE_OFFSET_ONEOF2(structname, fullname, unionname) \ + PB_SIZE_OFFSET_ONEOF3(structname, fullname, unionname) +#define PB_SIZE_OFFSET_ONEOF3(structname, fullname, unionname) \ + pb_delta(structname, fullname, which_##unionname) +#define PB_SIZE_OFFSET_OPTIONAL(structname, fieldname) \ + pb_delta(structname, fieldname, has_##fieldname) +#define PB_SIZE_OFFSET_REPEATED(structname, fieldname) \ + pb_delta(structname, fieldname, fieldname##_count) +#define PB_SIZE_OFFSET_FIXARRAY(structname, fieldname) 0 +#define PB_SIZE_OFFSET_PTR_REQUIRED(structname, fieldname) 0 +#define PB_SIZE_OFFSET_PTR_SINGULAR(structname, fieldname) 0 +#define PB_SIZE_OFFSET_PTR_ONEOF(structname, fieldname) \ + PB_SIZE_OFFSET_ONEOF(structname, fieldname) +#define PB_SIZE_OFFSET_PTR_OPTIONAL(structname, fieldname) 0 +#define PB_SIZE_OFFSET_PTR_REPEATED(structname, fieldname) \ + PB_SIZE_OFFSET_REPEATED(structname, fieldname) +#define PB_SIZE_OFFSET_PTR_FIXARRAY(structname, fieldname) 0 +#define PB_SIZE_OFFSET_CB_REQUIRED(structname, fieldname) 0 +#define PB_SIZE_OFFSET_CB_SINGULAR(structname, fieldname) 0 +#define PB_SIZE_OFFSET_CB_ONEOF(structname, fieldname) \ + PB_SIZE_OFFSET_ONEOF(structname, fieldname) +#define PB_SIZE_OFFSET_CB_OPTIONAL(structname, fieldname) 0 +#define PB_SIZE_OFFSET_CB_REPEATED(structname, fieldname) 0 +#define PB_SIZE_OFFSET_CB_FIXARRAY(structname, fieldname) 0 + +#define PB_ARRAY_SIZE_STATIC(htype, structname, fieldname) \ + PB_ARRAY_SIZE_##htype(structname, fieldname) +#define PB_ARRAY_SIZE_POINTER(htype, structname, fieldname) 1 +#define PB_ARRAY_SIZE_CALLBACK(htype, structname, fieldname) 1 +#define PB_ARRAY_SIZE_REQUIRED(structname, fieldname) 1 +#define PB_ARRAY_SIZE_SINGULAR(structname, fieldname) 1 +#define PB_ARRAY_SIZE_OPTIONAL(structname, fieldname) 1 +#define PB_ARRAY_SIZE_ONEOF(structname, fieldname) 1 +#define PB_ARRAY_SIZE_REPEATED(structname, fieldname) \ + pb_arraysize(structname, fieldname) +#define PB_ARRAY_SIZE_FIXARRAY(structname, fieldname) \ + pb_arraysize(structname, fieldname) + +#define PB_DATA_SIZE_STATIC(htype, structname, fieldname) \ + PB_DATA_SIZE_##htype(structname, fieldname) +#define PB_DATA_SIZE_POINTER(htype, structname, fieldname) \ + PB_DATA_SIZE_PTR_##htype(structname, fieldname) +#define PB_DATA_SIZE_CALLBACK(htype, structname, fieldname) \ + PB_DATA_SIZE_CB_##htype(structname, fieldname) +#define PB_DATA_SIZE_REQUIRED(structname, fieldname) \ + pb_membersize(structname, fieldname) +#define PB_DATA_SIZE_SINGULAR(structname, fieldname) \ + pb_membersize(structname, fieldname) +#define PB_DATA_SIZE_OPTIONAL(structname, fieldname) \ + pb_membersize(structname, fieldname) +#define PB_DATA_SIZE_ONEOF(structname, fieldname) \ + pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)) +#define PB_DATA_SIZE_REPEATED(structname, fieldname) \ + pb_membersize(structname, fieldname[0]) +#define PB_DATA_SIZE_FIXARRAY(structname, fieldname) \ + pb_membersize(structname, fieldname[0]) +#define PB_DATA_SIZE_PTR_REQUIRED(structname, fieldname) \ + pb_membersize(structname, fieldname[0]) +#define PB_DATA_SIZE_PTR_SINGULAR(structname, fieldname) \ + pb_membersize(structname, fieldname[0]) +#define PB_DATA_SIZE_PTR_OPTIONAL(structname, fieldname) \ + pb_membersize(structname, fieldname[0]) +#define PB_DATA_SIZE_PTR_ONEOF(structname, fieldname) \ + pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)[0]) +#define PB_DATA_SIZE_PTR_REPEATED(structname, fieldname) \ + pb_membersize(structname, fieldname[0]) +#define PB_DATA_SIZE_PTR_FIXARRAY(structname, fieldname) \ + pb_membersize(structname, fieldname[0]) +#define PB_DATA_SIZE_CB_REQUIRED(structname, fieldname) \ + pb_membersize(structname, fieldname) +#define PB_DATA_SIZE_CB_SINGULAR(structname, fieldname) \ + pb_membersize(structname, fieldname) +#define PB_DATA_SIZE_CB_OPTIONAL(structname, fieldname) \ + pb_membersize(structname, fieldname) +#define PB_DATA_SIZE_CB_ONEOF(structname, fieldname) \ + pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)) +#define PB_DATA_SIZE_CB_REPEATED(structname, fieldname) \ + pb_membersize(structname, fieldname) +#define PB_DATA_SIZE_CB_FIXARRAY(structname, fieldname) \ + pb_membersize(structname, fieldname) + +#define PB_ONEOF_NAME(type, tuple) PB_EXPAND(PB_ONEOF_NAME_##type tuple) +#define PB_ONEOF_NAME_UNION(unionname, membername, fullname) unionname +#define PB_ONEOF_NAME_MEMBER(unionname, membername, fullname) membername +#define PB_ONEOF_NAME_FULL(unionname, membername, fullname) fullname + +#define PB_GEN_SUBMSG_INFO(structname, atype, htype, ltype, fieldname, tag) \ + PB_SUBMSG_INFO_##htype(ltype, structname, fieldname) + +#define PB_SUBMSG_INFO_REQUIRED(ltype, structname, fieldname) \ + PB_SUBMSG_INFO_##ltype(structname##_##fieldname##_MSGTYPE) +#define PB_SUBMSG_INFO_SINGULAR(ltype, structname, fieldname) \ + PB_SUBMSG_INFO_##ltype(structname##_##fieldname##_MSGTYPE) +#define PB_SUBMSG_INFO_OPTIONAL(ltype, structname, fieldname) \ + PB_SUBMSG_INFO_##ltype(structname##_##fieldname##_MSGTYPE) +#define PB_SUBMSG_INFO_ONEOF(ltype, structname, fieldname) \ + PB_SUBMSG_INFO_ONEOF2(ltype, structname, PB_ONEOF_NAME(UNION, fieldname), \ + PB_ONEOF_NAME(MEMBER, fieldname)) +#define PB_SUBMSG_INFO_ONEOF2(ltype, structname, unionname, membername) \ + PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername) +#define PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername) \ + PB_SUBMSG_INFO_##ltype(structname##_##unionname##_##membername##_MSGTYPE) +#define PB_SUBMSG_INFO_REPEATED(ltype, structname, fieldname) \ + PB_SUBMSG_INFO_##ltype(structname##_##fieldname##_MSGTYPE) +#define PB_SUBMSG_INFO_FIXARRAY(ltype, structname, fieldname) \ + PB_SUBMSG_INFO_##ltype(structname##_##fieldname##_MSGTYPE) +#define PB_SUBMSG_INFO_BOOL(t) +#define PB_SUBMSG_INFO_BYTES(t) +#define PB_SUBMSG_INFO_DOUBLE(t) +#define PB_SUBMSG_INFO_ENUM(t) +#define PB_SUBMSG_INFO_UENUM(t) +#define PB_SUBMSG_INFO_FIXED32(t) +#define PB_SUBMSG_INFO_FIXED64(t) +#define PB_SUBMSG_INFO_FLOAT(t) +#define PB_SUBMSG_INFO_INT32(t) +#define PB_SUBMSG_INFO_INT64(t) +#define PB_SUBMSG_INFO_MESSAGE(t) PB_SUBMSG_DESCRIPTOR(t) +#define PB_SUBMSG_INFO_MSG_W_CB(t) PB_SUBMSG_DESCRIPTOR(t) +#define PB_SUBMSG_INFO_SFIXED32(t) +#define PB_SUBMSG_INFO_SFIXED64(t) +#define PB_SUBMSG_INFO_SINT32(t) +#define PB_SUBMSG_INFO_SINT64(t) +#define PB_SUBMSG_INFO_STRING(t) +#define PB_SUBMSG_INFO_UINT32(t) +#define PB_SUBMSG_INFO_UINT64(t) +#define PB_SUBMSG_INFO_EXTENSION(t) +#define PB_SUBMSG_INFO_FIXED_LENGTH_BYTES(t) +#define PB_SUBMSG_DESCRIPTOR(t) &(t##_msg), + +/* The field descriptors use a variable width format, with width of either + * 1, 2, 4 or 8 of 32-bit words. The two lowest bytes of the first byte always + * encode the descriptor size, 6 lowest bits of field tag number, and 8 bits + * of the field type. + * + * Descriptor size is encoded as 0 = 1 word, 1 = 2 words, 2 = 4 words, 3 = 8 + * words. + * + * Formats, listed starting with the least significant bit of the first word. + * 1 word: [2-bit len] [6-bit tag] [8-bit type] [8-bit data_offset] [4-bit + * size_offset] [4-bit data_size] + * + * 2 words: [2-bit len] [6-bit tag] [8-bit type] [12-bit array_size] [4-bit + * size_offset] [16-bit data_offset] [12-bit data_size] [4-bit tag>>6] + * + * 4 words: [2-bit len] [6-bit tag] [8-bit type] [16-bit array_size] + * [8-bit size_offset] [24-bit tag>>6] + * [32-bit data_offset] + * [32-bit data_size] + * + * 8 words: [2-bit len] [6-bit tag] [8-bit type] [16-bit reserved] + * [8-bit size_offset] [24-bit tag>>6] + * [32-bit data_offset] + * [32-bit data_size] + * [32-bit array_size] + * [32-bit reserved] + * [32-bit reserved] + * [32-bit reserved] + */ + +#define PB_FIELDINFO_1(tag, type, data_offset, data_size, size_offset, \ + array_size) \ + (0 | (((tag) << 2) & 0xFF) | ((type) << 8) | \ + (((uint32_t)(data_offset)&0xFF) << 16) | \ + (((uint32_t)(size_offset)&0x0F) << 24) | \ + (((uint32_t)(data_size)&0x0F) << 28)), + +#define PB_FIELDINFO_2(tag, type, data_offset, data_size, size_offset, \ + array_size) \ + (1 | (((tag) << 2) & 0xFF) | ((type) << 8) | \ + (((uint32_t)(array_size)&0xFFF) << 16) | \ + (((uint32_t)(size_offset)&0x0F) << 28)), \ + (((uint32_t)(data_offset)&0xFFFF) | \ + (((uint32_t)(data_size)&0xFFF) << 16) | \ + (((uint32_t)(tag)&0x2c0) << 22)), + +#define PB_FIELDINFO_4(tag, type, data_offset, data_size, size_offset, \ + array_size) \ + (2 | (((tag) << 2) & 0xFF) | ((type) << 8) | \ + (((uint32_t)(array_size)&0xFFFF) << 16)), \ + ((uint32_t)(int8_t)(size_offset) | \ + (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ + (data_offset), (data_size), + +#define PB_FIELDINFO_8(tag, type, data_offset, data_size, size_offset, \ + array_size) \ + (3 | (((tag) << 2) & 0xFF) | ((type) << 8)), \ + ((uint32_t)(int8_t)(size_offset) | \ + (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ + (data_offset), (data_size), (array_size) + +/* These assertions verify that the field information fits in the allocated + * space. The generator tries to automatically determine the correct width that + * can fit all data associated with a message. These asserts will fail only if + * there has been a problem in the automatic logic - this may be worth reporting + * as a bug. As a workaround, you can increase the descriptor width by defining + * PB_FIELDINFO_WIDTH or by setting descriptorsize option in .options file. + */ +#define PB_FITS(value, bits) ((uint32_t)(value) < ((uint32_t)1 << bits)) +#define PB_FIELDINFO_ASSERT_1(tag, type, data_offset, data_size, size_offset, \ + array_size) \ + PB_STATIC_ASSERT(PB_FITS(tag, 6) && PB_FITS(data_offset, 8) && \ + PB_FITS(size_offset, 4) && PB_FITS(data_size, 4) && \ + PB_FITS(array_size, 1), \ + FIELDINFO_DOES_NOT_FIT_width1_field##tag) + +#define PB_FIELDINFO_ASSERT_2(tag, type, data_offset, data_size, size_offset, \ + array_size) \ + PB_STATIC_ASSERT(PB_FITS(tag, 10) && PB_FITS(data_offset, 16) && \ + PB_FITS(size_offset, 4) && PB_FITS(data_size, 12) && \ + PB_FITS(array_size, 12), \ + FIELDINFO_DOES_NOT_FIT_width2_field##tag) + +#ifndef PB_FIELD_32BIT +/* Maximum field sizes are still 16-bit if pb_size_t is 16-bit */ +#define PB_FIELDINFO_ASSERT_4(tag, type, data_offset, data_size, size_offset, \ + array_size) \ + PB_STATIC_ASSERT(PB_FITS(tag, 16) && PB_FITS(data_offset, 16) && \ + PB_FITS((int8_t)size_offset, 8) && \ + PB_FITS(data_size, 16) && PB_FITS(array_size, 16), \ + FIELDINFO_DOES_NOT_FIT_width4_field##tag) + +#define PB_FIELDINFO_ASSERT_8(tag, type, data_offset, data_size, size_offset, \ + array_size) \ + PB_STATIC_ASSERT(PB_FITS(tag, 16) && PB_FITS(data_offset, 16) && \ + PB_FITS((int8_t)size_offset, 8) && \ + PB_FITS(data_size, 16) && PB_FITS(array_size, 16), \ + FIELDINFO_DOES_NOT_FIT_width8_field##tag) +#else +/* Up to 32-bit fields supported. + * Note that the checks are against 31 bits to avoid compiler warnings about + * shift wider than type in the test. I expect that there is no reasonable use + * for >2GB messages with nanopb anyway. + */ +#define PB_FIELDINFO_ASSERT_4(tag, type, data_offset, data_size, size_offset, \ + array_size) \ + PB_STATIC_ASSERT(PB_FITS(tag, 30) && PB_FITS(data_offset, 31) && \ + PB_FITS((int8_t)size_offset, 8) && \ + PB_FITS(data_size, 31) && PB_FITS(array_size, 16), \ + FIELDINFO_DOES_NOT_FIT_width4_field##tag) + +#define PB_FIELDINFO_ASSERT_8(tag, type, data_offset, data_size, size_offset, \ + array_size) \ + PB_STATIC_ASSERT(PB_FITS(tag, 30) && PB_FITS(data_offset, 31) && \ + PB_FITS((int8_t)size_offset, 8) && \ + PB_FITS(data_size, 31) && PB_FITS(array_size, 31), \ + FIELDINFO_DOES_NOT_FIT_width8_field##tag) +#endif + +/* Automatic picking of FIELDINFO width: + * Uses width 1 when possible, otherwise resorts to width 2. + */ + +#ifndef PB_FIELDINFO_WIDTH +#define PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype) \ + PB_FIELDINFO_WIDTH_##atype(htype, ltype) +#define PB_FIELDINFO_WIDTH_STATIC(htype, ltype) \ + PB_FIELDINFO_WIDTH_##htype(ltype) +#define PB_FIELDINFO_WIDTH_POINTER(htype, ltype) \ + PB_FIELDINFO_WIDTH_##htype(ltype) +#define PB_FIELDINFO_WIDTH_CALLBACK(htype, ltype) 2 +#define PB_FIELDINFO_WIDTH_REQUIRED(ltype) PB_FIELDINFO_WIDTH_##ltype +#define PB_FIELDINFO_WIDTH_SINGULAR(ltype) PB_FIELDINFO_WIDTH_##ltype +#define PB_FIELDINFO_WIDTH_OPTIONAL(ltype) PB_FIELDINFO_WIDTH_##ltype +#define PB_FIELDINFO_WIDTH_ONEOF(ltype) PB_FIELDINFO_WIDTH_##ltype +#define PB_FIELDINFO_WIDTH_REPEATED(ltype) 2 +#define PB_FIELDINFO_WIDTH_FIXARRAY(ltype) 2 +#define PB_FIELDINFO_WIDTH_BOOL 1 +#define PB_FIELDINFO_WIDTH_BYTES 2 +#define PB_FIELDINFO_WIDTH_DOUBLE 1 +#define PB_FIELDINFO_WIDTH_ENUM 1 +#define PB_FIELDINFO_WIDTH_UENUM 1 +#define PB_FIELDINFO_WIDTH_FIXED32 1 +#define PB_FIELDINFO_WIDTH_FIXED64 1 +#define PB_FIELDINFO_WIDTH_FLOAT 1 +#define PB_FIELDINFO_WIDTH_INT32 1 +#define PB_FIELDINFO_WIDTH_INT64 1 +#define PB_FIELDINFO_WIDTH_MESSAGE 2 +#define PB_FIELDINFO_WIDTH_SFIXED32 1 +#define PB_FIELDINFO_WIDTH_SFIXED64 1 +#define PB_FIELDINFO_WIDTH_SINT32 1 +#define PB_FIELDINFO_WIDTH_SINT64 1 +#define PB_FIELDINFO_WIDTH_STRING 2 +#define PB_FIELDINFO_WIDTH_UINT32 1 +#define PB_FIELDINFO_WIDTH_UINT64 1 +#define PB_FIELDINFO_WIDTH_EXTENSION 1 +#define PB_FIELDINFO_WIDTH_FIXED_LENGTH_BYTES 2 +#else +#define PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype) PB_FIELDINFO_WIDTH +#endif + +/* The mapping from protobuf types to LTYPEs is done using these macros. */ +#define PB_LTYPE_MAP_BOOL PB_LTYPE_BOOL +#define PB_LTYPE_MAP_BYTES PB_LTYPE_BYTES +#define PB_LTYPE_MAP_DOUBLE PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_ENUM PB_LTYPE_VARINT +#define PB_LTYPE_MAP_UENUM PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_FIXED32 PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_FIXED64 PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_FLOAT PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_INT32 PB_LTYPE_VARINT +#define PB_LTYPE_MAP_INT64 PB_LTYPE_VARINT +#define PB_LTYPE_MAP_MESSAGE PB_LTYPE_SUBMESSAGE +#define PB_LTYPE_MAP_MSG_W_CB PB_LTYPE_SUBMSG_W_CB +#define PB_LTYPE_MAP_SFIXED32 PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_SFIXED64 PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT +#define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT +#define PB_LTYPE_MAP_STRING PB_LTYPE_STRING +#define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION +#define PB_LTYPE_MAP_FIXED_LENGTH_BYTES PB_LTYPE_FIXED_LENGTH_BYTES + +/* These macros are used for giving out error messages. + * They are mostly a debugging aid; the main error information + * is the true/false return value from functions. + * Some code space can be saved by disabling the error + * messages if not used. + * + * PB_SET_ERROR() sets the error message if none has been set yet. + * msg must be a constant string literal. + * PB_GET_ERROR() always returns a pointer to a string. + * PB_RETURN_ERROR() sets the error and returns false from current + * function. + */ +#ifdef PB_NO_ERRMSG +#define PB_SET_ERROR(stream, msg) PB_UNUSED(stream) +#define PB_GET_ERROR(stream) "(errmsg disabled)" +#else +#define PB_SET_ERROR(stream, msg) \ + (stream->errmsg = (stream)->errmsg ? (stream)->errmsg : (msg)) +#define PB_GET_ERROR(stream) ((stream)->errmsg ? (stream)->errmsg : "(none)") +#endif + +#define PB_RETURN_ERROR(stream, msg) return PB_SET_ERROR(stream, msg), false + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#ifdef __cplusplus +#if __cplusplus >= 201103L +#define PB_CONSTEXPR constexpr +#else // __cplusplus >= 201103L +#define PB_CONSTEXPR +#endif // __cplusplus >= 201103L + +#if __cplusplus >= 201703L +#define PB_INLINE_CONSTEXPR inline constexpr +#else // __cplusplus >= 201703L +#define PB_INLINE_CONSTEXPR PB_CONSTEXPR +#endif // __cplusplus >= 201703L + +namespace nanopb { +// Each type will be partially specialized by the generator. +template struct MessageDescriptor; +} // namespace nanopb +#endif /* __cplusplus */ + +#endif diff --git a/src/nanopb/pb_common.c b/src/nanopb/pb_common.c new file mode 100644 index 00000000..9b7baaac --- /dev/null +++ b/src/nanopb/pb_common.c @@ -0,0 +1,276 @@ +/* pb_common.c: Common support functions for pb_encode.c and pb_decode.c. + * + * 2014 Petteri Aimonen + */ + +#include "os.h" +#include "pb_common.h" + +static bool load_descriptor_values(pb_field_iter_t *iter) { + uint32_t word0; + uint32_t data_offset; + uint8_t format; + int8_t size_offset; + + if (iter->index >= iter->descriptor->field_count) + return false; + + word0 = PB_PROGMEM_READU32( + ((uint32_t *)PIC(((pb_msgdesc_t *)PIC(iter->descriptor)) + ->field_info))[iter->field_info_index]); + format = word0 & 3; + iter->tag = (pb_size_t)((word0 >> 2) & 0x3F); + iter->type = (pb_type_t)((word0 >> 8) & 0xFF); + + if (format == 0) { + /* 1-word format */ + iter->array_size = 1; + size_offset = (int8_t)((word0 >> 24) & 0x0F); + data_offset = (word0 >> 16) & 0xFF; + iter->data_size = (pb_size_t)((word0 >> 28) & 0x0F); + } else if (format == 1) { + /* 2-word format */ + uint32_t word1 = PB_PROGMEM_READU32( + ((uint32_t *)PIC(((pb_msgdesc_t *)PIC(iter->descriptor)) + ->field_info))[iter->field_info_index + 1]); + + iter->array_size = (pb_size_t)((word0 >> 16) & 0x0FFF); + iter->tag = (pb_size_t)(iter->tag | ((word1 >> 28) << 6)); + size_offset = (int8_t)((word0 >> 28) & 0x0F); + data_offset = word1 & 0xFFFF; + iter->data_size = (pb_size_t)((word1 >> 16) & 0x0FFF); + } else if (format == 2) { + /* 4-word format */ + uint32_t word1 = PB_PROGMEM_READU32( + iter->descriptor->field_info[iter->field_info_index + 1]); + uint32_t word2 = PB_PROGMEM_READU32( + iter->descriptor->field_info[iter->field_info_index + 2]); + uint32_t word3 = PB_PROGMEM_READU32( + iter->descriptor->field_info[iter->field_info_index + 3]); + + iter->array_size = (pb_size_t)(word0 >> 16); + iter->tag = (pb_size_t)(iter->tag | ((word1 >> 8) << 6)); + size_offset = (int8_t)(word1 & 0xFF); + data_offset = word2; + iter->data_size = (pb_size_t)word3; + } else { + /* 8-word format */ + uint32_t word1 = PB_PROGMEM_READU32( + iter->descriptor->field_info[iter->field_info_index + 1]); + uint32_t word2 = PB_PROGMEM_READU32( + iter->descriptor->field_info[iter->field_info_index + 2]); + uint32_t word3 = PB_PROGMEM_READU32( + iter->descriptor->field_info[iter->field_info_index + 3]); + uint32_t word4 = PB_PROGMEM_READU32( + iter->descriptor->field_info[iter->field_info_index + 4]); + + iter->array_size = (pb_size_t)word4; + iter->tag = (pb_size_t)(iter->tag | ((word1 >> 8) << 6)); + size_offset = (int8_t)(word1 & 0xFF); + data_offset = word2; + iter->data_size = (pb_size_t)word3; + } + + iter->pField = (char *)iter->message + data_offset; + + if (size_offset) { + iter->pSize = (char *)iter->pField - size_offset; + } else if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED && + (PB_ATYPE(iter->type) == PB_ATYPE_STATIC || + PB_ATYPE(iter->type) == PB_ATYPE_POINTER)) { + /* Fixed count array */ + iter->pSize = &iter->array_size; + } else { + iter->pSize = NULL; + } + + if (PB_ATYPE(iter->type) == PB_ATYPE_POINTER && iter->pField != NULL) { + iter->pData = *(void **)iter->pField; + } else { + iter->pData = iter->pField; + } + + if (PB_LTYPE_IS_SUBMSG(iter->type)) { + iter->submsg_desc = ((const pb_msgdesc_t *const *)PIC( + ((pb_msgdesc_t *)PIC(iter->descriptor)) + ->submsg_info))[iter->submessage_index]; + } else { + iter->submsg_desc = NULL; + } + + return true; +} + +static void advance_iterator(pb_field_iter_t *iter) { + iter->index++; + + if (iter->index >= iter->descriptor->field_count) { + /* Restart */ + iter->index = 0; + iter->field_info_index = 0; + iter->submessage_index = 0; + iter->required_field_index = 0; + } else { + /* Increment indexes based on previous field type. + * All field info formats have the following fields: + * - lowest 2 bits tell the amount of words in the descriptor (2^n words) + * - bits 2..7 give the lowest bits of tag number. + * - bits 8..15 give the field type. + */ + uint32_t prev_descriptor = PB_PROGMEM_READU32( + ((uint32_t *)PIC(((pb_msgdesc_t *)PIC(iter->descriptor)) + ->field_info))[iter->field_info_index]); + + pb_type_t prev_type = (prev_descriptor >> 8) & 0xFF; + pb_size_t descriptor_len = (pb_size_t)(1 << (prev_descriptor & 3)); + + iter->field_info_index = + (pb_size_t)(iter->field_info_index + descriptor_len); + + if (PB_HTYPE(prev_type) == PB_HTYPE_REQUIRED) { + iter->required_field_index++; + } + + if (PB_LTYPE_IS_SUBMSG(prev_type)) { + iter->submessage_index++; + } + } +} + +bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_msgdesc_t *desc, + void *message) { + memset(iter, 0, sizeof(*iter)); + + iter->descriptor = PIC(desc); + iter->message = message; + + return load_descriptor_values(iter); +} + +bool pb_field_iter_begin_extension(pb_field_iter_t *iter, + pb_extension_t *extension) { + const pb_msgdesc_t *msg = (const pb_msgdesc_t *)extension->type->arg; + bool status; + + uint32_t word0 = PB_PROGMEM_READU32(msg->field_info[0]); + if (PB_ATYPE(word0 >> 8) == PB_ATYPE_POINTER) { + /* For pointer extensions, the pointer is stored directly + * in the extension structure. This avoids having an extra + * indirection. */ + status = pb_field_iter_begin(iter, msg, &extension->dest); + } else { + status = pb_field_iter_begin(iter, msg, extension->dest); + } + + iter->pSize = &extension->found; + return status; +} + +bool pb_field_iter_next(pb_field_iter_t *iter) { + advance_iterator(iter); + (void)load_descriptor_values(iter); + return iter->index != 0; +} + +bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag) { + if (iter->tag == tag) { + return true; /* Nothing to do, correct field already. */ + } else { + pb_size_t start = iter->index; + uint32_t fieldinfo; + + do { + /* Advance iterator but don't load values yet */ + advance_iterator(iter); + + /* Do fast check for tag number match */ + fieldinfo = PB_PROGMEM_READU32( + ((uint32_t *)PIC(((pb_msgdesc_t *)PIC(iter->descriptor)) + ->field_info))[iter->field_info_index]); + + if (((fieldinfo >> 2) & 0x3F) == (tag & 0x3F)) { + /* Good candidate, check further */ + (void)load_descriptor_values(iter); + + if (iter->tag == tag && PB_LTYPE(iter->type) != PB_LTYPE_EXTENSION) { + /* Found it */ + return true; + } + } + } while (iter->index != start); + + /* Searched all the way back to start, and found nothing. */ + (void)load_descriptor_values(iter); + return false; + } +} + +bool pb_default_field_callback(pb_istream_t *istream, pb_ostream_t *ostream, + const pb_field_t *field) { + if (field->data_size == sizeof(pb_callback_t)) { + pb_callback_t *pCallback = (pb_callback_t *)field->pData; + + if (pCallback != NULL) { + if (istream != NULL && pCallback->funcs.decode != NULL) { + return pCallback->funcs.decode(istream, field, &pCallback->arg); + } + + if (ostream != NULL && pCallback->funcs.encode != NULL) { + return pCallback->funcs.encode(ostream, field, &pCallback->arg); + } + } + } + + return true; /* Success, but didn't do anything */ +} + +#ifdef PB_VALIDATE_UTF8 + +/* This function checks whether a string is valid UTF-8 text. + * + * Algorithm is adapted from https://www.cl.cam.ac.uk/~mgk25/ucs/utf8_check.c + * Original copyright: Markus Kuhn 2005-03-30 + * Licensed under "Short code license", which allows use under MIT license or + * any compatible with it. + */ + +bool pb_validate_utf8(const char *str) { + const pb_byte_t *s = (const pb_byte_t *)str; + while (*s) { + if (*s < 0x80) { + /* 0xxxxxxx */ + s++; + } else if ((s[0] & 0xe0) == 0xc0) { + /* 110XXXXx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || (s[0] & 0xfe) == 0xc0) /* overlong? */ + return false; + else + s += 2; + } else if ((s[0] & 0xf0) == 0xe0) { + /* 1110XXXX 10Xxxxxx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 || + (s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || /* overlong? */ + (s[0] == 0xed && (s[1] & 0xe0) == 0xa0) || /* surrogate? */ + (s[0] == 0xef && s[1] == 0xbf && + (s[2] & 0xfe) == 0xbe)) /* U+FFFE or U+FFFF? */ + return false; + else + s += 3; + } else if ((s[0] & 0xf8) == 0xf0) { + /* 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 || + (s[3] & 0xc0) != 0x80 || + (s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) || /* overlong? */ + (s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) /* > U+10FFFF? */ + return false; + else + s += 4; + } else { + return false; + } + } + + return true; +} + +#endif diff --git a/src/nanopb/pb_common.h b/src/nanopb/pb_common.h new file mode 100644 index 00000000..8d475999 --- /dev/null +++ b/src/nanopb/pb_common.h @@ -0,0 +1,40 @@ +/* pb_common.h: Common support functions for pb_encode.c and pb_decode.c. + * These functions are rarely needed by applications directly. + */ + +#ifndef PB_COMMON_H_INCLUDED +#define PB_COMMON_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initialize the field iterator structure to beginning. + * Returns false if the message type is empty. */ +bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_msgdesc_t *desc, + void *message); + +/* Get a field iterator for extension field. */ +bool pb_field_iter_begin_extension(pb_field_iter_t *iter, + pb_extension_t *extension); + +/* Advance the iterator to the next field. + * Returns false when the iterator wraps back to the first field. */ +bool pb_field_iter_next(pb_field_iter_t *iter); + +/* Advance the iterator until it points at a field with the given tag. + * Returns false if no such field exists. */ +bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag); + +#ifdef PB_VALIDATE_UTF8 +/* Validate UTF-8 text string */ +bool pb_validate_utf8(const char *s); +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/nanopb/pb_custom.c b/src/nanopb/pb_custom.c new file mode 100644 index 00000000..bd22c8c4 --- /dev/null +++ b/src/nanopb/pb_custom.c @@ -0,0 +1,176 @@ +#include "../ui/transactions/protobuf.h" +#include "pb_custom.h" +#include "os.h" +#include "pb_decode.h" +#include "../main.h" + +/******************************************************* + * Ledger's APDU pb_istream_from_apdu_t implementation * + *******************************************************/ + +#define MAX_FETCH_ATTEMPTS 10 + +#define ERR_PB_READ_IS_TOO_BIG 0x6002 +#define ERR_NOT_ENOUGH_BYTES_RECEIVED 0x6003 +#define ERR_BUFFER_TOO_SMALL 0x6005 +#define ERR_WRONG_MESSAGE_SIZE 0x6006 +#define ERR_WRONG_PARAMETER 0x6007 + +#define PRINTF_PB(...) // PRINTF(__VA_ARGS__) + +#if !defined(__GNUC__) || (__GNUC__ < 3) || \ + (__GNUC__ == 3 && __GNUC_MINOR__ < 4) +#define checkreturn +#else +#define checkreturn __attribute__((warn_unused_result)) +#endif + +typedef bool (*pb_decoder_t)(pb_istream_t *stream, const pb_field_t *field, + void *dest) checkreturn; + +void inline fetch_new_apdu(uiProtobuf_t *state) + __attribute__((no_instrument_function)); + +void fetch_new_apdu(uiProtobuf_t *state) { + + unsigned int rx; + unsigned int tx = 0; + unsigned int flags = 0; + unsigned short sw = 0x9000; + G_io_apdu_buffer[tx] = sw >> 8; + G_io_apdu_buffer[tx + 1] = sw; + rx = io_exchange(CHANNEL_APDU | flags , 2); + if (G_io_apdu_buffer[4] != rx - 5) { + // the length of the APDU should match what's in the 5-byte header. + // If not fail. Don't want to buffer overrun or anything. + THROW(SW_CONDITIONS_NOT_SATISFIED); + } + + if (G_io_apdu_buffer[2] != P1_MORE && G_io_apdu_buffer[2] != P1_LAST) { + THROW(SW_INCORRECT_P1_P2); + } else if (state->bytes_stored + G_io_apdu_buffer[4] > sizeof(state->data)) { + PRINTF("ERR_BUFF_TOO_SMALL: %d %d\n", state->bytes_stored, + G_io_apdu_buffer[4]); + THROW(ERR_BUFFER_TOO_SMALL); + } + + if (tmp_ctx.signing_context.step == 8) { + THROW(SW_INCORRECT_P1_P2); + } + PRINTF("New APDU received:\n%.*H\n", rx, G_io_apdu_buffer); + state->total_received += G_io_apdu_buffer[4]; +} + +bool checkreturn apdu_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) { + uiProtobuf_t *state; + uint16_t bytes_not_read_yet; + uint8_t fetch_attempts; + const pb_byte_t *source; + + if (count > MAX_PB_ELEMENT_SIZE) { + THROW(ERR_PB_READ_IS_TOO_BIG); + } + + state = (uiProtobuf_t *)stream->state; + + bytes_not_read_yet = state->bytes_stored - state->read_offset; + + PRINTF_PB("r: %d re: %d s %d\n", count, bytes_not_read_yet, + state->bytes_stored); + + /* not enough data has been received and deciphered, we fetch a new apdu or + stop the s tream if the last apdu was already received*/ + if (count > bytes_not_read_yet) { + // shift data to the beginning of the buffer + memmove(state->data, state->data + state->read_offset, + state->bytes_stored - state->read_offset); + state->bytes_stored = bytes_not_read_yet; + state->read_offset = 0; + + PRINTF_PB("SHIFT LEFT: available: %d\n", bytes_not_read_yet); + + // loop over apdu fetching while there's not enough bytes stored to feed the + // amount requested + fetch_attempts = 0; + while (count > bytes_not_read_yet) { + + if (++fetch_attempts > MAX_FETCH_ATTEMPTS) { + THROW(ERR_NOT_ENOUGH_BYTES_RECEIVED); + } else if (state->total_received == state->total_size) { + // Everything has been received, signal to nanopb that it's time to end + // decoding + stream->bytes_left = 0; + return false; + } + // fetch next bytes + fetch_new_apdu(state); + // creating hash to check view and sign data are the same + int size = G_io_apdu_buffer[4]; + if((state->total_read + size + state->bytes_stored) > state->total_size) { + size = state->total_size - state->total_read - state->bytes_stored; + } + tmp_ctx.signing_context.sign_from = size; + cx_hash(&tmp_ctx.signing_context.ui.hash_ctx.header, CX_NONE, + G_io_apdu_buffer + 5, size, NULL, 0); + memmove(state->data + state->bytes_stored, G_io_apdu_buffer + 5, + G_io_apdu_buffer[4]); + + state->bytes_stored += G_io_apdu_buffer[4]; + bytes_not_read_yet = state->bytes_stored - state->read_offset; + } + } + if (state->total_size <= state->total_read) { + // Everything has been received, signal to nanopb that it's time to end + // decoding + stream->bytes_left = 0; + return false; + } + // extract data to output buffer + source = (const pb_byte_t *)state->data + state->read_offset; + state->read_offset += count; + state->total_read += count; + if (buf != NULL) { + for (uint16_t i = 0; i < count; i++) + buf[i] = source[i]; + } + + return true; +} + +/* + Returns a nanopb input stream handler that feeds data from APDUs + ctx: istream state that stores information about io context + init_buffer: initialized the stream with some data (can be set to NULL) + init_buffer_size: length of init_buffer + total_buffer_size: total length of the message to receive + start_index: index from where starting new message in G_io_apdu_buffer +*/ +pb_istream_t pb_istream_from_apdu(uiProtobuf_t *ctx, uint8_t *init_buffer, + uint8_t init_buffer_size, + uint16_t total_buffer_size, + uint8_t start_index) { + pb_istream_t stream; + stream.callback = &apdu_read; + stream.state = ctx; + stream.bytes_left = SIZE_MAX; +#ifndef PB_NO_ERRMSG + stream.errmsg = NULL; +#endif + memset(ctx, 0, sizeof(uiProtobuf_t)); + ctx->total_received = init_buffer_size; + ctx->total_size = total_buffer_size; + memmove(ctx->data, init_buffer, init_buffer_size); + uint8_t hash_size = init_buffer_size; + //if chunk size bigger than message size + if(init_buffer_size > total_buffer_size) { + hash_size = total_buffer_size; + tmp_ctx.signing_context.sign_from = total_buffer_size + start_index - 5; + } + cx_hash(&tmp_ctx.signing_context.ui.hash_ctx.header, CX_NONE, init_buffer, + hash_size, NULL, 0); + ctx->bytes_stored = init_buffer_size; + ctx->read_offset = 0; + ctx->total_read = 0; + + return stream; +} diff --git a/src/nanopb/pb_custom.h b/src/nanopb/pb_custom.h new file mode 100644 index 00000000..4e6d5f8a --- /dev/null +++ b/src/nanopb/pb_custom.h @@ -0,0 +1,26 @@ +#ifndef _PB_CUSTOM_ +#define _PB_CUSTOM_ + +#include "stdint.h" +#include "os.h" +#include "cx.h" +#include "pb.h" +#include "main.h" + +/* Custom `pb_istream_s.state` structure that handles decoding from apdu + * streaming */ +#define PB_DECODING_FAILED 0 +#define MAX_PB_ELEMENT_SIZE 100 + +pb_istream_t apdu_pb_istream(uiProtobuf_t *ctx, uint8_t *init_buffer, + uint8_t init_buffer_size, + uint16_t total_buffer_size); +pb_istream_t pb_istream_from_apdu(uiProtobuf_t *ctx, uint8_t *init_buffer, + uint8_t init_buffer_size, + uint16_t total_buffer_size, + uint8_t start_index); +bool transaction_callback(pb_istream_t *stream, const pb_field_t *field, + void **arg); +bool asset_callback(pb_istream_t *stream, const pb_field_t *field, void **arg); + +#endif \ No newline at end of file diff --git a/src/nanopb/pb_decode.c b/src/nanopb/pb_decode.c new file mode 100644 index 00000000..8e899048 --- /dev/null +++ b/src/nanopb/pb_decode.c @@ -0,0 +1,1547 @@ +/* pb_decode.c -- decode a protobuf using minimal resources + * + * 2011 Petteri Aimonen + */ + +/* Use the GCC warn_unused_result attribute to check that all return values + * are propagated correctly. On other compilers and gcc before 3.4.0 just + * ignore the annotation. + */ +#if !defined(__GNUC__) || (__GNUC__ < 3) || \ + (__GNUC__ == 3 && __GNUC_MINOR__ < 4) +#define checkreturn +#else +#define checkreturn __attribute__((warn_unused_result)) +#endif + +#include "os.h" +#include "pb.h" +#include "pb_decode.h" +#include "pb_common.h" + +/************************************** + * Declarations internal to this file * + **************************************/ + +static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, + size_t count); +static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, + uint32_t *dest, bool *eof); +static bool checkreturn read_raw_value(pb_istream_t *stream, + pb_wire_type_t wire_type, pb_byte_t *buf, + size_t *size); +static bool checkreturn decode_basic_field(pb_istream_t *stream, + pb_field_iter_t *field); +static bool checkreturn decode_static_field(pb_istream_t *stream, + pb_wire_type_t wire_type, + pb_field_iter_t *field); +static bool checkreturn decode_pointer_field(pb_istream_t *stream, + pb_wire_type_t wire_type, + pb_field_iter_t *field); +static bool checkreturn decode_callback_field(pb_istream_t *stream, + pb_wire_type_t wire_type, + pb_field_iter_t *field); +static bool checkreturn decode_field(pb_istream_t *stream, + pb_wire_type_t wire_type, + pb_field_iter_t *field); +static bool checkreturn default_extension_decoder(pb_istream_t *stream, + pb_extension_t *extension, + uint32_t tag, + pb_wire_type_t wire_type); +static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, + pb_wire_type_t wire_type, + pb_field_iter_t *iter); +static bool checkreturn find_extension_field(pb_field_iter_t *iter); +static bool pb_message_set_to_defaults(pb_field_iter_t *iter); +static bool checkreturn pb_dec_bool(pb_istream_t *stream, + const pb_field_iter_t *field); +static bool checkreturn pb_dec_varint(pb_istream_t *stream, + const pb_field_iter_t *field); +static bool checkreturn pb_dec_fixed(pb_istream_t *stream, + const pb_field_iter_t *field); +static bool checkreturn pb_dec_bytes(pb_istream_t *stream, + const pb_field_iter_t *field); +static bool checkreturn pb_dec_string(pb_istream_t *stream, + const pb_field_iter_t *field); +static bool checkreturn pb_dec_submessage(pb_istream_t *stream, + const pb_field_iter_t *field); +static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, + const pb_field_iter_t *field); +static bool checkreturn pb_skip_varint(pb_istream_t *stream); +static bool checkreturn pb_skip_string(pb_istream_t *stream); + +#ifdef PB_ENABLE_MALLOC +static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, + size_t data_size, size_t array_size); +static void initialize_pointer_field(void *pItem, pb_field_iter_t *field); +static bool checkreturn pb_release_union_field(pb_istream_t *stream, + pb_field_iter_t *field); +static void pb_release_single_field(pb_field_iter_t *field); +#endif + +#ifdef PB_WITHOUT_64BIT +#define pb_int64_t int32_t +#define pb_uint64_t uint32_t +#else +#define pb_int64_t int64_t +#define pb_uint64_t uint64_t +#endif + +typedef struct { + uint32_t bitfield[(PB_MAX_REQUIRED_FIELDS + 31) / 32]; +} pb_fields_seen_t; + +/******************************* + * pb_istream_t implementation * + *******************************/ + +static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, + size_t count) { + size_t i; + const pb_byte_t *source = (const pb_byte_t *)stream->state; + stream->state = (pb_byte_t *)stream->state + count; + + if (buf != NULL) { + for (i = 0; i < count; i++) + buf[i] = source[i]; + } + + return true; +} + +bool checkreturn pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) { + if (count == 0) + return true; + +#ifndef PB_BUFFER_ONLY + if (buf == NULL && stream->callback != buf_read) { + /* Skip input bytes */ + pb_byte_t tmp[16]; + while (count > 16) { + if (!pb_read(stream, tmp, 16)) + return false; + + count -= 16; + } + + return pb_read(stream, tmp, count); + } +#endif + + if (stream->bytes_left < count) + PB_RETURN_ERROR(stream, "end-of-stream"); + +#ifndef PB_BUFFER_ONLY + if (!stream->callback(stream, buf, count)) + PB_RETURN_ERROR(stream, "io error"); +#else + if (!buf_read(stream, buf, count)) + return false; +#endif + + stream->bytes_left -= count; + return true; +} + +/* Read a single byte from input stream. buf may not be NULL. + * This is an optimization for the varint decoding. */ +static bool checkreturn pb_readbyte(pb_istream_t *stream, pb_byte_t *buf) { + if (stream->bytes_left == 0) + PB_RETURN_ERROR(stream, "end-of-stream"); + +#ifndef PB_BUFFER_ONLY + if (!stream->callback(stream, buf, 1)) + PB_RETURN_ERROR(stream, "io error"); +#else + *buf = *(const pb_byte_t *)stream->state; + stream->state = (pb_byte_t *)stream->state + 1; +#endif + stream->bytes_left--; + + return true; +} + +pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize) { + pb_istream_t stream; + /* Cast away the const from buf without a compiler error. We are + * careful to use it only in a const manner in the callbacks. + */ + union { + void *state; + const void *c_state; + } state; +#ifdef PB_BUFFER_ONLY + stream.callback = NULL; +#else + stream.callback = &buf_read; +#endif + state.c_state = buf; + stream.state = state.state; + stream.bytes_left = bufsize; +#ifndef PB_NO_ERRMSG + stream.errmsg = NULL; +#endif + return stream; +} + +/******************** + * Helper functions * + ********************/ + +static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, + uint32_t *dest, bool *eof) { + pb_byte_t byte; + uint32_t result; + + if (!pb_readbyte(stream, &byte)) { + if (stream->bytes_left == 0) { + if (eof) { + *eof = true; + } + } + + return false; + } + + if ((byte & 0x80) == 0) { + /* Quick case, 1 byte value */ + result = byte; + } else { + /* Multibyte case */ + uint_fast8_t bitpos = 7; + result = byte & 0x7F; + + do { + if (!pb_readbyte(stream, &byte)) + return false; + + if (bitpos >= 32) { + /* Note: The varint could have trailing 0x80 bytes, or 0xFF for + * negative. */ + uint8_t sign_extension = (bitpos < 63) ? 0xFF : 0x01; + + if ((byte & 0x7F) != 0x00 && + ((result >> 31) == 0 || byte != sign_extension)) { + PB_RETURN_ERROR(stream, "varint overflow"); + } + } else { + result |= (uint32_t)(byte & 0x7F) << bitpos; + } + bitpos = (uint_fast8_t)(bitpos + 7); + } while (byte & 0x80); + + if (bitpos == 35 && (byte & 0x70) != 0) { + /* The last byte was at bitpos=28, so only bottom 4 bits fit. */ + PB_RETURN_ERROR(stream, "varint overflow"); + } + } + + *dest = result; + return true; +} + +bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) { + return pb_decode_varint32_eof(stream, dest, NULL); +} + +#ifndef PB_WITHOUT_64BIT +bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest) { + pb_byte_t byte; + uint_fast8_t bitpos = 0; + uint64_t result = 0; + + do { + if (bitpos >= 64) + PB_RETURN_ERROR(stream, "varint overflow"); + + if (!pb_readbyte(stream, &byte)) + return false; + + result |= (uint64_t)(byte & 0x7F) << bitpos; + bitpos = (uint_fast8_t)(bitpos + 7); + } while (byte & 0x80); + + *dest = result; + return true; +} +#endif + +bool checkreturn pb_skip_varint(pb_istream_t *stream) { + pb_byte_t byte; + do { + if (!pb_read(stream, &byte, 1)) + return false; + } while (byte & 0x80); + return true; +} + +bool checkreturn pb_skip_string(pb_istream_t *stream) { + uint32_t length; + if (!pb_decode_varint32(stream, &length)) + return false; + + if ((size_t)length != length) { + PB_RETURN_ERROR(stream, "size too large"); + } + + return pb_read(stream, NULL, (size_t)length); +} + +bool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, + uint32_t *tag, bool *eof) { + uint32_t temp; + *eof = false; + *wire_type = (pb_wire_type_t)0; + *tag = 0; + + if (!pb_decode_varint32_eof(stream, &temp, eof)) { + return false; + } + + *tag = temp >> 3; + *wire_type = (pb_wire_type_t)(temp & 7); + return true; +} + +bool checkreturn pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type) { + switch (wire_type) { + case PB_WT_VARINT: + return pb_skip_varint(stream); + case PB_WT_64BIT: + return pb_read(stream, NULL, 8); + case PB_WT_STRING: + return pb_skip_string(stream); + case PB_WT_32BIT: + return pb_read(stream, NULL, 4); + default: + PB_RETURN_ERROR(stream, "invalid wire_type"); + } +} + +/* Read a raw value to buffer, for the purpose of passing it to callback as + * a substream. Size is maximum size on call, and actual size on return. + */ +static bool checkreturn read_raw_value(pb_istream_t *stream, + pb_wire_type_t wire_type, pb_byte_t *buf, + size_t *size) { + size_t max_size = *size; + switch (wire_type) { + case PB_WT_VARINT: + *size = 0; + do { + (*size)++; + if (*size > max_size) + PB_RETURN_ERROR(stream, "varint overflow"); + + if (!pb_read(stream, buf, 1)) + return false; + } while (*buf++ & 0x80); + return true; + + case PB_WT_64BIT: + *size = 8; + return pb_read(stream, buf, 8); + + case PB_WT_32BIT: + *size = 4; + return pb_read(stream, buf, 4); + + case PB_WT_STRING: + /* Calling read_raw_value with a PB_WT_STRING is an error. + * Explicitly handle this case and fallthrough to default to avoid + * compiler warnings. + */ + + default: + PB_RETURN_ERROR(stream, "invalid wire_type"); + } +} + +/* Decode string length from stream and return a substream with limited length. + * Remember to close the substream using pb_close_string_substream(). + */ +bool checkreturn pb_make_string_substream(pb_istream_t *stream, + pb_istream_t *substream) { + uint32_t size; + if (!pb_decode_varint32(stream, &size)) + return false; + + *substream = *stream; + if (substream->bytes_left < size) + PB_RETURN_ERROR(stream, "parent stream too short"); + + substream->bytes_left = (size_t)size; + stream->bytes_left -= (size_t)size; + return true; +} + +bool checkreturn pb_close_string_substream(pb_istream_t *stream, + pb_istream_t *substream) { + if (substream->bytes_left) { + if (!pb_read(substream, NULL, substream->bytes_left)) + return false; + } + + stream->state = substream->state; + +#ifndef PB_NO_ERRMSG + stream->errmsg = substream->errmsg; +#endif + return true; +} + +/************************* + * Decode a single field * + *************************/ + +static bool checkreturn decode_basic_field(pb_istream_t *stream, + pb_field_iter_t *field) { + switch (PB_LTYPE(field->type)) { + case PB_LTYPE_BOOL: + return pb_dec_bool(stream, field); + + case PB_LTYPE_VARINT: + case PB_LTYPE_UVARINT: + case PB_LTYPE_SVARINT: + return pb_dec_varint(stream, field); + + case PB_LTYPE_FIXED32: + case PB_LTYPE_FIXED64: + return pb_dec_fixed(stream, field); + + case PB_LTYPE_BYTES: + return pb_dec_bytes(stream, field); + + case PB_LTYPE_STRING: + return pb_dec_string(stream, field); + + case PB_LTYPE_SUBMESSAGE: + case PB_LTYPE_SUBMSG_W_CB: + return pb_dec_submessage(stream, field); + + case PB_LTYPE_FIXED_LENGTH_BYTES: + return pb_dec_fixed_length_bytes(stream, field); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +static bool checkreturn decode_static_field(pb_istream_t *stream, + pb_wire_type_t wire_type, + pb_field_iter_t *field) { + switch (PB_HTYPE(field->type)) { + case PB_HTYPE_REQUIRED: + return decode_basic_field(stream, field); + + case PB_HTYPE_OPTIONAL: + if (field->pSize != NULL) + *(bool *)field->pSize = true; + return decode_basic_field(stream, field); + + case PB_HTYPE_REPEATED: + if (wire_type == PB_WT_STRING && + PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) { + /* Packed array */ + bool status = true; + pb_istream_t substream; + pb_size_t *size = (pb_size_t *)field->pSize; + field->pData = (char *)field->pField + field->data_size * (*size); + + if (!pb_make_string_substream(stream, &substream)) + return false; + + while (substream.bytes_left > 0 && *size < field->array_size) { + if (!decode_basic_field(&substream, field)) { + status = false; + break; + } + (*size)++; + field->pData = (char *)field->pData + field->data_size; + } + + if (substream.bytes_left != 0) + PB_RETURN_ERROR(stream, "array overflow"); + if (!pb_close_string_substream(stream, &substream)) + return false; + + return status; + } else { + /* Repeated field */ + pb_size_t *size = (pb_size_t *)field->pSize; + field->pData = (char *)field->pField + field->data_size * (*size); + + if ((*size)++ >= field->array_size) + PB_RETURN_ERROR(stream, "array overflow"); + + return decode_basic_field(stream, field); + } + + case PB_HTYPE_ONEOF: + *(pb_size_t *)field->pSize = field->tag; + if (PB_LTYPE_IS_SUBMSG(field->type)) { + /* We memset to zero so that any callbacks are set to NULL. + * This is because the callbacks might otherwise have values + * from some other union field. + * If callbacks are needed inside oneof field, use .proto + * option submsg_callback to have a separate callback function + * that can set the fields before submessage is decoded. + * pb_dec_submessage() will set any default values. */ + memset(field->pData, 0, (size_t)field->data_size); + } + return decode_basic_field(stream, field); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +#ifdef PB_ENABLE_MALLOC +/* Allocate storage for the field and store the pointer at iter->pData. + * array_size is the number of entries to reserve in an array. + * Zero size is not allowed, use pb_free() for releasing. + */ +static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, + size_t data_size, size_t array_size) { + void *ptr = *(void **)pData; + + if (data_size == 0 || array_size == 0) + PB_RETURN_ERROR(stream, "invalid size"); + + /* Check for multiplication overflows. + * This code avoids the costly division if the sizes are small enough. + * Multiplication is safe as long as only half of bits are set + * in either multiplicand. + */ + { + const size_t check_limit = (size_t)1 << (sizeof(size_t) * 4); + if (data_size >= check_limit || array_size >= check_limit) { + const size_t size_max = (size_t)-1; + if (size_max / array_size < data_size) { + PB_RETURN_ERROR(stream, "size too large"); + } + } + } + + /* Allocate new or expand previous allocation */ + /* Note: on failure the old pointer will remain in the structure, + * the message must be freed by caller also on error return. */ + ptr = pb_realloc(ptr, array_size * data_size); + if (ptr == NULL) + PB_RETURN_ERROR(stream, "realloc failed"); + + *(void **)pData = ptr; + return true; +} + +/* Clear a newly allocated item in case it contains a pointer, or is a + * submessage. */ +static void initialize_pointer_field(void *pItem, pb_field_iter_t *field) { + if (PB_LTYPE(field->type) == PB_LTYPE_STRING || + PB_LTYPE(field->type) == PB_LTYPE_BYTES) { + *(void **)pItem = NULL; + } else if (PB_LTYPE_IS_SUBMSG(field->type)) { + /* We memset to zero so that any callbacks are set to NULL. + * Then set any default values. */ + pb_field_iter_t submsg_iter; + memset(pItem, 0, field->data_size); + + if (pb_field_iter_begin(&submsg_iter, field->submsg_desc, pItem)) { + (void)pb_message_set_to_defaults(&submsg_iter); + } + } +} +#endif + +static bool checkreturn decode_pointer_field(pb_istream_t *stream, + pb_wire_type_t wire_type, + pb_field_iter_t *field) { +#ifndef PB_ENABLE_MALLOC + PB_UNUSED(wire_type); + PB_UNUSED(field); + PB_RETURN_ERROR(stream, "no malloc support"); +#else + switch (PB_HTYPE(field->type)) { + case PB_HTYPE_REQUIRED: + case PB_HTYPE_OPTIONAL: + case PB_HTYPE_ONEOF: + if (PB_LTYPE_IS_SUBMSG(field->type) && *(void **)field->pField != NULL) { + /* Duplicate field, have to release the old allocation first. */ + /* FIXME: Does this work correctly for oneofs? */ + pb_release_single_field(field); + } + + if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF) { + *(pb_size_t *)field->pSize = field->tag; + } + + if (PB_LTYPE(field->type) == PB_LTYPE_STRING || + PB_LTYPE(field->type) == PB_LTYPE_BYTES) { + /* pb_dec_string and pb_dec_bytes handle allocation themselves */ + field->pData = field->pField; + return decode_basic_field(stream, field); + } else { + if (!allocate_field(stream, field->pField, field->data_size, 1)) + return false; + + field->pData = *(void **)field->pField; + initialize_pointer_field(field->pData, field); + return decode_basic_field(stream, field); + } + + case PB_HTYPE_REPEATED: + if (wire_type == PB_WT_STRING && + PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) { + /* Packed array, multiple items come in at once. */ + bool status = true; + pb_size_t *size = (pb_size_t *)field->pSize; + size_t allocated_size = *size; + pb_istream_t substream; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + while (substream.bytes_left) { + if ((size_t)*size + 1 > allocated_size) { + /* Allocate more storage. This tries to guess the + * number of remaining entries. Round the division + * upwards. */ + allocated_size += (substream.bytes_left - 1) / field->data_size + 1; + + if (!allocate_field(&substream, field->pField, field->data_size, + allocated_size)) { + status = false; + break; + } + } + + /* Decode the array entry */ + field->pData = *(char **)field->pField + field->data_size * (*size); + initialize_pointer_field(field->pData, field); + if (!decode_basic_field(&substream, field)) { + status = false; + break; + } + + if (*size == PB_SIZE_MAX) { +#ifndef PB_NO_ERRMSG + stream->errmsg = "too many array entries"; +#endif + status = false; + break; + } + + (*size)++; + } + if (!pb_close_string_substream(stream, &substream)) + return false; + + return status; + } else { + /* Normal repeated field, i.e. only one item at a time. */ + pb_size_t *size = (pb_size_t *)field->pSize; + + if (*size == PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "too many array entries"); + + (*size)++; + if (!allocate_field(stream, field->pField, field->data_size, *size)) + return false; + + field->pData = *(char **)field->pField + field->data_size * (*size - 1); + initialize_pointer_field(field->pData, field); + return decode_basic_field(stream, field); + } + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +#endif +} + +static bool checkreturn decode_callback_field(pb_istream_t *stream, + pb_wire_type_t wire_type, + pb_field_iter_t *field) { + if (!field->descriptor->field_callback) + return pb_skip_field(stream, wire_type); + + if (wire_type == PB_WT_STRING) { + pb_istream_t substream; + size_t prev_bytes_left; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + do { + prev_bytes_left = substream.bytes_left; + if (!((bool (*)(pb_istream_t * istream, pb_ostream_t * ostream, + const pb_field_iter_t *field))( + PIC(field->descriptor->field_callback)))(&substream, NULL, field)) + PB_RETURN_ERROR(stream, "callback failed"); + } while (substream.bytes_left > 0 && + substream.bytes_left < prev_bytes_left); + + if (!pb_close_string_substream(stream, &substream)) + return false; + + return true; + } else { + /* Copy the single scalar value to stack. + * This is required so that we can limit the stream length, + * which in turn allows to use same callback for packed and + * not-packed fields. */ + pb_istream_t substream; + pb_byte_t buffer[10]; + size_t size = sizeof(buffer); + + if (!read_raw_value(stream, wire_type, buffer, &size)) + return false; + substream = pb_istream_from_buffer(buffer, size); + + return field->descriptor->field_callback(&substream, NULL, field); + } +} + +static bool checkreturn decode_field(pb_istream_t *stream, + pb_wire_type_t wire_type, + pb_field_iter_t *field) { +#ifdef PB_ENABLE_MALLOC + /* When decoding an oneof field, check if there is old data that must be + * released first. */ + if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF) { + if (!pb_release_union_field(stream, field)) + return false; + } +#endif + + switch (PB_ATYPE(field->type)) { + case PB_ATYPE_STATIC: + return decode_static_field(stream, wire_type, field); + + case PB_ATYPE_POINTER: + return decode_pointer_field(stream, wire_type, field); + + case PB_ATYPE_CALLBACK: + return decode_callback_field(stream, wire_type, field); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +/* Default handler for extension fields. Expects to have a pb_msgdesc_t + * pointer in the extension->type->arg field, pointing to a message with + * only one field in it. */ +static bool checkreturn default_extension_decoder(pb_istream_t *stream, + pb_extension_t *extension, + uint32_t tag, + pb_wire_type_t wire_type) { + pb_field_iter_t iter; + + if (!pb_field_iter_begin_extension(&iter, extension)) + PB_RETURN_ERROR(stream, "invalid extension"); + + if (iter.tag != tag) + return true; + + extension->found = true; + return decode_field(stream, wire_type, &iter); +} + +/* Try to decode an unknown field as an extension field. Tries each extension + * decoder in turn, until one of them handles the field or loop ends. */ +static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, + pb_wire_type_t wire_type, + pb_field_iter_t *iter) { + pb_extension_t *extension = *(pb_extension_t *const *)iter->pData; + size_t pos = stream->bytes_left; + + while (extension != NULL && pos == stream->bytes_left) { + bool status; + if (extension->type->decode) + status = extension->type->decode(stream, extension, tag, wire_type); + else + status = default_extension_decoder(stream, extension, tag, wire_type); + + if (!status) + return false; + + extension = extension->next; + } + + return true; +} + +/* Step through the iterator until an extension field is found or until all + * entries have been checked. There can be only one extension field per + * message. Returns false if no extension field is found. */ +static bool checkreturn find_extension_field(pb_field_iter_t *iter) { + pb_size_t start = iter->index; + + do { + if (PB_LTYPE(iter->type) == PB_LTYPE_EXTENSION) + return true; + (void)pb_field_iter_next(iter); + } while (iter->index != start); + + return false; +} + +/* Initialize message fields to default values, recursively */ +static bool pb_field_set_to_default(pb_field_iter_t *field) { + pb_type_t type; + type = field->type; + + if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) { + pb_extension_t *ext = *(pb_extension_t *const *)field->pData; + while (ext != NULL) { + pb_field_iter_t ext_iter; + if (pb_field_iter_begin_extension(&ext_iter, ext)) { + ext->found = false; + if (!pb_message_set_to_defaults(&ext_iter)) + return false; + } + ext = ext->next; + } + } else if (PB_ATYPE(type) == PB_ATYPE_STATIC) { + bool init_data = true; + if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && field->pSize != NULL) { + /* Set has_field to false. Still initialize the optional field + * itself also. */ + *(bool *)field->pSize = false; + } else if (PB_HTYPE(type) == PB_HTYPE_REPEATED || + PB_HTYPE(type) == PB_HTYPE_ONEOF) { + /* REPEATED: Set array count to 0, no need to initialize contents. + ONEOF: Set which_field to 0. */ + *(pb_size_t *)field->pSize = 0; + init_data = false; + } + + if (init_data) { + if (PB_LTYPE_IS_SUBMSG(field->type)) { + /* Initialize submessage to defaults */ + pb_field_iter_t submsg_iter; + if (pb_field_iter_begin(&submsg_iter, field->submsg_desc, + field->pData)) { + if (!pb_message_set_to_defaults(&submsg_iter)) + return false; + } + } else { + /* Initialize to zeros */ + memset(field->pData, 0, (size_t)field->data_size); + } + } + } else if (PB_ATYPE(type) == PB_ATYPE_POINTER) { + /* Initialize the pointer to NULL. */ + *(void **)field->pField = NULL; + + /* Initialize array count to 0. */ + if (PB_HTYPE(type) == PB_HTYPE_REPEATED || + PB_HTYPE(type) == PB_HTYPE_ONEOF) { + *(pb_size_t *)field->pSize = 0; + } + } else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK) { + /* Don't overwrite callback */ + } + + return true; +} + +static bool pb_message_set_to_defaults(pb_field_iter_t *iter) { + pb_istream_t defstream = PB_ISTREAM_EMPTY; + uint32_t tag = 0; + pb_wire_type_t wire_type = PB_WT_VARINT; + bool eof; + + if (iter->descriptor->default_value) { + defstream = + pb_istream_from_buffer(iter->descriptor->default_value, (size_t)-1); + if (!pb_decode_tag(&defstream, &wire_type, &tag, &eof)) + return false; + } + + do { + if (!pb_field_set_to_default(iter)) + return false; + + if (tag != 0 && iter->tag == tag) { + /* We have a default value for this field in the defstream */ + if (!decode_field(&defstream, wire_type, iter)) + return false; + if (!pb_decode_tag(&defstream, &wire_type, &tag, &eof)) + return false; + + if (iter->pSize) + *(bool *)iter->pSize = false; + } + } while (pb_field_iter_next(iter)); + + return true; +} + +/********************* + * Decode all fields * + *********************/ + +static bool checkreturn pb_decode_inner(pb_istream_t *stream, + const pb_msgdesc_t *fields, + void *dest_struct, unsigned int flags) { + uint32_t extension_range_start = 0; + + /* 'fixed_count_field' and 'fixed_count_size' track position of a repeated + * fixed count field. This can only handle _one_ repeated fixed count field + * that is unpacked and unordered among other (non repeated fixed count) + * fields. + */ + pb_size_t fixed_count_field = PB_SIZE_MAX; + pb_size_t fixed_count_size = 0; + pb_size_t fixed_count_total_size = 0; + + pb_fields_seen_t fields_seen = {{0, 0}}; + const uint32_t allbits = ~(uint32_t)0; + pb_field_iter_t iter; + + /* Return value ignored, as empty message types will be correctly handled by + * pb_field_iter_find() anyway. */ + (void)pb_field_iter_begin(&iter, fields, dest_struct); + + while (stream->bytes_left) { + uint32_t tag; + pb_wire_type_t wire_type; + bool eof; + + if (!pb_decode_tag(stream, &wire_type, &tag, &eof)) { + if (eof) + break; + else + return false; + } + + if (tag == 0) { + if (flags & PB_DECODE_NULLTERMINATED) { + break; + } else { + PB_RETURN_ERROR(stream, "zero tag"); + } + } + + if (!pb_field_iter_find(&iter, tag) || + PB_LTYPE(iter.type) == PB_LTYPE_EXTENSION) { + /* No match found, check if it matches an extension. */ + if (tag >= extension_range_start) { + if (!find_extension_field(&iter)) + extension_range_start = (uint32_t)-1; + else + extension_range_start = iter.tag; + + if (tag >= extension_range_start) { + size_t pos = stream->bytes_left; + + if (!decode_extension(stream, tag, wire_type, &iter)) + return false; + + if (pos != stream->bytes_left) { + /* The field was handled */ + continue; + } + } + } + + /* No match found, skip data */ + if (!pb_skip_field(stream, wire_type)) + return false; + continue; + } + + /* If a repeated fixed count field was found, get size from + * 'fixed_count_field' as there is no counter contained in the struct. + */ + if (PB_HTYPE(iter.type) == PB_HTYPE_REPEATED && + iter.pSize == &iter.array_size) { + if (fixed_count_field != iter.index) { + /* If the new fixed count field does not match the previous one, + * check that the previous one is NULL or that it finished + * receiving all the expected data. + */ + if (fixed_count_field != PB_SIZE_MAX && + fixed_count_size != fixed_count_total_size) { + PB_RETURN_ERROR(stream, "wrong size for fixed count field"); + } + + fixed_count_field = iter.index; + fixed_count_size = 0; + fixed_count_total_size = iter.array_size; + } + + iter.pSize = &fixed_count_size; + } + + if (PB_HTYPE(iter.type) == PB_HTYPE_REQUIRED && + iter.required_field_index < PB_MAX_REQUIRED_FIELDS) { + uint32_t tmp = ((uint32_t)1 << (iter.required_field_index & 31)); + fields_seen.bitfield[iter.required_field_index >> 5] |= tmp; + } + + if (!decode_field(stream, wire_type, &iter)) + return false; + } + + /* Check that all elements of the last decoded fixed count field were present. + */ + if (fixed_count_field != PB_SIZE_MAX && + fixed_count_size != fixed_count_total_size) { + PB_RETURN_ERROR(stream, "wrong size for fixed count field"); + } + + /* Check that all required fields were present. */ + { + /* First figure out the number of required fields by + * seeking to the end of the field array. Usually we + * are already close to end after decoding. + */ + pb_size_t req_field_count; + pb_type_t last_type; + pb_size_t i; + do { + req_field_count = iter.required_field_index; + last_type = iter.type; + } while (pb_field_iter_next(&iter)); + + /* Fixup if last field was also required. */ + if (PB_HTYPE(last_type) == PB_HTYPE_REQUIRED && iter.tag != 0) + req_field_count++; + + if (req_field_count > PB_MAX_REQUIRED_FIELDS) + req_field_count = PB_MAX_REQUIRED_FIELDS; + + if (req_field_count > 0) { + /* Check the whole words */ + for (i = 0; i < (req_field_count >> 5); i++) { + if (fields_seen.bitfield[i] != allbits) + PB_RETURN_ERROR(stream, "missing required field"); + } + + /* Check the remaining bits (if any) */ + if ((req_field_count & 31) != 0) { + if (fields_seen.bitfield[req_field_count >> 5] != + (allbits >> (uint8_t)(32 - (req_field_count & 31)))) { + PB_RETURN_ERROR(stream, "missing required field"); + } + } + } + } + + return true; +} + +bool checkreturn pb_decode_ex(pb_istream_t *stream, const pb_msgdesc_t *fields, + void *dest_struct, unsigned int flags) { + bool status; + + if ((flags & PB_DECODE_NOINIT) == 0) { + pb_field_iter_t iter; + + if (pb_field_iter_begin(&iter, fields, dest_struct)) { + if (!pb_message_set_to_defaults(&iter)) + PB_RETURN_ERROR(stream, "failed to set defaults"); + } + } + + if ((flags & PB_DECODE_DELIMITED) == 0) { + status = pb_decode_inner(stream, fields, dest_struct, flags); + } else { + pb_istream_t substream; + if (!pb_make_string_substream(stream, &substream)) + return false; + + status = pb_decode_inner(&substream, fields, dest_struct, flags); + + if (!pb_close_string_substream(stream, &substream)) + return false; + } + +#ifdef PB_ENABLE_MALLOC + if (!status) + pb_release(fields, dest_struct); +#endif + + return status; +} + +bool checkreturn pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, + void *dest_struct) { + return pb_decode_ex(stream, fields, dest_struct, 0); +} + +#ifdef PB_ENABLE_MALLOC +/* Given an oneof field, if there has already been a field inside this oneof, + * release it before overwriting with a different one. */ +static bool pb_release_union_field(pb_istream_t *stream, + pb_field_iter_t *field) { + pb_field_iter_t old_field = *field; + pb_size_t old_tag = *(pb_size_t *)field->pSize; /* Previous which_ value */ + pb_size_t new_tag = field->tag; /* New which_ value */ + + if (old_tag == 0) + return true; /* Ok, no old data in union */ + + if (old_tag == new_tag) + return true; /* Ok, old data is of same type => merge */ + + /* Release old data. The find can fail if the message struct contains + * invalid data. */ + if (!pb_field_iter_find(&old_field, old_tag)) + PB_RETURN_ERROR(stream, "invalid union tag"); + + pb_release_single_field(&old_field); + + return true; +} + +static void pb_release_single_field(pb_field_iter_t *field) { + pb_type_t type; + type = field->type; + + if (PB_HTYPE(type) == PB_HTYPE_ONEOF) { + if (*(pb_size_t *)field->pSize != field->tag) + return; /* This is not the current field in the union */ + } + + /* Release anything contained inside an extension or submsg. + * This has to be done even if the submsg itself is statically + * allocated. */ + if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) { + /* Release fields from all extensions in the linked list */ + pb_extension_t *ext = *(pb_extension_t **)field->pData; + while (ext != NULL) { + pb_field_iter_t ext_iter; + if (pb_field_iter_begin_extension(&ext_iter, ext)) { + pb_release_single_field(&ext_iter); + } + ext = ext->next; + } + } else if (PB_LTYPE_IS_SUBMSG(type) && PB_ATYPE(type) != PB_ATYPE_CALLBACK) { + /* Release fields in submessage or submsg array */ + pb_size_t count = 1; + + if (PB_ATYPE(type) == PB_ATYPE_POINTER) { + field->pData = *(void **)field->pField; + } else { + field->pData = field->pField; + } + + if (PB_HTYPE(type) == PB_HTYPE_REPEATED) { + count = *(pb_size_t *)field->pSize; + + if (PB_ATYPE(type) == PB_ATYPE_STATIC && count > field->array_size) { + /* Protect against corrupted _count fields */ + count = field->array_size; + } + } + + if (field->pData) { + while (count--) { + pb_release(field->submsg_desc, field->pData); + field->pData = (char *)field->pData + field->data_size; + } + } + } + + if (PB_ATYPE(type) == PB_ATYPE_POINTER) { + if (PB_HTYPE(type) == PB_HTYPE_REPEATED && + (PB_LTYPE(type) == PB_LTYPE_STRING || + PB_LTYPE(type) == PB_LTYPE_BYTES)) { + /* Release entries in repeated string or bytes array */ + void **pItem = *(void ***)field->pField; + pb_size_t count = *(pb_size_t *)field->pSize; + while (count--) { + pb_free(*pItem); + *pItem++ = NULL; + } + } + + if (PB_HTYPE(type) == PB_HTYPE_REPEATED) { + /* We are going to release the array, so set the size to 0 */ + *(pb_size_t *)field->pSize = 0; + } + + /* Release main pointer */ + pb_free(*(void **)field->pField); + *(void **)field->pField = NULL; + } +} + +void pb_release(const pb_msgdesc_t *fields, void *dest_struct) { + pb_field_iter_t iter; + + if (!dest_struct) + return; /* Ignore NULL pointers, similar to free() */ + + if (!pb_field_iter_begin(&iter, fields, dest_struct)) + return; /* Empty message type */ + + do { + pb_release_single_field(&iter); + } while (pb_field_iter_next(&iter)); +} +#endif + +/* Field decoders */ + +bool pb_decode_bool(pb_istream_t *stream, bool *dest) { + uint32_t value; + if (!pb_decode_varint32(stream, &value)) + return false; + + *(bool *)dest = (value != 0); + return true; +} + +bool pb_decode_svarint(pb_istream_t *stream, pb_int64_t *dest) { + pb_uint64_t value; + if (!pb_decode_varint(stream, &value)) + return false; + + if (value & 1) + *dest = (pb_int64_t)(~(value >> 1)); + else + *dest = (pb_int64_t)(value >> 1); + + return true; +} + +bool pb_decode_fixed32(pb_istream_t *stream, void *dest) { + union { + uint32_t fixed32; + pb_byte_t bytes[4]; + } u; + + if (!pb_read(stream, u.bytes, 4)) + return false; + +#if defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN && CHAR_BIT == 8 + /* fast path - if we know that we're on little endian, assign directly */ + *(uint32_t *)dest = u.fixed32; +#else + *(uint32_t *)dest = + ((uint32_t)u.bytes[0] << 0) | ((uint32_t)u.bytes[1] << 8) | + ((uint32_t)u.bytes[2] << 16) | ((uint32_t)u.bytes[3] << 24); +#endif + return true; +} + +#ifndef PB_WITHOUT_64BIT +bool pb_decode_fixed64(pb_istream_t *stream, void *dest) { + union { + uint64_t fixed64; + pb_byte_t bytes[8]; + } u; + + if (!pb_read(stream, u.bytes, 8)) + return false; + +#if defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN && CHAR_BIT == 8 + /* fast path - if we know that we're on little endian, assign directly */ + *(uint64_t *)dest = u.fixed64; +#else + *(uint64_t *)dest = + ((uint64_t)u.bytes[0] << 0) | ((uint64_t)u.bytes[1] << 8) | + ((uint64_t)u.bytes[2] << 16) | ((uint64_t)u.bytes[3] << 24) | + ((uint64_t)u.bytes[4] << 32) | ((uint64_t)u.bytes[5] << 40) | + ((uint64_t)u.bytes[6] << 48) | ((uint64_t)u.bytes[7] << 56); +#endif + return true; +} +#endif + +static bool checkreturn pb_dec_bool(pb_istream_t *stream, + const pb_field_iter_t *field) { + return pb_decode_bool(stream, (bool *)field->pData); +} + +static bool checkreturn pb_dec_varint(pb_istream_t *stream, + const pb_field_iter_t *field) { + if (PB_LTYPE(field->type) == PB_LTYPE_UVARINT) { + pb_uint64_t value, clamped; + if (!pb_decode_varint(stream, &value)) + return false; + + /* Cast to the proper field size, while checking for overflows */ + if (field->data_size == sizeof(pb_uint64_t)) + clamped = *(pb_uint64_t *)field->pData = value; + else if (field->data_size == sizeof(uint32_t)) + clamped = *(uint32_t *)field->pData = (uint32_t)value; + else if (field->data_size == sizeof(uint_least16_t)) + clamped = *(uint_least16_t *)field->pData = (uint_least16_t)value; + else if (field->data_size == sizeof(uint_least8_t)) + clamped = *(uint_least8_t *)field->pData = (uint_least8_t)value; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + if (clamped != value) + PB_RETURN_ERROR(stream, "integer too large"); + + return true; + } else { + pb_uint64_t value; + pb_int64_t svalue; + pb_int64_t clamped; + + if (PB_LTYPE(field->type) == PB_LTYPE_SVARINT) { + if (!pb_decode_svarint(stream, &svalue)) + return false; + } else { + if (!pb_decode_varint(stream, &value)) + return false; + + /* See issue 97: Google's C++ protobuf allows negative varint values to + * be cast as int32_t, instead of the int64_t that should be used when + * encoding. Previous nanopb versions had a bug in encoding. In order to + * not break decoding of such messages, we cast <=32 bit fields to + * int32_t first to get the sign correct. + */ + if (field->data_size == sizeof(pb_int64_t)) + svalue = (pb_int64_t)value; + else + svalue = (int32_t)value; + } + + /* Cast to the proper field size, while checking for overflows */ + if (field->data_size == sizeof(pb_int64_t)) + clamped = *(pb_int64_t *)field->pData = svalue; + else if (field->data_size == sizeof(int32_t)) + clamped = *(int32_t *)field->pData = (int32_t)svalue; + else if (field->data_size == sizeof(int_least16_t)) + clamped = *(int_least16_t *)field->pData = (int_least16_t)svalue; + else if (field->data_size == sizeof(int_least8_t)) + clamped = *(int_least8_t *)field->pData = (int_least8_t)svalue; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + if (clamped != svalue) + PB_RETURN_ERROR(stream, "integer too large"); + + return true; + } +} + +static bool checkreturn pb_dec_fixed(pb_istream_t *stream, + const pb_field_iter_t *field) { +#ifdef PB_CONVERT_DOUBLE_FLOAT + if (field->data_size == sizeof(float) && + PB_LTYPE(field->type) == PB_LTYPE_FIXED64) { + return pb_decode_double_as_float(stream, (float *)field->pData); + } +#endif + + if (field->data_size == sizeof(uint32_t)) { + return pb_decode_fixed32(stream, field->pData); + } +#ifndef PB_WITHOUT_64BIT + else if (field->data_size == sizeof(uint64_t)) { + return pb_decode_fixed64(stream, field->pData); + } +#endif + else { + PB_RETURN_ERROR(stream, "invalid data_size"); + } +} + +static bool checkreturn pb_dec_bytes(pb_istream_t *stream, + const pb_field_iter_t *field) { + uint32_t size; + size_t alloc_size; + pb_bytes_array_t *dest; + + if (!pb_decode_varint32(stream, &size)) + return false; + + if (size > PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "bytes overflow"); + + alloc_size = PB_BYTES_ARRAY_T_ALLOCSIZE(size); + if (size > alloc_size) + PB_RETURN_ERROR(stream, "size too large"); + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) { +#ifndef PB_ENABLE_MALLOC + PB_RETURN_ERROR(stream, "no malloc support"); +#else + if (!allocate_field(stream, field->pData, alloc_size, 1)) + return false; + dest = *(pb_bytes_array_t **)field->pData; +#endif + } else { + if (alloc_size > field->data_size) + PB_RETURN_ERROR(stream, "bytes overflow"); + dest = (pb_bytes_array_t *)field->pData; + } + + dest->size = (pb_size_t)size; + return pb_read(stream, dest->bytes, (size_t)size); +} + +static bool checkreturn pb_dec_string(pb_istream_t *stream, + const pb_field_iter_t *field) { + uint32_t size; + size_t alloc_size; + pb_byte_t *dest = (pb_byte_t *)field->pData; + + if (!pb_decode_varint32(stream, &size)) + return false; + + /* Space for null terminator */ + alloc_size = (size_t)(size + 1); + if (alloc_size < size) + PB_RETURN_ERROR(stream, "size too large"); + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) { +#ifndef PB_ENABLE_MALLOC + PB_RETURN_ERROR(stream, "no malloc support"); +#else + if (!allocate_field(stream, field->pData, alloc_size, 1)) + return false; + dest = *(pb_byte_t **)field->pData; +#endif + } else { + if (alloc_size > field->data_size) + PB_RETURN_ERROR(stream, "string overflow"); + } + + dest[size] = 0; + + if (!pb_read(stream, dest, (size_t)size)) + return false; + +#ifdef PB_VALIDATE_UTF8 + if (!pb_validate_utf8((const char *)dest)) + PB_RETURN_ERROR(stream, "invalid utf8"); +#endif + + return true; +} + +static bool checkreturn pb_dec_submessage(pb_istream_t *stream, + const pb_field_iter_t *field) { + bool status = true; + pb_istream_t substream; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + if (field->submsg_desc == NULL) + PB_RETURN_ERROR(stream, "invalid field descriptor"); + + /* New array entries need to be initialized, while required and optional + * submessages have already been initialized in the top-level pb_decode. */ + if (PB_HTYPE(field->type) == PB_HTYPE_REPEATED || + PB_HTYPE(field->type) == PB_HTYPE_ONEOF) { + pb_field_iter_t submsg_iter; + if (pb_field_iter_begin(&submsg_iter, field->submsg_desc, field->pData)) { + if (!pb_message_set_to_defaults(&submsg_iter)) + PB_RETURN_ERROR(stream, "failed to set defaults"); + } + } + + /* Submessages can have a separate message-level callback that is called + * before decoding the message. Typically it is used to set callback fields + * inside oneofs. */ + if (PB_LTYPE(field->type) == PB_LTYPE_SUBMSG_W_CB && field->pSize != NULL) { + /* Message callback is stored right before pSize. */ + pb_callback_t *callback = (pb_callback_t *)field->pSize - 1; + if (callback->funcs.decode) { + status = callback->funcs.decode(&substream, field, &callback->arg); + } + } + + /* Now decode the submessage contents */ + if (status) { + status = pb_decode_noinit(&substream, field->submsg_desc, field->pData); + } + + if (!pb_close_string_substream(stream, &substream)) + return false; + + return status; +} + +static bool checkreturn +pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_iter_t *field) { + uint32_t size; + + if (!pb_decode_varint32(stream, &size)) + return false; + + if (size > PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "bytes overflow"); + + if (size == 0) { + /* As a special case, treat empty bytes string as all zeros for + * fixed_length_bytes. */ + memset(field->pData, 0, (size_t)field->data_size); + return true; + } + + if (size != field->data_size) + PB_RETURN_ERROR(stream, "incorrect fixed length bytes size"); + + return pb_read(stream, (pb_byte_t *)field->pData, (size_t)field->data_size); +} + +#ifdef PB_CONVERT_DOUBLE_FLOAT +bool pb_decode_double_as_float(pb_istream_t *stream, float *dest) { + uint8_t sign; + int exponent; + uint32_t mantissa; + uint64_t value; + union { + float f; + uint32_t i; + } out; + + if (!pb_decode_fixed64(stream, &value)) + return false; + + /* Decompose input value */ + sign = (uint8_t)((value >> 63) & 1); + exponent = (int)((value >> 52) & 0x7FF) - 1023; + mantissa = (value >> 28) & 0xFFFFFF; /* Highest 24 bits */ + + /* Figure if value is in range representable by floats. */ + if (exponent == 1024) { + /* Special value */ + exponent = 128; + } else if (exponent > 127) { + /* Too large, convert to infinity */ + exponent = 128; + mantissa = 0; + } else if (exponent < -150) { + /* Too small, convert to zero */ + exponent = -127; + mantissa = 0; + } else if (exponent < -126) { + /* Denormalized */ + mantissa |= 0x1000000; + mantissa >>= (-126 - exponent); + exponent = -127; + } + + /* Round off mantissa */ + mantissa = (mantissa + 1) >> 1; + + /* Check if mantissa went over 2.0 */ + if (mantissa & 0x800000) { + exponent += 1; + mantissa &= 0x7FFFFF; + mantissa >>= 1; + } + + /* Combine fields */ + out.i = mantissa; + out.i |= (uint32_t)(exponent + 127) << 23; + out.i |= (uint32_t)sign << 31; + + *dest = out.f; + return true; +} +#endif diff --git a/src/nanopb/pb_decode.h b/src/nanopb/pb_decode.h new file mode 100644 index 00000000..f5f266b3 --- /dev/null +++ b/src/nanopb/pb_decode.h @@ -0,0 +1,194 @@ +/* pb_decode.h: Functions to decode protocol buffers. Depends on pb_decode.c. + * The main function is pb_decode. You also need an input stream, and the + * field descriptions created by nanopb_generator.py. + */ + +#ifndef PB_DECODE_H_INCLUDED +#define PB_DECODE_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure for defining custom input streams. You will need to provide + * a callback function to read the bytes from your storage, which can be + * for example a file or a network socket. + * + * The callback must conform to these rules: + * + * 1) Return false on IO errors. This will cause decoding to abort. + * 2) You can use state to store your own data (e.g. buffer pointer), + * and rely on pb_read to verify that no-body reads past bytes_left. + * 3) Your callback may be used with substreams, in which case bytes_left + * is different than from the main stream. Don't use bytes_left to compute + * any pointers. + */ +struct pb_istream_s { +#ifdef PB_BUFFER_ONLY + /* Callback pointer is not used in buffer-only configuration. + * Having an int pointer here allows binary compatibility but + * gives an error if someone tries to assign callback function. + */ + int *callback; +#else + bool (*callback)(pb_istream_t *stream, pb_byte_t *buf, size_t count); +#endif + + void *state; /* Free field for use by callback implementation */ + size_t bytes_left; + +#ifndef PB_NO_ERRMSG + const char *errmsg; +#endif +}; + +#ifndef PB_NO_ERRMSG +#define PB_ISTREAM_EMPTY \ + { 0, 0, 0, 0 } +#else +#define PB_ISTREAM_EMPTY \ + { 0, 0, 0 } +#endif + +/*************************** + * Main decoding functions * + ***************************/ + +/* Decode a single protocol buffers message from input stream into a C + * structure. Returns true on success, false on any failure. The actual struct + * pointed to by dest must match the description in fields. Callback fields of + * the destination structure must be initialized by caller. All other fields + * will be initialized by this function. + * + * Example usage: + * MyMessage msg = {}; + * uint8_t buffer[64]; + * pb_istream_t stream; + * + * // ... read some data into buffer ... + * + * stream = pb_istream_from_buffer(buffer, count); + * pb_decode(&stream, MyMessage_fields, &msg); + */ +bool pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, + void *dest_struct); + +/* Extended version of pb_decode, with several options to control + * the decoding process: + * + * PB_DECODE_NOINIT: Do not initialize the fields to default values. + * This is slightly faster if you do not need the + * default values and instead initialize the structure to 0 using e.g. memset(). + * This can also be used for merging two messages, i.e. combine already existing + * data with new values. + * + * PB_DECODE_DELIMITED: Input message starts with the message size as + * varint. Corresponds to parseDelimitedFrom() in Google's protobuf API. + * + * PB_DECODE_NULLTERMINATED: Stop reading when field tag is read as 0. This + * allows reading null terminated messages. NOTE: Until nanopb-0.4.0, + * pb_decode() also allows null-termination. This behaviour is not supported in + * most other protobuf implementations, so + * PB_DECODE_DELIMITED is a better option for compatibility. + * + * Multiple flags can be combined with bitwise or (| operator) + */ +#define PB_DECODE_NOINIT 0x01U +#define PB_DECODE_DELIMITED 0x02U +#define PB_DECODE_NULLTERMINATED 0x04U +bool pb_decode_ex(pb_istream_t *stream, const pb_msgdesc_t *fields, + void *dest_struct, unsigned int flags); + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define pb_decode_noinit(s, f, d) pb_decode_ex(s, f, d, PB_DECODE_NOINIT) +#define pb_decode_delimited(s, f, d) pb_decode_ex(s, f, d, PB_DECODE_DELIMITED) +#define pb_decode_delimited_noinit(s, f, d) \ + pb_decode_ex(s, f, d, PB_DECODE_DELIMITED | PB_DECODE_NOINIT) +#define pb_decode_nullterminated(s, f, d) \ + pb_decode_ex(s, f, d, PB_DECODE_NULLTERMINATED) + +#ifdef PB_ENABLE_MALLOC +/* Release any allocated pointer fields. If you use dynamic allocation, you + * should call this for any successfully decoded message when you are done with + * it. If pb_decode() returns with an error, the message is already released. + */ +void pb_release(const pb_msgdesc_t *fields, void *dest_struct); +#endif + +/************************************** + * Functions for manipulating streams * + **************************************/ + +/* Create an input stream for reading from a memory buffer. + * + * Alternatively, you can use a custom stream that reads directly from e.g. + * a file or a network socket. + */ +pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize); + +/* Function to read from a pb_istream_t. You can use this if you need to + * read some custom header data, or to read data in field callbacks. + */ +bool pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); + +/************************************************ + * Helper functions for writing field callbacks * + ************************************************/ + +/* Decode the tag for the next field in the stream. Gives the wire type and + * field tag. At end of the message, returns false and sets eof to true. */ +bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, + uint32_t *tag, bool *eof); + +/* Skip the field payload data, given the wire type. */ +bool pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type); + +/* Decode an integer in the varint format. This works for enum, int32, + * int64, uint32 and uint64 field types. */ +#ifndef PB_WITHOUT_64BIT +bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest); +#else +#define pb_decode_varint pb_decode_varint32 +#endif + +/* Decode an integer in the varint format. This works for enum, int32, + * and uint32 field types. */ +bool pb_decode_varint32(pb_istream_t *stream, uint32_t *dest); + +/* Decode a bool value in varint format. */ +bool pb_decode_bool(pb_istream_t *stream, bool *dest); + +/* Decode an integer in the zig-zagged svarint format. This works for sint32 + * and sint64. */ +#ifndef PB_WITHOUT_64BIT +bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest); +#else +bool pb_decode_svarint(pb_istream_t *stream, int32_t *dest); +#endif + +/* Decode a fixed32, sfixed32 or float value. You need to pass a pointer to + * a 4-byte wide C variable. */ +bool pb_decode_fixed32(pb_istream_t *stream, void *dest); + +#ifndef PB_WITHOUT_64BIT +/* Decode a fixed64, sfixed64 or double value. You need to pass a pointer to + * a 8-byte wide C variable. */ +bool pb_decode_fixed64(pb_istream_t *stream, void *dest); +#endif + +#ifdef PB_CONVERT_DOUBLE_FLOAT +/* Decode a double value into float variable. */ +bool pb_decode_double_as_float(pb_istream_t *stream, float *dest); +#endif + +/* Make a limited-length substream for reading a PB_WT_STRING field. */ +bool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream); +bool pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/nanopb/pb_encode.c b/src/nanopb/pb_encode.c new file mode 100644 index 00000000..f7a2f380 --- /dev/null +++ b/src/nanopb/pb_encode.c @@ -0,0 +1,887 @@ +/* pb_encode.c -- encode a protobuf using minimal resources + * + * 2011 Petteri Aimonen + */ + +#include "pb.h" +#include "pb_encode.h" +#include "pb_common.h" + +/* Use the GCC warn_unused_result attribute to check that all return values + * are propagated correctly. On other compilers and gcc before 3.4.0 just + * ignore the annotation. + */ +#if !defined(__GNUC__) || (__GNUC__ < 3) || \ + (__GNUC__ == 3 && __GNUC_MINOR__ < 4) +#define checkreturn +#else +#define checkreturn __attribute__((warn_unused_result)) +#endif + +/************************************** + * Declarations internal to this file * + **************************************/ +static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, + size_t count); +static bool checkreturn encode_array(pb_ostream_t *stream, + pb_field_iter_t *field); +static bool checkreturn +pb_check_proto3_default_value(const pb_field_iter_t *field); +static bool checkreturn encode_basic_field(pb_ostream_t *stream, + const pb_field_iter_t *field); +static bool checkreturn encode_callback_field(pb_ostream_t *stream, + const pb_field_iter_t *field); +static bool checkreturn encode_field(pb_ostream_t *stream, + pb_field_iter_t *field); +static bool checkreturn encode_extension_field(pb_ostream_t *stream, + const pb_field_iter_t *field); +static bool checkreturn default_extension_encoder( + pb_ostream_t *stream, const pb_extension_t *extension); +static void *pb_const_cast(const void *p); +static bool checkreturn pb_encode_varint_32(pb_ostream_t *stream, uint32_t low, + uint32_t high); +static bool checkreturn pb_enc_bool(pb_ostream_t *stream, + const pb_field_iter_t *field); +static bool checkreturn pb_enc_varint(pb_ostream_t *stream, + const pb_field_iter_t *field); +static bool checkreturn pb_enc_fixed(pb_ostream_t *stream, + const pb_field_iter_t *field); +static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, + const pb_field_iter_t *field); +static bool checkreturn pb_enc_string(pb_ostream_t *stream, + const pb_field_iter_t *field); +static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, + const pb_field_iter_t *field); +static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, + const pb_field_iter_t *field); + +#ifdef PB_WITHOUT_64BIT +#define pb_int64_t int32_t +#define pb_uint64_t uint32_t +#else +#define pb_int64_t int64_t +#define pb_uint64_t uint64_t +#endif + +/******************************* + * pb_ostream_t implementation * + *******************************/ + +static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, + size_t count) { + size_t i; + pb_byte_t *dest = (pb_byte_t *)stream->state; + stream->state = dest + count; + + for (i = 0; i < count; i++) + dest[i] = buf[i]; + + return true; +} + +pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize) { + pb_ostream_t stream; +#ifdef PB_BUFFER_ONLY + stream.callback = (void *)1; /* Just a marker value */ +#else + stream.callback = &buf_write; +#endif + stream.state = buf; + stream.max_size = bufsize; + stream.bytes_written = 0; +#ifndef PB_NO_ERRMSG + stream.errmsg = NULL; +#endif + return stream; +} + +bool checkreturn pb_write(pb_ostream_t *stream, const pb_byte_t *buf, + size_t count) { + if (count > 0 && stream->callback != NULL) { + if (stream->bytes_written + count > stream->max_size) + PB_RETURN_ERROR(stream, "stream full"); + +#ifdef PB_BUFFER_ONLY + if (!buf_write(stream, buf, count)) + PB_RETURN_ERROR(stream, "io error"); +#else + if (!stream->callback(stream, buf, count)) + PB_RETURN_ERROR(stream, "io error"); +#endif + } + + stream->bytes_written += count; + return true; +} + +/************************* + * Encode a single field * + *************************/ + +/* Read a bool value without causing undefined behavior even if the value + * is invalid. See issue #434 and + * https://stackoverflow.com/questions/27661768/weird-results-for-conditional + */ +static bool safe_read_bool(const void *pSize) { + const char *p = (const char *)pSize; + size_t i; + for (i = 0; i < sizeof(bool); i++) { + if (p[i] != 0) + return true; + } + return false; +} + +/* Encode a static array. Handles the size calculations and possible packing. */ +static bool checkreturn encode_array(pb_ostream_t *stream, + pb_field_iter_t *field) { + pb_size_t i; + pb_size_t count; +#ifndef PB_ENCODE_ARRAYS_UNPACKED + size_t size; +#endif + + count = *(pb_size_t *)field->pSize; + + if (count == 0) + return true; + + if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size) + PB_RETURN_ERROR(stream, "array max size exceeded"); + +#ifndef PB_ENCODE_ARRAYS_UNPACKED + /* We always pack arrays if the datatype allows it. */ + if (PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) { + if (!pb_encode_tag(stream, PB_WT_STRING, field->tag)) + return false; + + /* Determine the total size of packed array. */ + if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32) { + size = 4 * (size_t)count; + } else if (PB_LTYPE(field->type) == PB_LTYPE_FIXED64) { + size = 8 * (size_t)count; + } else { + pb_ostream_t sizestream = PB_OSTREAM_SIZING; + void *pData_orig = field->pData; + for (i = 0; i < count; i++) { + if (!pb_enc_varint(&sizestream, field)) + PB_RETURN_ERROR(stream, PB_GET_ERROR(&sizestream)); + field->pData = (char *)field->pData + field->data_size; + } + field->pData = pData_orig; + size = sizestream.bytes_written; + } + + if (!pb_encode_varint(stream, (pb_uint64_t)size)) + return false; + + if (stream->callback == NULL) + return pb_write(stream, NULL, size); /* Just sizing.. */ + + /* Write the data */ + for (i = 0; i < count; i++) { + if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32 || + PB_LTYPE(field->type) == PB_LTYPE_FIXED64) { + if (!pb_enc_fixed(stream, field)) + return false; + } else { + if (!pb_enc_varint(stream, field)) + return false; + } + + field->pData = (char *)field->pData + field->data_size; + } + } else /* Unpacked fields */ +#endif + { + for (i = 0; i < count; i++) { + /* Normally the data is stored directly in the array entries, but + * for pointer-type string and bytes fields, the array entries are + * actually pointers themselves also. So we have to dereference once + * more to get to the actual data. */ + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER && + (PB_LTYPE(field->type) == PB_LTYPE_STRING || + PB_LTYPE(field->type) == PB_LTYPE_BYTES)) { + bool status; + void *pData_orig = field->pData; + field->pData = *(void *const *)field->pData; + + if (!field->pData) { + /* Null pointer in array is treated as empty string / bytes */ + status = pb_encode_tag_for_field(stream, field) && + pb_encode_varint(stream, 0); + } else { + status = encode_basic_field(stream, field); + } + + field->pData = pData_orig; + + if (!status) + return false; + } else { + if (!encode_basic_field(stream, field)) + return false; + } + field->pData = (char *)field->pData + field->data_size; + } + } + + return true; +} + +/* In proto3, all fields are optional and are only encoded if their value is + * "non-zero". This function implements the check for the zero value. */ +static bool checkreturn +pb_check_proto3_default_value(const pb_field_iter_t *field) { + pb_type_t type = field->type; + + if (PB_ATYPE(type) == PB_ATYPE_STATIC) { + if (PB_HTYPE(type) == PB_HTYPE_REQUIRED) { + /* Required proto2 fields inside proto3 submessage, pretty rare case */ + return false; + } else if (PB_HTYPE(type) == PB_HTYPE_REPEATED) { + /* Repeated fields inside proto3 submessage: present if count != 0 */ + return *(const pb_size_t *)field->pSize == 0; + } else if (PB_HTYPE(type) == PB_HTYPE_ONEOF) { + /* Oneof fields */ + return *(const pb_size_t *)field->pSize == 0; + } else if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && field->pSize != NULL) { + /* Proto2 optional fields inside proto3 message, or proto3 + * submessage fields. */ + return safe_read_bool(field->pSize) == false; + } + + /* Rest is proto3 singular fields */ + if (PB_LTYPE(type) == PB_LTYPE_BYTES) { + const pb_bytes_array_t *bytes = (const pb_bytes_array_t *)field->pData; + return bytes->size == 0; + } else if (PB_LTYPE(type) == PB_LTYPE_STRING) { + return *(const char *)field->pData == '\0'; + } else if (PB_LTYPE(type) == PB_LTYPE_FIXED_LENGTH_BYTES) { + /* Fixed length bytes is only empty if its length is fixed + * as 0. Which would be pretty strange, but we can check + * it anyway. */ + return field->data_size == 0; + } else if (PB_LTYPE_IS_SUBMSG(type)) { + /* Check all fields in the submessage to find if any of them + * are non-zero. The comparison cannot be done byte-per-byte + * because the C struct may contain padding bytes that must + * be skipped. Note that usually proto3 submessages have + * a separate has_field that is checked earlier in this if. + */ + pb_field_iter_t iter; + if (pb_field_iter_begin(&iter, field->submsg_desc, field->pData)) { + do { + if (!pb_check_proto3_default_value(&iter)) { + return false; + } + } while (pb_field_iter_next(&iter)); + } + return true; + } + } + + { + /* Catch-all branch that does byte-per-byte comparison for zero value. + * + * This is for all pointer fields, and for static PB_LTYPE_VARINT, + * UVARINT, SVARINT, FIXED32, FIXED64, EXTENSION fields, and also + * callback fields. These all have integer or pointer value which + * can be compared with 0. + */ + pb_size_t i; + const char *p = (const char *)field->pData; + for (i = 0; i < field->data_size; i++) { + if (p[i] != 0) { + return false; + } + } + + return true; + } +} + +/* Encode a field with static or pointer allocation, i.e. one whose data + * is available to the encoder directly. */ +static bool checkreturn encode_basic_field(pb_ostream_t *stream, + const pb_field_iter_t *field) { + if (!field->pData) { + /* Missing pointer field */ + return true; + } + + if (!pb_encode_tag_for_field(stream, field)) + return false; + + switch (PB_LTYPE(field->type)) { + case PB_LTYPE_BOOL: + return pb_enc_bool(stream, field); + + case PB_LTYPE_VARINT: + case PB_LTYPE_UVARINT: + case PB_LTYPE_SVARINT: + return pb_enc_varint(stream, field); + + case PB_LTYPE_FIXED32: + case PB_LTYPE_FIXED64: + return pb_enc_fixed(stream, field); + + case PB_LTYPE_BYTES: + return pb_enc_bytes(stream, field); + + case PB_LTYPE_STRING: + return pb_enc_string(stream, field); + + case PB_LTYPE_SUBMESSAGE: + case PB_LTYPE_SUBMSG_W_CB: + return pb_enc_submessage(stream, field); + + case PB_LTYPE_FIXED_LENGTH_BYTES: + return pb_enc_fixed_length_bytes(stream, field); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +/* Encode a field with callback semantics. This means that a user function is + * called to provide and encode the actual data. */ +static bool checkreturn encode_callback_field(pb_ostream_t *stream, + const pb_field_iter_t *field) { + if (field->descriptor->field_callback != NULL) { + if (!field->descriptor->field_callback(NULL, stream, field)) + PB_RETURN_ERROR(stream, "callback error"); + } + return true; +} + +/* Encode a single field of any callback, pointer or static type. */ +static bool checkreturn encode_field(pb_ostream_t *stream, + pb_field_iter_t *field) { + /* Check field presence */ + if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF) { + if (*(const pb_size_t *)field->pSize != field->tag) { + /* Different type oneof field */ + return true; + } + } else if (PB_HTYPE(field->type) == PB_HTYPE_OPTIONAL) { + if (field->pSize) { + if (safe_read_bool(field->pSize) == false) { + /* Missing optional field */ + return true; + } + } else if (PB_ATYPE(field->type) == PB_ATYPE_STATIC) { + /* Proto3 singular field */ + if (pb_check_proto3_default_value(field)) + return true; + } + } + + if (!field->pData) { + if (PB_HTYPE(field->type) == PB_HTYPE_REQUIRED) + PB_RETURN_ERROR(stream, "missing required field"); + + /* Pointer field set to NULL */ + return true; + } + + /* Then encode field contents */ + if (PB_ATYPE(field->type) == PB_ATYPE_CALLBACK) { + return encode_callback_field(stream, field); + } else if (PB_HTYPE(field->type) == PB_HTYPE_REPEATED) { + return encode_array(stream, field); + } else { + return encode_basic_field(stream, field); + } +} + +/* Default handler for extension fields. Expects to have a pb_msgdesc_t + * pointer in the extension->type->arg field, pointing to a message with + * only one field in it. */ +static bool checkreturn default_extension_encoder( + pb_ostream_t *stream, const pb_extension_t *extension) { + pb_field_iter_t iter; + + if (!pb_field_iter_begin_extension( + &iter, (pb_extension_t *)pb_const_cast(extension))) + PB_RETURN_ERROR(stream, "invalid extension"); + + return encode_field(stream, &iter); +} + +/* Walk through all the registered extensions and give them a chance + * to encode themselves. */ +static bool checkreturn encode_extension_field(pb_ostream_t *stream, + const pb_field_iter_t *field) { + const pb_extension_t *extension = + *(const pb_extension_t *const *)field->pData; + + while (extension) { + bool status; + if (extension->type->encode) + status = extension->type->encode(stream, extension); + else + status = default_extension_encoder(stream, extension); + + if (!status) + return false; + + extension = extension->next; + } + + return true; +} + +/********************* + * Encode all fields * + *********************/ + +static void *pb_const_cast(const void *p) { + /* Note: this casts away const, in order to use the common field iterator + * logic for both encoding and decoding. */ + union { + void *p1; + const void *p2; + } t; + t.p2 = p; + return t.p1; +} + +bool checkreturn pb_encode(pb_ostream_t *stream, const pb_msgdesc_t *fields, + const void *src_struct) { + pb_field_iter_t iter; + if (!pb_field_iter_begin(&iter, fields, pb_const_cast(src_struct))) + return true; /* Empty message type */ + + do { + if (PB_LTYPE(iter.type) == PB_LTYPE_EXTENSION) { + /* Special case for the extension field placeholder */ + if (!encode_extension_field(stream, &iter)) + return false; + } else { + /* Regular field */ + if (!encode_field(stream, &iter)) + return false; + } + } while (pb_field_iter_next(&iter)); + + return true; +} + +bool checkreturn pb_encode_ex(pb_ostream_t *stream, const pb_msgdesc_t *fields, + const void *src_struct, unsigned int flags) { + if ((flags & PB_ENCODE_DELIMITED) != 0) { + return pb_encode_submessage(stream, fields, src_struct); + } else if ((flags & PB_ENCODE_NULLTERMINATED) != 0) { + const pb_byte_t zero = 0; + + if (!pb_encode(stream, fields, src_struct)) + return false; + + return pb_write(stream, &zero, 1); + } else { + return pb_encode(stream, fields, src_struct); + } +} + +bool pb_get_encoded_size(size_t *size, const pb_msgdesc_t *fields, + const void *src_struct) { + pb_ostream_t stream = PB_OSTREAM_SIZING; + + if (!pb_encode(&stream, fields, src_struct)) + return false; + + *size = stream.bytes_written; + return true; +} + +/******************** + * Helper functions * + ********************/ + +/* This function avoids 64-bit shifts as they are quite slow on many platforms. + */ +static bool checkreturn pb_encode_varint_32(pb_ostream_t *stream, uint32_t low, + uint32_t high) { + size_t i = 0; + pb_byte_t buffer[10]; + pb_byte_t byte = (pb_byte_t)(low & 0x7F); + low >>= 7; + + while (i < 4 && (low != 0 || high != 0)) { + byte |= 0x80; + buffer[i++] = byte; + byte = (pb_byte_t)(low & 0x7F); + low >>= 7; + } + + if (high) { + byte = (pb_byte_t)(byte | ((high & 0x07) << 4)); + high >>= 3; + + while (high) { + byte |= 0x80; + buffer[i++] = byte; + byte = (pb_byte_t)(high & 0x7F); + high >>= 7; + } + } + + buffer[i++] = byte; + + return pb_write(stream, buffer, i); +} + +bool checkreturn pb_encode_varint(pb_ostream_t *stream, pb_uint64_t value) { + if (value <= 0x7F) { + /* Fast path: single byte */ + pb_byte_t byte = (pb_byte_t)value; + return pb_write(stream, &byte, 1); + } else { +#ifdef PB_WITHOUT_64BIT + return pb_encode_varint_32(stream, value, 0); +#else + return pb_encode_varint_32(stream, (uint32_t)value, + (uint32_t)(value >> 32)); +#endif + } +} + +bool checkreturn pb_encode_svarint(pb_ostream_t *stream, pb_int64_t value) { + pb_uint64_t zigzagged; + if (value < 0) + zigzagged = ~((pb_uint64_t)value << 1); + else + zigzagged = (pb_uint64_t)value << 1; + + return pb_encode_varint(stream, zigzagged); +} + +bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value) { + uint32_t val = *(const uint32_t *)value; + pb_byte_t bytes[4]; + bytes[0] = (pb_byte_t)(val & 0xFF); + bytes[1] = (pb_byte_t)((val >> 8) & 0xFF); + bytes[2] = (pb_byte_t)((val >> 16) & 0xFF); + bytes[3] = (pb_byte_t)((val >> 24) & 0xFF); + return pb_write(stream, bytes, 4); +} + +#ifndef PB_WITHOUT_64BIT +bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value) { + uint64_t val = *(const uint64_t *)value; + pb_byte_t bytes[8]; + bytes[0] = (pb_byte_t)(val & 0xFF); + bytes[1] = (pb_byte_t)((val >> 8) & 0xFF); + bytes[2] = (pb_byte_t)((val >> 16) & 0xFF); + bytes[3] = (pb_byte_t)((val >> 24) & 0xFF); + bytes[4] = (pb_byte_t)((val >> 32) & 0xFF); + bytes[5] = (pb_byte_t)((val >> 40) & 0xFF); + bytes[6] = (pb_byte_t)((val >> 48) & 0xFF); + bytes[7] = (pb_byte_t)((val >> 56) & 0xFF); + return pb_write(stream, bytes, 8); +} +#endif + +bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, + uint32_t field_number) { + pb_uint64_t tag = ((pb_uint64_t)field_number << 3) | wiretype; + return pb_encode_varint(stream, tag); +} + +bool pb_encode_tag_for_field(pb_ostream_t *stream, + const pb_field_iter_t *field) { + pb_wire_type_t wiretype; + switch (PB_LTYPE(field->type)) { + case PB_LTYPE_BOOL: + case PB_LTYPE_VARINT: + case PB_LTYPE_UVARINT: + case PB_LTYPE_SVARINT: + wiretype = PB_WT_VARINT; + break; + + case PB_LTYPE_FIXED32: + wiretype = PB_WT_32BIT; + break; + + case PB_LTYPE_FIXED64: + wiretype = PB_WT_64BIT; + break; + + case PB_LTYPE_BYTES: + case PB_LTYPE_STRING: + case PB_LTYPE_SUBMESSAGE: + case PB_LTYPE_SUBMSG_W_CB: + case PB_LTYPE_FIXED_LENGTH_BYTES: + wiretype = PB_WT_STRING; + break; + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } + + return pb_encode_tag(stream, wiretype, field->tag); +} + +bool checkreturn pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, + size_t size) { + if (!pb_encode_varint(stream, (pb_uint64_t)size)) + return false; + + return pb_write(stream, buffer, size); +} + +bool checkreturn pb_encode_submessage(pb_ostream_t *stream, + const pb_msgdesc_t *fields, + const void *src_struct) { + /* First calculate the message size using a non-writing substream. */ + pb_ostream_t substream = PB_OSTREAM_SIZING; + size_t size; + bool status; + + if (!pb_encode(&substream, fields, src_struct)) { +#ifndef PB_NO_ERRMSG + stream->errmsg = substream.errmsg; +#endif + return false; + } + + size = substream.bytes_written; + + if (!pb_encode_varint(stream, (pb_uint64_t)size)) + return false; + + if (stream->callback == NULL) + return pb_write(stream, NULL, size); /* Just sizing */ + + if (stream->bytes_written + size > stream->max_size) + PB_RETURN_ERROR(stream, "stream full"); + + /* Use a substream to verify that a callback doesn't write more than + * what it did the first time. */ + substream.callback = stream->callback; + substream.state = stream->state; + substream.max_size = size; + substream.bytes_written = 0; +#ifndef PB_NO_ERRMSG + substream.errmsg = NULL; +#endif + + status = pb_encode(&substream, fields, src_struct); + + stream->bytes_written += substream.bytes_written; + stream->state = substream.state; +#ifndef PB_NO_ERRMSG + stream->errmsg = substream.errmsg; +#endif + + if (substream.bytes_written != size) + PB_RETURN_ERROR(stream, "submsg size changed"); + + return status; +} + +/* Field encoders */ + +static bool checkreturn pb_enc_bool(pb_ostream_t *stream, + const pb_field_iter_t *field) { + uint32_t value = safe_read_bool(field->pData) ? 1 : 0; + PB_UNUSED(field); + return pb_encode_varint(stream, value); +} + +static bool checkreturn pb_enc_varint(pb_ostream_t *stream, + const pb_field_iter_t *field) { + if (PB_LTYPE(field->type) == PB_LTYPE_UVARINT) { + /* Perform unsigned integer extension */ + pb_uint64_t value = 0; + + if (field->data_size == sizeof(uint_least8_t)) + value = *(const uint_least8_t *)field->pData; + else if (field->data_size == sizeof(uint_least16_t)) + value = *(const uint_least16_t *)field->pData; + else if (field->data_size == sizeof(uint32_t)) + value = *(const uint32_t *)field->pData; + else if (field->data_size == sizeof(pb_uint64_t)) + value = *(const pb_uint64_t *)field->pData; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + return pb_encode_varint(stream, value); + } else { + /* Perform signed integer extension */ + pb_int64_t value = 0; + + if (field->data_size == sizeof(int_least8_t)) + value = *(const int_least8_t *)field->pData; + else if (field->data_size == sizeof(int_least16_t)) + value = *(const int_least16_t *)field->pData; + else if (field->data_size == sizeof(int32_t)) + value = *(const int32_t *)field->pData; + else if (field->data_size == sizeof(pb_int64_t)) + value = *(const pb_int64_t *)field->pData; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + if (PB_LTYPE(field->type) == PB_LTYPE_SVARINT) + return pb_encode_svarint(stream, value); +#ifdef PB_WITHOUT_64BIT + else if (value < 0) + return pb_encode_varint_32(stream, (uint32_t)value, (uint32_t)-1); +#endif + else + return pb_encode_varint(stream, (pb_uint64_t)value); + } +} + +static bool checkreturn pb_enc_fixed(pb_ostream_t *stream, + const pb_field_iter_t *field) { +#ifdef PB_CONVERT_DOUBLE_FLOAT + if (field->data_size == sizeof(float) && + PB_LTYPE(field->type) == PB_LTYPE_FIXED64) { + return pb_encode_float_as_double(stream, *(float *)field->pData); + } +#endif + + if (field->data_size == sizeof(uint32_t)) { + return pb_encode_fixed32(stream, field->pData); + } +#ifndef PB_WITHOUT_64BIT + else if (field->data_size == sizeof(uint64_t)) { + return pb_encode_fixed64(stream, field->pData); + } +#endif + else { + PB_RETURN_ERROR(stream, "invalid data_size"); + } +} + +static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, + const pb_field_iter_t *field) { + const pb_bytes_array_t *bytes = NULL; + + bytes = (const pb_bytes_array_t *)field->pData; + + if (bytes == NULL) { + /* Treat null pointer as an empty bytes field */ + return pb_encode_string(stream, NULL, 0); + } + + if (PB_ATYPE(field->type) == PB_ATYPE_STATIC && + PB_BYTES_ARRAY_T_ALLOCSIZE(bytes->size) > field->data_size) { + PB_RETURN_ERROR(stream, "bytes size exceeded"); + } + + return pb_encode_string(stream, bytes->bytes, (size_t)bytes->size); +} + +static bool checkreturn pb_enc_string(pb_ostream_t *stream, + const pb_field_iter_t *field) { + size_t size = 0; + size_t max_size = (size_t)field->data_size; + const char *str = (const char *)field->pData; + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) { + max_size = (size_t)-1; + } else { + /* pb_dec_string() assumes string fields end with a null + * terminator when the type isn't PB_ATYPE_POINTER, so we + * shouldn't allow more than max-1 bytes to be written to + * allow space for the null terminator. + */ + if (max_size == 0) + PB_RETURN_ERROR(stream, "zero-length string"); + + max_size -= 1; + } + + if (str == NULL) { + size = 0; /* Treat null pointer as an empty string */ + } else { + const char *p = str; + + /* strnlen() is not always available, so just use a loop */ + while (size < max_size && *p != '\0') { + size++; + p++; + } + + if (*p != '\0') { + PB_RETURN_ERROR(stream, "unterminated string"); + } + } + +#ifdef PB_VALIDATE_UTF8 + if (!pb_validate_utf8(str)) + PB_RETURN_ERROR(stream, "invalid utf8"); +#endif + + return pb_encode_string(stream, (const pb_byte_t *)str, size); +} + +static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, + const pb_field_iter_t *field) { + if (field->submsg_desc == NULL) + PB_RETURN_ERROR(stream, "invalid field descriptor"); + + if (PB_LTYPE(field->type) == PB_LTYPE_SUBMSG_W_CB && field->pSize != NULL) { + /* Message callback is stored right before pSize. */ + pb_callback_t *callback = (pb_callback_t *)field->pSize - 1; + if (callback->funcs.encode) { + if (!callback->funcs.encode(stream, field, &callback->arg)) + return false; + } + } + + return pb_encode_submessage(stream, field->submsg_desc, field->pData); +} + +static bool checkreturn +pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_iter_t *field) { + return pb_encode_string(stream, (const pb_byte_t *)field->pData, + (size_t)field->data_size); +} + +#ifdef PB_CONVERT_DOUBLE_FLOAT +bool pb_encode_float_as_double(pb_ostream_t *stream, float value) { + union { + float f; + uint32_t i; + } in; + uint8_t sign; + int exponent; + uint64_t mantissa; + + in.f = value; + + /* Decompose input value */ + sign = (uint8_t)((in.i >> 31) & 1); + exponent = (int)((in.i >> 23) & 0xFF) - 127; + mantissa = in.i & 0x7FFFFF; + + if (exponent == 128) { + /* Special value (NaN etc.) */ + exponent = 1024; + } else if (exponent == -127) { + if (!mantissa) { + /* Zero */ + exponent = -1023; + } else { + /* Denormalized */ + mantissa <<= 1; + while (!(mantissa & 0x800000)) { + mantissa <<= 1; + exponent--; + } + mantissa &= 0x7FFFFF; + } + } + + /* Combine fields */ + mantissa <<= 29; + mantissa |= (uint64_t)(exponent + 1023) << 52; + mantissa |= (uint64_t)sign << 63; + + return pb_encode_fixed64(stream, &mantissa); +} +#endif diff --git a/src/nanopb/pb_encode.h b/src/nanopb/pb_encode.h new file mode 100644 index 00000000..dc222083 --- /dev/null +++ b/src/nanopb/pb_encode.h @@ -0,0 +1,193 @@ +/* pb_encode.h: Functions to encode protocol buffers. Depends on pb_encode.c. + * The main function is pb_encode. You also need an output stream, and the + * field descriptions created by nanopb_generator.py. + */ + +#ifndef PB_ENCODE_H_INCLUDED +#define PB_ENCODE_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure for defining custom output streams. You will need to provide + * a callback function to write the bytes to your storage, which can be + * for example a file or a network socket. + * + * The callback must conform to these rules: + * + * 1) Return false on IO errors. This will cause encoding to abort. + * 2) You can use state to store your own data (e.g. buffer pointer). + * 3) pb_write will update bytes_written after your callback runs. + * 4) Substreams will modify max_size and bytes_written. Don't use them + * to calculate any pointers. + */ +struct pb_ostream_s { +#ifdef PB_BUFFER_ONLY + /* Callback pointer is not used in buffer-only configuration. + * Having an int pointer here allows binary compatibility but + * gives an error if someone tries to assign callback function. + * Also, NULL pointer marks a 'sizing stream' that does not + * write anything. + */ + int *callback; +#else + bool (*callback)(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); +#endif + void *state; /* Free field for use by callback implementation. */ + size_t max_size; /* Limit number of output bytes written (or use SIZE_MAX). */ + size_t bytes_written; /* Number of bytes written so far. */ + +#ifndef PB_NO_ERRMSG + const char *errmsg; +#endif +}; + +/*************************** + * Main encoding functions * + ***************************/ + +/* Encode a single protocol buffers message from C structure into a stream. + * Returns true on success, false on any failure. + * The actual struct pointed to by src_struct must match the description in + * fields. All required fields in the struct are assumed to have been filled in. + * + * Example usage: + * MyMessage msg = {}; + * uint8_t buffer[64]; + * pb_ostream_t stream; + * + * msg.field1 = 42; + * stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + * pb_encode(&stream, MyMessage_fields, &msg); + */ +bool pb_encode(pb_ostream_t *stream, const pb_msgdesc_t *fields, + const void *src_struct); + +/* Extended version of pb_encode, with several options to control the + * encoding process: + * + * PB_ENCODE_DELIMITED: Prepend the length of message as a varint. + * Corresponds to writeDelimitedTo() in Google's + * protobuf API. + * + * PB_ENCODE_NULLTERMINATED: Append a null byte to the message for termination. + * NOTE: This behaviour is not supported in most other + * protobuf implementations, so PB_ENCODE_DELIMITED + * is a better option for compatibility. + */ +#define PB_ENCODE_DELIMITED 0x02U +#define PB_ENCODE_NULLTERMINATED 0x04U +bool pb_encode_ex(pb_ostream_t *stream, const pb_msgdesc_t *fields, + const void *src_struct, unsigned int flags); + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define pb_encode_delimited(s, f, d) pb_encode_ex(s, f, d, PB_ENCODE_DELIMITED) +#define pb_encode_nullterminated(s, f, d) \ + pb_encode_ex(s, f, d, PB_ENCODE_NULLTERMINATED) + +/* Encode the message to get the size of the encoded data, but do not store + * the data. */ +bool pb_get_encoded_size(size_t *size, const pb_msgdesc_t *fields, + const void *src_struct); + +/************************************** + * Functions for manipulating streams * + **************************************/ + +/* Create an output stream for writing into a memory buffer. + * The number of bytes written can be found in stream.bytes_written after + * encoding the message. + * + * Alternatively, you can use a custom stream that writes directly to e.g. + * a file or a network socket. + */ +pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize); + +/* Pseudo-stream for measuring the size of a message without actually storing + * the encoded data. + * + * Example usage: + * MyMessage msg = {}; + * pb_ostream_t stream = PB_OSTREAM_SIZING; + * pb_encode(&stream, MyMessage_fields, &msg); + * printf("Message size is %d\n", stream.bytes_written); + */ +#ifndef PB_NO_ERRMSG +#define PB_OSTREAM_SIZING \ + { 0, 0, 0, 0, 0 } +#else +#define PB_OSTREAM_SIZING \ + { 0, 0, 0, 0 } +#endif + +/* Function to write into a pb_ostream_t stream. You can use this if you need + * to append or prepend some custom headers to the message. + */ +bool pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); + +/************************************************ + * Helper functions for writing field callbacks * + ************************************************/ + +/* Encode field header based on type and field number defined in the field + * structure. Call this from the callback before writing out field contents. */ +bool pb_encode_tag_for_field(pb_ostream_t *stream, + const pb_field_iter_t *field); + +/* Encode field header by manually specifing wire type. You need to use this + * if you want to write out packed arrays from a callback field. */ +bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, + uint32_t field_number); + +/* Encode an integer in the varint format. + * This works for bool, enum, int32, int64, uint32 and uint64 field types. */ +#ifndef PB_WITHOUT_64BIT +bool pb_encode_varint(pb_ostream_t *stream, uint64_t value); +#else +bool pb_encode_varint(pb_ostream_t *stream, uint32_t value); +#endif + +/* Encode an integer in the zig-zagged svarint format. + * This works for sint32 and sint64. */ +#ifndef PB_WITHOUT_64BIT +bool pb_encode_svarint(pb_ostream_t *stream, int64_t value); +#else +bool pb_encode_svarint(pb_ostream_t *stream, int32_t value); +#endif + +/* Encode a string or bytes type field. For strings, pass strlen(s) as size. */ +bool pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, + size_t size); + +/* Encode a fixed32, sfixed32 or float value. + * You need to pass a pointer to a 4-byte wide C variable. */ +bool pb_encode_fixed32(pb_ostream_t *stream, const void *value); + +#ifndef PB_WITHOUT_64BIT +/* Encode a fixed64, sfixed64 or double value. + * You need to pass a pointer to a 8-byte wide C variable. */ +bool pb_encode_fixed64(pb_ostream_t *stream, const void *value); +#endif + +#ifdef PB_CONVERT_DOUBLE_FLOAT +/* Encode a float value so that it appears like a double in the encoded + * message. */ +bool pb_encode_float_as_double(pb_ostream_t *stream, float value); +#endif + +/* Encode a submessage field. + * You need to pass the pb_field_t array and pointer to struct, just like + * with pb_encode(). This internally encodes the submessage twice, first to + * calculate message size and then to actually write it out. + */ +bool pb_encode_submessage(pb_ostream_t *stream, const pb_msgdesc_t *fields, + const void *src_struct); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/nanopb_stubs/amount.pb.c b/src/nanopb_stubs/amount.pb.c new file mode 100644 index 00000000..f93feb70 --- /dev/null +++ b/src/nanopb_stubs/amount.pb.c @@ -0,0 +1,12 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.2-dev */ + +#include "amount.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(waves_Amount, waves_Amount, AUTO) + + + diff --git a/src/nanopb_stubs/amount.pb.h b/src/nanopb_stubs/amount.pb.h new file mode 100644 index 00000000..54a4b979 --- /dev/null +++ b/src/nanopb_stubs/amount.pb.h @@ -0,0 +1,50 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.2-dev */ + +#ifndef PB_WAVES_AMOUNT_PB_H_INCLUDED +#define PB_WAVES_AMOUNT_PB_H_INCLUDED +#include + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Struct definitions */ +typedef struct _waves_Amount { + pb_callback_t asset_id; + int64_t amount; +} waves_Amount; + + +/* Initializer values for message structs */ +#define waves_Amount_init_default {{{NULL}, NULL}, 0} +#define waves_Amount_init_zero {{{NULL}, NULL}, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define waves_Amount_asset_id_tag 1 +#define waves_Amount_amount_tag 2 + +/* Struct field encoding specification for nanopb */ +#define waves_Amount_FIELDLIST(X, a) \ +X(a, CALLBACK, SINGULAR, BYTES, asset_id, 1) \ +X(a, STATIC, SINGULAR, INT64, amount, 2) +#define waves_Amount_CALLBACK pb_default_field_callback +#define waves_Amount_DEFAULT NULL + +extern const pb_msgdesc_t waves_Amount_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define waves_Amount_fields &waves_Amount_msg + +/* Maximum encoded size of messages (where known) */ +/* waves_Amount_size depends on runtime parameters */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/nanopb_stubs/order.pb.c b/src/nanopb_stubs/order.pb.c new file mode 100644 index 00000000..4c78f576 --- /dev/null +++ b/src/nanopb_stubs/order.pb.c @@ -0,0 +1,16 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.2-dev */ + +#include "order.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(waves_AssetPair, waves_AssetPair, AUTO) + + +PB_BIND(waves_Order, waves_Order, AUTO) + + + + diff --git a/src/nanopb_stubs/order.pb.h b/src/nanopb_stubs/order.pb.h new file mode 100644 index 00000000..77128086 --- /dev/null +++ b/src/nanopb_stubs/order.pb.h @@ -0,0 +1,112 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.2-dev */ + +#ifndef PB_WAVES_ORDER_PB_H_INCLUDED +#define PB_WAVES_ORDER_PB_H_INCLUDED +#include +#include "amount.pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Enum definitions */ +typedef enum _waves_Order_Side { + waves_Order_Side_BUY = 0, + waves_Order_Side_SELL = 1 +} waves_Order_Side; + +/* Struct definitions */ +typedef struct _waves_AssetPair { + pb_callback_t amount_asset_id; + pb_callback_t price_asset_id; +} waves_AssetPair; + +typedef struct _waves_Order { + int32_t chain_id; + pb_callback_t sender_public_key; + pb_callback_t matcher_public_key; + bool has_asset_pair; + waves_AssetPair asset_pair; + waves_Order_Side order_side; + int64_t amount; + int64_t price; + int64_t timestamp; + int64_t expiration; + bool has_matcher_fee; + waves_Amount matcher_fee; + int32_t version; +} waves_Order; + + +/* Helper constants for enums */ +#define _waves_Order_Side_MIN waves_Order_Side_BUY +#define _waves_Order_Side_MAX waves_Order_Side_SELL +#define _waves_Order_Side_ARRAYSIZE ((waves_Order_Side)(waves_Order_Side_SELL+1)) + + +/* Initializer values for message structs */ +#define waves_AssetPair_init_default {{{NULL}, NULL}, {{NULL}, NULL}} +#define waves_Order_init_default {0, {{NULL}, NULL}, {{NULL}, NULL}, false, waves_AssetPair_init_default, _waves_Order_Side_MIN, 0, 0, 0, 0, false, waves_Amount_init_default, 0} +#define waves_AssetPair_init_zero {{{NULL}, NULL}, {{NULL}, NULL}} +#define waves_Order_init_zero {0, {{NULL}, NULL}, {{NULL}, NULL}, false, waves_AssetPair_init_zero, _waves_Order_Side_MIN, 0, 0, 0, 0, false, waves_Amount_init_zero, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define waves_AssetPair_amount_asset_id_tag 1 +#define waves_AssetPair_price_asset_id_tag 2 +#define waves_Order_chain_id_tag 1 +#define waves_Order_sender_public_key_tag 2 +#define waves_Order_matcher_public_key_tag 3 +#define waves_Order_asset_pair_tag 4 +#define waves_Order_order_side_tag 5 +#define waves_Order_amount_tag 6 +#define waves_Order_price_tag 7 +#define waves_Order_timestamp_tag 8 +#define waves_Order_expiration_tag 9 +#define waves_Order_matcher_fee_tag 10 +#define waves_Order_version_tag 11 + +/* Struct field encoding specification for nanopb */ +#define waves_AssetPair_FIELDLIST(X, a) \ +X(a, CALLBACK, SINGULAR, BYTES, amount_asset_id, 1) \ +X(a, CALLBACK, SINGULAR, BYTES, price_asset_id, 2) +#define waves_AssetPair_CALLBACK pb_default_field_callback +#define waves_AssetPair_DEFAULT NULL + +#define waves_Order_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, chain_id, 1) \ +X(a, CALLBACK, SINGULAR, BYTES, sender_public_key, 2) \ +X(a, CALLBACK, SINGULAR, BYTES, matcher_public_key, 3) \ +X(a, STATIC, OPTIONAL, MESSAGE, asset_pair, 4) \ +X(a, STATIC, SINGULAR, UENUM, order_side, 5) \ +X(a, STATIC, SINGULAR, INT64, amount, 6) \ +X(a, STATIC, SINGULAR, INT64, price, 7) \ +X(a, STATIC, SINGULAR, INT64, timestamp, 8) \ +X(a, STATIC, SINGULAR, INT64, expiration, 9) \ +X(a, STATIC, OPTIONAL, MESSAGE, matcher_fee, 10) \ +X(a, STATIC, SINGULAR, INT32, version, 11) +#define waves_Order_CALLBACK pb_default_field_callback +#define waves_Order_DEFAULT NULL +#define waves_Order_asset_pair_MSGTYPE waves_AssetPair +#define waves_Order_matcher_fee_MSGTYPE waves_Amount + +extern const pb_msgdesc_t waves_AssetPair_msg; +extern const pb_msgdesc_t waves_Order_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define waves_AssetPair_fields &waves_AssetPair_msg +#define waves_Order_fields &waves_Order_msg + +/* Maximum encoded size of messages (where known) */ +/* waves_AssetPair_size depends on runtime parameters */ +/* waves_Order_size depends on runtime parameters */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/nanopb_stubs/recipient.pb.c b/src/nanopb_stubs/recipient.pb.c new file mode 100644 index 00000000..4ffc8b1d --- /dev/null +++ b/src/nanopb_stubs/recipient.pb.c @@ -0,0 +1,12 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.2-dev */ + +#include "recipient.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(waves_Recipient, waves_Recipient, AUTO) + + + diff --git a/src/nanopb_stubs/recipient.pb.h b/src/nanopb_stubs/recipient.pb.h new file mode 100644 index 00000000..ad2cbd8a --- /dev/null +++ b/src/nanopb_stubs/recipient.pb.h @@ -0,0 +1,53 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.2-dev */ + +#ifndef PB_WAVES_RECIPIENT_PB_H_INCLUDED +#define PB_WAVES_RECIPIENT_PB_H_INCLUDED +#include + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Struct definitions */ +typedef struct _waves_Recipient { + pb_size_t which_recipient; + union { + pb_byte_t public_key_hash[20]; + char alias[31]; + } recipient; +} waves_Recipient; + + +/* Initializer values for message structs */ +#define waves_Recipient_init_default {0, {{0}}} +#define waves_Recipient_init_zero {0, {{0}}} + +/* Field tags (for use in manual encoding/decoding) */ +#define waves_Recipient_public_key_hash_tag 1 +#define waves_Recipient_alias_tag 2 + +/* Struct field encoding specification for nanopb */ +#define waves_Recipient_FIELDLIST(X, a) \ +X(a, STATIC, ONEOF, FIXED_LENGTH_BYTES, (recipient,public_key_hash,recipient.public_key_hash), 1) \ +X(a, STATIC, ONEOF, STRING, (recipient,alias,recipient.alias), 2) +#define waves_Recipient_CALLBACK NULL +#define waves_Recipient_DEFAULT NULL + +extern const pb_msgdesc_t waves_Recipient_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define waves_Recipient_fields &waves_Recipient_msg + +/* Maximum encoded size of messages (where known) */ +#define waves_Recipient_size 32 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/nanopb_stubs/transaction.pb.c b/src/nanopb_stubs/transaction.pb.c new file mode 100644 index 00000000..ed73bb56 --- /dev/null +++ b/src/nanopb_stubs/transaction.pb.c @@ -0,0 +1,66 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.2-dev */ + +#include "transaction.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(waves_SignedTransaction, waves_SignedTransaction, AUTO) + + +PB_BIND(waves_Transaction, waves_Transaction, 2) + + +PB_BIND(waves_GenesisTransactionData, waves_GenesisTransactionData, AUTO) + + +PB_BIND(waves_PaymentTransactionData, waves_PaymentTransactionData, AUTO) + + +PB_BIND(waves_TransferTransactionData, waves_TransferTransactionData, AUTO) + + +PB_BIND(waves_CreateAliasTransactionData, waves_CreateAliasTransactionData, AUTO) + + +PB_BIND(waves_DataTransactionData, waves_DataTransactionData, AUTO) + + +PB_BIND(waves_MassTransferTransactionData, waves_MassTransferTransactionData, AUTO) + + +PB_BIND(waves_LeaseTransactionData, waves_LeaseTransactionData, AUTO) + + +PB_BIND(waves_LeaseCancelTransactionData, waves_LeaseCancelTransactionData, AUTO) + + +PB_BIND(waves_BurnTransactionData, waves_BurnTransactionData, AUTO) + + +PB_BIND(waves_IssueTransactionData, waves_IssueTransactionData, AUTO) + + +PB_BIND(waves_ReissueTransactionData, waves_ReissueTransactionData, AUTO) + + +PB_BIND(waves_SetAssetScriptTransactionData, waves_SetAssetScriptTransactionData, AUTO) + + +PB_BIND(waves_SetScriptTransactionData, waves_SetScriptTransactionData, AUTO) + + +PB_BIND(waves_ExchangeTransactionData, waves_ExchangeTransactionData, AUTO) + + +PB_BIND(waves_SponsorFeeTransactionData, waves_SponsorFeeTransactionData, AUTO) + + +PB_BIND(waves_InvokeScriptTransactionData, waves_InvokeScriptTransactionData, AUTO) + + +PB_BIND(waves_UpdateAssetInfoTransactionData, waves_UpdateAssetInfoTransactionData, AUTO) + + + diff --git a/src/nanopb_stubs/transaction.pb.h b/src/nanopb_stubs/transaction.pb.h new file mode 100644 index 00000000..f831485a --- /dev/null +++ b/src/nanopb_stubs/transaction.pb.h @@ -0,0 +1,456 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.2-dev */ + +#ifndef PB_WAVES_TRANSACTION_PB_H_INCLUDED +#define PB_WAVES_TRANSACTION_PB_H_INCLUDED +#include +#include "amount.pb.h" +#include "recipient.pb.h" +#include "order.pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Struct definitions */ +typedef struct _waves_CreateAliasTransactionData { + pb_callback_t alias; +} waves_CreateAliasTransactionData; + +typedef struct _waves_DataTransactionData { + char dummy_field; +} waves_DataTransactionData; + +typedef struct _waves_ExchangeTransactionData { + char dummy_field; +} waves_ExchangeTransactionData; + +typedef struct _waves_GenesisTransactionData { + char dummy_field; +} waves_GenesisTransactionData; + +typedef struct _waves_LeaseCancelTransactionData { + pb_callback_t lease_id; +} waves_LeaseCancelTransactionData; + +typedef struct _waves_MassTransferTransactionData { + pb_callback_t asset_id; + pb_callback_t attachment; +} waves_MassTransferTransactionData; + +typedef struct _waves_PaymentTransactionData { + char dummy_field; +} waves_PaymentTransactionData; + +typedef struct _waves_SetAssetScriptTransactionData { + pb_callback_t asset_id; +} waves_SetAssetScriptTransactionData; + +typedef struct _waves_SetScriptTransactionData { + char dummy_field; +} waves_SetScriptTransactionData; + +typedef struct _waves_UpdateAssetInfoTransactionData { + pb_callback_t asset_id; + pb_callback_t name; + pb_callback_t description; +} waves_UpdateAssetInfoTransactionData; + +typedef struct _waves_BurnTransactionData { + bool has_asset_amount; + waves_Amount asset_amount; +} waves_BurnTransactionData; + +typedef struct _waves_InvokeScriptTransactionData { + bool has_d_app; + waves_Recipient d_app; + pb_callback_t function_call; + pb_size_t payments_count; + waves_Amount payments[2]; +} waves_InvokeScriptTransactionData; + +typedef struct _waves_IssueTransactionData { + pb_callback_t name; + pb_callback_t description; + int64_t amount; + int32_t decimals; + bool reissuable; + pb_callback_t script; +} waves_IssueTransactionData; + +typedef struct _waves_LeaseTransactionData { + bool has_recipient; + waves_Recipient recipient; + int64_t amount; +} waves_LeaseTransactionData; + +typedef struct _waves_ReissueTransactionData { + bool has_asset_amount; + waves_Amount asset_amount; + bool reissuable; +} waves_ReissueTransactionData; + +typedef struct _waves_SponsorFeeTransactionData { + bool has_min_fee; + waves_Amount min_fee; +} waves_SponsorFeeTransactionData; + +typedef struct _waves_TransferTransactionData { + bool has_recipient; + waves_Recipient recipient; + bool has_amount; + waves_Amount amount; + pb_callback_t attachment; +} waves_TransferTransactionData; + +typedef struct _waves_Transaction { + pb_callback_t sender_public_key; + pb_callback_t cb_fee; + bool has_fee; + waves_Amount fee; + pb_callback_t cb_data; + pb_size_t which_data; + union { + waves_GenesisTransactionData genesis; + waves_PaymentTransactionData payment; + waves_IssueTransactionData issue; + waves_TransferTransactionData transfer; + waves_ReissueTransactionData reissue; + waves_BurnTransactionData burn; + waves_ExchangeTransactionData exchange; + waves_LeaseTransactionData lease; + waves_LeaseCancelTransactionData lease_cancel; + waves_CreateAliasTransactionData create_alias; + waves_MassTransferTransactionData mass_transfer; + waves_DataTransactionData data_transaction; + waves_SetScriptTransactionData set_script; + waves_SponsorFeeTransactionData sponsor_fee; + waves_SetAssetScriptTransactionData set_asset_script; + waves_InvokeScriptTransactionData invoke_script; + waves_UpdateAssetInfoTransactionData update_asset_info; + } data; +} waves_Transaction; + +typedef struct _waves_SignedTransaction { + bool has_transaction; + waves_Transaction transaction; + pb_callback_t proofs; +} waves_SignedTransaction; + + +/* Initializer values for message structs */ +#define waves_SignedTransaction_init_default {false, waves_Transaction_init_default, {{NULL}, NULL}} +#define waves_Transaction_init_default {{{NULL}, NULL}, {{NULL}, NULL}, false, waves_Amount_init_default, {{NULL}, NULL}, 0, {waves_GenesisTransactionData_init_default}} +#define waves_GenesisTransactionData_init_default {0} +#define waves_PaymentTransactionData_init_default {0} +#define waves_TransferTransactionData_init_default {false, waves_Recipient_init_default, false, waves_Amount_init_default, {{NULL}, NULL}} +#define waves_CreateAliasTransactionData_init_default {{{NULL}, NULL}} +#define waves_DataTransactionData_init_default {0} +#define waves_MassTransferTransactionData_init_default {{{NULL}, NULL}, {{NULL}, NULL}} +#define waves_LeaseTransactionData_init_default {false, waves_Recipient_init_default, 0} +#define waves_LeaseCancelTransactionData_init_default {{{NULL}, NULL}} +#define waves_BurnTransactionData_init_default {false, waves_Amount_init_default} +#define waves_IssueTransactionData_init_default {{{NULL}, NULL}, {{NULL}, NULL}, 0, 0, 0, {{NULL}, NULL}} +#define waves_ReissueTransactionData_init_default {false, waves_Amount_init_default, 0} +#define waves_SetAssetScriptTransactionData_init_default {{{NULL}, NULL}} +#define waves_SetScriptTransactionData_init_default {0} +#define waves_ExchangeTransactionData_init_default {0} +#define waves_SponsorFeeTransactionData_init_default {false, waves_Amount_init_default} +#define waves_InvokeScriptTransactionData_init_default {false, waves_Recipient_init_default, {{NULL}, NULL}, 0, {waves_Amount_init_default, waves_Amount_init_default}} +#define waves_UpdateAssetInfoTransactionData_init_default {{{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}} +#define waves_SignedTransaction_init_zero {false, waves_Transaction_init_zero, {{NULL}, NULL}} +#define waves_Transaction_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, false, waves_Amount_init_zero, {{NULL}, NULL}, 0, {waves_GenesisTransactionData_init_zero}} +#define waves_GenesisTransactionData_init_zero {0} +#define waves_PaymentTransactionData_init_zero {0} +#define waves_TransferTransactionData_init_zero {false, waves_Recipient_init_zero, false, waves_Amount_init_zero, {{NULL}, NULL}} +#define waves_CreateAliasTransactionData_init_zero {{{NULL}, NULL}} +#define waves_DataTransactionData_init_zero {0} +#define waves_MassTransferTransactionData_init_zero {{{NULL}, NULL}, {{NULL}, NULL}} +#define waves_LeaseTransactionData_init_zero {false, waves_Recipient_init_zero, 0} +#define waves_LeaseCancelTransactionData_init_zero {{{NULL}, NULL}} +#define waves_BurnTransactionData_init_zero {false, waves_Amount_init_zero} +#define waves_IssueTransactionData_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, 0, 0, 0, {{NULL}, NULL}} +#define waves_ReissueTransactionData_init_zero {false, waves_Amount_init_zero, 0} +#define waves_SetAssetScriptTransactionData_init_zero {{{NULL}, NULL}} +#define waves_SetScriptTransactionData_init_zero {0} +#define waves_ExchangeTransactionData_init_zero {0} +#define waves_SponsorFeeTransactionData_init_zero {false, waves_Amount_init_zero} +#define waves_InvokeScriptTransactionData_init_zero {false, waves_Recipient_init_zero, {{NULL}, NULL}, 0, {waves_Amount_init_zero, waves_Amount_init_zero}} +#define waves_UpdateAssetInfoTransactionData_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}} + +/* Field tags (for use in manual encoding/decoding) */ +#define waves_CreateAliasTransactionData_alias_tag 1 +#define waves_LeaseCancelTransactionData_lease_id_tag 1 +#define waves_MassTransferTransactionData_asset_id_tag 1 +#define waves_MassTransferTransactionData_attachment_tag 3 +#define waves_SetAssetScriptTransactionData_asset_id_tag 1 +#define waves_UpdateAssetInfoTransactionData_asset_id_tag 1 +#define waves_UpdateAssetInfoTransactionData_name_tag 2 +#define waves_UpdateAssetInfoTransactionData_description_tag 3 +#define waves_BurnTransactionData_asset_amount_tag 1 +#define waves_InvokeScriptTransactionData_d_app_tag 1 +#define waves_InvokeScriptTransactionData_function_call_tag 2 +#define waves_InvokeScriptTransactionData_payments_tag 3 +#define waves_IssueTransactionData_name_tag 1 +#define waves_IssueTransactionData_description_tag 2 +#define waves_IssueTransactionData_amount_tag 3 +#define waves_IssueTransactionData_decimals_tag 4 +#define waves_IssueTransactionData_reissuable_tag 5 +#define waves_IssueTransactionData_script_tag 6 +#define waves_LeaseTransactionData_recipient_tag 1 +#define waves_LeaseTransactionData_amount_tag 2 +#define waves_ReissueTransactionData_asset_amount_tag 1 +#define waves_ReissueTransactionData_reissuable_tag 2 +#define waves_SponsorFeeTransactionData_min_fee_tag 1 +#define waves_TransferTransactionData_recipient_tag 1 +#define waves_TransferTransactionData_amount_tag 2 +#define waves_TransferTransactionData_attachment_tag 3 +#define waves_Transaction_genesis_tag 101 +#define waves_Transaction_payment_tag 102 +#define waves_Transaction_issue_tag 103 +#define waves_Transaction_transfer_tag 104 +#define waves_Transaction_reissue_tag 105 +#define waves_Transaction_burn_tag 106 +#define waves_Transaction_exchange_tag 107 +#define waves_Transaction_lease_tag 108 +#define waves_Transaction_lease_cancel_tag 109 +#define waves_Transaction_create_alias_tag 110 +#define waves_Transaction_mass_transfer_tag 111 +#define waves_Transaction_data_transaction_tag 112 +#define waves_Transaction_set_script_tag 113 +#define waves_Transaction_sponsor_fee_tag 114 +#define waves_Transaction_set_asset_script_tag 115 +#define waves_Transaction_invoke_script_tag 116 +#define waves_Transaction_update_asset_info_tag 117 +#define waves_Transaction_sender_public_key_tag 2 +#define waves_Transaction_fee_tag 3 +#define waves_SignedTransaction_transaction_tag 1 +#define waves_SignedTransaction_proofs_tag 2 + +/* Struct field encoding specification for nanopb */ +#define waves_SignedTransaction_FIELDLIST(X, a) \ +X(a, STATIC, OPTIONAL, MESSAGE, transaction, 1) \ +X(a, CALLBACK, REPEATED, BYTES, proofs, 2) +#define waves_SignedTransaction_CALLBACK pb_default_field_callback +#define waves_SignedTransaction_DEFAULT NULL +#define waves_SignedTransaction_transaction_MSGTYPE waves_Transaction + +#define waves_Transaction_FIELDLIST(X, a) \ +X(a, CALLBACK, SINGULAR, BYTES, sender_public_key, 2) \ +X(a, STATIC, OPTIONAL, MSG_W_CB, fee, 3) \ +X(a, STATIC, ONEOF, MSG_W_CB, (data,genesis,data.genesis), 101) \ +X(a, STATIC, ONEOF, MSG_W_CB, (data,payment,data.payment), 102) \ +X(a, STATIC, ONEOF, MSG_W_CB, (data,issue,data.issue), 103) \ +X(a, STATIC, ONEOF, MSG_W_CB, (data,transfer,data.transfer), 104) \ +X(a, STATIC, ONEOF, MSG_W_CB, (data,reissue,data.reissue), 105) \ +X(a, STATIC, ONEOF, MSG_W_CB, (data,burn,data.burn), 106) \ +X(a, STATIC, ONEOF, MSG_W_CB, (data,exchange,data.exchange), 107) \ +X(a, STATIC, ONEOF, MSG_W_CB, (data,lease,data.lease), 108) \ +X(a, STATIC, ONEOF, MSG_W_CB, (data,lease_cancel,data.lease_cancel), 109) \ +X(a, STATIC, ONEOF, MSG_W_CB, (data,create_alias,data.create_alias), 110) \ +X(a, STATIC, ONEOF, MSG_W_CB, (data,mass_transfer,data.mass_transfer), 111) \ +X(a, STATIC, ONEOF, MSG_W_CB, (data,data_transaction,data.data_transaction), 112) \ +X(a, STATIC, ONEOF, MSG_W_CB, (data,set_script,data.set_script), 113) \ +X(a, STATIC, ONEOF, MSG_W_CB, (data,sponsor_fee,data.sponsor_fee), 114) \ +X(a, STATIC, ONEOF, MSG_W_CB, (data,set_asset_script,data.set_asset_script), 115) \ +X(a, STATIC, ONEOF, MSG_W_CB, (data,invoke_script,data.invoke_script), 116) \ +X(a, STATIC, ONEOF, MSG_W_CB, (data,update_asset_info,data.update_asset_info), 117) +#define waves_Transaction_CALLBACK pb_default_field_callback +#define waves_Transaction_DEFAULT NULL +#define waves_Transaction_fee_MSGTYPE waves_Amount +#define waves_Transaction_data_genesis_MSGTYPE waves_GenesisTransactionData +#define waves_Transaction_data_payment_MSGTYPE waves_PaymentTransactionData +#define waves_Transaction_data_issue_MSGTYPE waves_IssueTransactionData +#define waves_Transaction_data_transfer_MSGTYPE waves_TransferTransactionData +#define waves_Transaction_data_reissue_MSGTYPE waves_ReissueTransactionData +#define waves_Transaction_data_burn_MSGTYPE waves_BurnTransactionData +#define waves_Transaction_data_exchange_MSGTYPE waves_ExchangeTransactionData +#define waves_Transaction_data_lease_MSGTYPE waves_LeaseTransactionData +#define waves_Transaction_data_lease_cancel_MSGTYPE waves_LeaseCancelTransactionData +#define waves_Transaction_data_create_alias_MSGTYPE waves_CreateAliasTransactionData +#define waves_Transaction_data_mass_transfer_MSGTYPE waves_MassTransferTransactionData +#define waves_Transaction_data_data_transaction_MSGTYPE waves_DataTransactionData +#define waves_Transaction_data_set_script_MSGTYPE waves_SetScriptTransactionData +#define waves_Transaction_data_sponsor_fee_MSGTYPE waves_SponsorFeeTransactionData +#define waves_Transaction_data_set_asset_script_MSGTYPE waves_SetAssetScriptTransactionData +#define waves_Transaction_data_invoke_script_MSGTYPE waves_InvokeScriptTransactionData +#define waves_Transaction_data_update_asset_info_MSGTYPE waves_UpdateAssetInfoTransactionData + +#define waves_GenesisTransactionData_FIELDLIST(X, a) \ + +#define waves_GenesisTransactionData_CALLBACK NULL +#define waves_GenesisTransactionData_DEFAULT NULL + +#define waves_PaymentTransactionData_FIELDLIST(X, a) \ + +#define waves_PaymentTransactionData_CALLBACK NULL +#define waves_PaymentTransactionData_DEFAULT NULL + +#define waves_TransferTransactionData_FIELDLIST(X, a) \ +X(a, STATIC, OPTIONAL, MESSAGE, recipient, 1) \ +X(a, STATIC, OPTIONAL, MESSAGE, amount, 2) \ +X(a, CALLBACK, SINGULAR, BYTES, attachment, 3) +#define waves_TransferTransactionData_CALLBACK pb_default_field_callback +#define waves_TransferTransactionData_DEFAULT NULL +#define waves_TransferTransactionData_recipient_MSGTYPE waves_Recipient +#define waves_TransferTransactionData_amount_MSGTYPE waves_Amount + +#define waves_CreateAliasTransactionData_FIELDLIST(X, a) \ +X(a, CALLBACK, SINGULAR, STRING, alias, 1) +#define waves_CreateAliasTransactionData_CALLBACK pb_default_field_callback +#define waves_CreateAliasTransactionData_DEFAULT NULL + +#define waves_DataTransactionData_FIELDLIST(X, a) \ + +#define waves_DataTransactionData_CALLBACK NULL +#define waves_DataTransactionData_DEFAULT NULL + +#define waves_MassTransferTransactionData_FIELDLIST(X, a) \ +X(a, CALLBACK, SINGULAR, BYTES, asset_id, 1) \ +X(a, CALLBACK, SINGULAR, BYTES, attachment, 3) +#define waves_MassTransferTransactionData_CALLBACK pb_default_field_callback +#define waves_MassTransferTransactionData_DEFAULT NULL + +#define waves_LeaseTransactionData_FIELDLIST(X, a) \ +X(a, STATIC, OPTIONAL, MESSAGE, recipient, 1) \ +X(a, STATIC, SINGULAR, INT64, amount, 2) +#define waves_LeaseTransactionData_CALLBACK NULL +#define waves_LeaseTransactionData_DEFAULT NULL +#define waves_LeaseTransactionData_recipient_MSGTYPE waves_Recipient + +#define waves_LeaseCancelTransactionData_FIELDLIST(X, a) \ +X(a, CALLBACK, SINGULAR, BYTES, lease_id, 1) +#define waves_LeaseCancelTransactionData_CALLBACK pb_default_field_callback +#define waves_LeaseCancelTransactionData_DEFAULT NULL + +#define waves_BurnTransactionData_FIELDLIST(X, a) \ +X(a, STATIC, OPTIONAL, MESSAGE, asset_amount, 1) +#define waves_BurnTransactionData_CALLBACK NULL +#define waves_BurnTransactionData_DEFAULT NULL +#define waves_BurnTransactionData_asset_amount_MSGTYPE waves_Amount + +#define waves_IssueTransactionData_FIELDLIST(X, a) \ +X(a, CALLBACK, SINGULAR, STRING, name, 1) \ +X(a, CALLBACK, SINGULAR, STRING, description, 2) \ +X(a, STATIC, SINGULAR, INT64, amount, 3) \ +X(a, STATIC, SINGULAR, INT32, decimals, 4) \ +X(a, STATIC, SINGULAR, BOOL, reissuable, 5) \ +X(a, CALLBACK, SINGULAR, BYTES, script, 6) +#define waves_IssueTransactionData_CALLBACK pb_default_field_callback +#define waves_IssueTransactionData_DEFAULT NULL + +#define waves_ReissueTransactionData_FIELDLIST(X, a) \ +X(a, STATIC, OPTIONAL, MESSAGE, asset_amount, 1) \ +X(a, STATIC, SINGULAR, BOOL, reissuable, 2) +#define waves_ReissueTransactionData_CALLBACK NULL +#define waves_ReissueTransactionData_DEFAULT NULL +#define waves_ReissueTransactionData_asset_amount_MSGTYPE waves_Amount + +#define waves_SetAssetScriptTransactionData_FIELDLIST(X, a) \ +X(a, CALLBACK, SINGULAR, BYTES, asset_id, 1) +#define waves_SetAssetScriptTransactionData_CALLBACK pb_default_field_callback +#define waves_SetAssetScriptTransactionData_DEFAULT NULL + +#define waves_SetScriptTransactionData_FIELDLIST(X, a) \ + +#define waves_SetScriptTransactionData_CALLBACK NULL +#define waves_SetScriptTransactionData_DEFAULT NULL + +#define waves_ExchangeTransactionData_FIELDLIST(X, a) \ + +#define waves_ExchangeTransactionData_CALLBACK NULL +#define waves_ExchangeTransactionData_DEFAULT NULL + +#define waves_SponsorFeeTransactionData_FIELDLIST(X, a) \ +X(a, STATIC, OPTIONAL, MESSAGE, min_fee, 1) +#define waves_SponsorFeeTransactionData_CALLBACK NULL +#define waves_SponsorFeeTransactionData_DEFAULT NULL +#define waves_SponsorFeeTransactionData_min_fee_MSGTYPE waves_Amount + +#define waves_InvokeScriptTransactionData_FIELDLIST(X, a) \ +X(a, STATIC, OPTIONAL, MESSAGE, d_app, 1) \ +X(a, CALLBACK, SINGULAR, BYTES, function_call, 2) \ +X(a, STATIC, REPEATED, MESSAGE, payments, 3) +#define waves_InvokeScriptTransactionData_CALLBACK pb_default_field_callback +#define waves_InvokeScriptTransactionData_DEFAULT NULL +#define waves_InvokeScriptTransactionData_d_app_MSGTYPE waves_Recipient +#define waves_InvokeScriptTransactionData_payments_MSGTYPE waves_Amount + +#define waves_UpdateAssetInfoTransactionData_FIELDLIST(X, a) \ +X(a, CALLBACK, SINGULAR, BYTES, asset_id, 1) \ +X(a, CALLBACK, SINGULAR, STRING, name, 2) \ +X(a, CALLBACK, SINGULAR, STRING, description, 3) +#define waves_UpdateAssetInfoTransactionData_CALLBACK pb_default_field_callback +#define waves_UpdateAssetInfoTransactionData_DEFAULT NULL + +extern const pb_msgdesc_t waves_SignedTransaction_msg; +extern const pb_msgdesc_t waves_Transaction_msg; +extern const pb_msgdesc_t waves_GenesisTransactionData_msg; +extern const pb_msgdesc_t waves_PaymentTransactionData_msg; +extern const pb_msgdesc_t waves_TransferTransactionData_msg; +extern const pb_msgdesc_t waves_CreateAliasTransactionData_msg; +extern const pb_msgdesc_t waves_DataTransactionData_msg; +extern const pb_msgdesc_t waves_MassTransferTransactionData_msg; +extern const pb_msgdesc_t waves_LeaseTransactionData_msg; +extern const pb_msgdesc_t waves_LeaseCancelTransactionData_msg; +extern const pb_msgdesc_t waves_BurnTransactionData_msg; +extern const pb_msgdesc_t waves_IssueTransactionData_msg; +extern const pb_msgdesc_t waves_ReissueTransactionData_msg; +extern const pb_msgdesc_t waves_SetAssetScriptTransactionData_msg; +extern const pb_msgdesc_t waves_SetScriptTransactionData_msg; +extern const pb_msgdesc_t waves_ExchangeTransactionData_msg; +extern const pb_msgdesc_t waves_SponsorFeeTransactionData_msg; +extern const pb_msgdesc_t waves_InvokeScriptTransactionData_msg; +extern const pb_msgdesc_t waves_UpdateAssetInfoTransactionData_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define waves_SignedTransaction_fields &waves_SignedTransaction_msg +#define waves_Transaction_fields &waves_Transaction_msg +#define waves_GenesisTransactionData_fields &waves_GenesisTransactionData_msg +#define waves_PaymentTransactionData_fields &waves_PaymentTransactionData_msg +#define waves_TransferTransactionData_fields &waves_TransferTransactionData_msg +#define waves_CreateAliasTransactionData_fields &waves_CreateAliasTransactionData_msg +#define waves_DataTransactionData_fields &waves_DataTransactionData_msg +#define waves_MassTransferTransactionData_fields &waves_MassTransferTransactionData_msg +#define waves_LeaseTransactionData_fields &waves_LeaseTransactionData_msg +#define waves_LeaseCancelTransactionData_fields &waves_LeaseCancelTransactionData_msg +#define waves_BurnTransactionData_fields &waves_BurnTransactionData_msg +#define waves_IssueTransactionData_fields &waves_IssueTransactionData_msg +#define waves_ReissueTransactionData_fields &waves_ReissueTransactionData_msg +#define waves_SetAssetScriptTransactionData_fields &waves_SetAssetScriptTransactionData_msg +#define waves_SetScriptTransactionData_fields &waves_SetScriptTransactionData_msg +#define waves_ExchangeTransactionData_fields &waves_ExchangeTransactionData_msg +#define waves_SponsorFeeTransactionData_fields &waves_SponsorFeeTransactionData_msg +#define waves_InvokeScriptTransactionData_fields &waves_InvokeScriptTransactionData_msg +#define waves_UpdateAssetInfoTransactionData_fields &waves_UpdateAssetInfoTransactionData_msg + +/* Maximum encoded size of messages (where known) */ +/* waves_SignedTransaction_size depends on runtime parameters */ +/* waves_Transaction_size depends on runtime parameters */ +#define waves_GenesisTransactionData_size 0 +#define waves_PaymentTransactionData_size 0 +/* waves_TransferTransactionData_size depends on runtime parameters */ +/* waves_CreateAliasTransactionData_size depends on runtime parameters */ +#define waves_DataTransactionData_size 0 +/* waves_MassTransferTransactionData_size depends on runtime parameters */ +#define waves_LeaseTransactionData_size 45 +/* waves_LeaseCancelTransactionData_size depends on runtime parameters */ +#define waves_BurnTransactionData_size (6 + waves_Amount_size) +/* waves_IssueTransactionData_size depends on runtime parameters */ +#define waves_ReissueTransactionData_size (8 + waves_Amount_size) +/* waves_SetAssetScriptTransactionData_size depends on runtime parameters */ +#define waves_SetScriptTransactionData_size 0 +#define waves_ExchangeTransactionData_size 0 +#define waves_SponsorFeeTransactionData_size (6 + waves_Amount_size) +/* waves_InvokeScriptTransactionData_size depends on runtime parameters */ +/* waves_UpdateAssetInfoTransactionData_size depends on runtime parameters */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/ui/blue/ui_menus_blue.h b/src/ui/blue/ui_menus_blue.h index d55a61fe..97a386d7 100644 --- a/src/ui/blue/ui_menus_blue.h +++ b/src/ui/blue/ui_menus_blue.h @@ -23,8 +23,10 @@ #include "os.h" #include "cx.h" +#include "ux.h" #include "../ui_logic.h" +////////////////////////////////////////////////////////////////////////////// const bagl_element_t ui_idle_blue[] = { // type userid x y w h str rad // fill fg bg fid iid txt touchparams... ] @@ -114,7 +116,7 @@ const bagl_element_t ui_idle_blue[] = { NULL, NULL}, }; - +////////////////////////////////////////////////////////////////////////////// const bagl_element_t ui_verify_transfer_blue[] = { {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, 0x000000, 0, 0}, @@ -200,7 +202,7 @@ const bagl_element_t ui_verify_transfer_blue[] = { {{BAGL_LABEL, 0x10, 130, 140, 160, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, - (const char *)ui_context.line1, + (const char *)tmp_ctx.signing_context.ui.line1, 0, 0, 0, @@ -231,7 +233,7 @@ const bagl_element_t ui_verify_transfer_blue[] = { {{BAGL_LABEL, 0x11, 130, 166, 160, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, - (const char *)ui_context.line2, + (const char *)tmp_ctx.signing_context.ui.line2, 0, 0, 0, @@ -262,7 +264,7 @@ const bagl_element_t ui_verify_transfer_blue[] = { {{BAGL_LABEL, 0x11, 130, 192, 160, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, - (const char *)ui_context.line3, + (const char *)tmp_ctx.signing_context.ui.line3, 0, 0, 0, @@ -293,7 +295,7 @@ const bagl_element_t ui_verify_transfer_blue[] = { {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, - (const char *)ui_context.line4, + (const char *)tmp_ctx.signing_context.ui.fee_amount, 0, 0, 0, @@ -324,7 +326,7 @@ const bagl_element_t ui_verify_transfer_blue[] = { {{BAGL_LABEL, 0x11, 130, 244, 160, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, - (const char *)ui_context.line5, + (const char *)tmp_ctx.signing_context.ui.fee_asset, 0, 0, 0, @@ -355,7 +357,7 @@ const bagl_element_t ui_verify_transfer_blue[] = { {{BAGL_LABEL, 0x11, 130, 270, 160, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, - (const char *)ui_context.line6, + (const char *)tmp_ctx.signing_context.ui.line4, 0, 0, 0, @@ -386,7 +388,7 @@ const bagl_element_t ui_verify_transfer_blue[] = { {{BAGL_LABEL, 0x11, 130, 296, 160, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, - (const char *)ui_context.line7, + (const char *)tmp_ctx.signing_context.ui.from, 0, 0, 0, @@ -417,7 +419,7 @@ const bagl_element_t ui_verify_transfer_blue[] = { {{BAGL_LABEL, 0x11, 130, 322, 160, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, - (const char *)ui_context.line8, + (const char *)tmp_ctx.signing_context.first_data_hash, 0, 0, 0, @@ -462,7 +464,9 @@ const bagl_element_t ui_verify_transfer_blue[] = { }; -const bagl_element_t ui_approval_blue[] = { +////////////////////////////////////////////////////////////////////////////// + +const bagl_element_t ui_verify_data_blue[] = { {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, 0x000000, 0, 0}, NULL, @@ -496,7 +500,7 @@ const bagl_element_t ui_approval_blue[] = { NULL}, // BADGE_TRANSACTION.GIF - {{BAGL_ICON, 0x40, 30, 98, 50, 50, 0, 0, BAGL_FILL, 0, COLOR_BG_1, 0, 0}, + {{BAGL_ICON, 0x40, 30, 75, 50, 50, 0, 0, BAGL_FILL, 0, COLOR_BG_1, 0, 0}, &C_badge_transaction, 0, 0, @@ -505,7 +509,7 @@ const bagl_element_t ui_approval_blue[] = { NULL, NULL}, - {{BAGL_LABELINE, 0x50, 100, 117, 320, 30, 0, 0, BAGL_FILL, 0x000000, + {{BAGL_LABELINE, 0x50, 100, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, "Confirm", 0, @@ -514,9 +518,9 @@ const bagl_element_t ui_approval_blue[] = { NULL, NULL, NULL}, - {{BAGL_LABELINE, 0x50, 154, 117, 320, 30, 0, 0, BAGL_FILL, 0x000000, + {{BAGL_LABELINE, 0x50, 154, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, - (const char *)ui_context.line1, + "Data Transaction", 0, 0, 0, @@ -524,7 +528,7 @@ const bagl_element_t ui_approval_blue[] = { NULL, NULL}, - {{BAGL_LABELINE, 0x00, 100, 138, 320, 30, 0, 0, BAGL_FILL, 0x999999, + {{BAGL_LABELINE, 0x00, 100, 115, 320, 30, 0, 0, BAGL_FILL, 0x999999, COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_8_11PX, 0}, "Check and confirm data", 0, @@ -534,9 +538,9 @@ const bagl_element_t ui_approval_blue[] = { NULL, NULL}, - {{BAGL_LABELINE, 0x70, 30, 196, 100, 30, 0, 0, BAGL_FILL, 0x000000, - COLOR_BG_1, BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, - (const char *)ui_context.line2, + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee", 0, 0, 0, @@ -544,10 +548,20 @@ const bagl_element_t ui_approval_blue[] = { NULL, NULL}, // x-18 when ... - {{BAGL_LABELINE, 0x10, 130, 200, 160, 30, 0, 0, BAGL_FILL, 0x000000, - COLOR_BG_1, BAGL_FONT_OPEN_SANS_LIGHT_16_22PX | BAGL_FONT_ALIGNMENT_RIGHT, + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_amount, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, 0}, - (const char *)ui_context.line3, + NULL, 0, 0, 0, @@ -555,7 +569,28 @@ const bagl_element_t ui_approval_blue[] = { NULL, NULL}, - {{BAGL_RECTANGLE, 0x31, 30, 216, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + {{BAGL_LABEL, 0x71, 30, 244, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 244, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_asset, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 257, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, 0}, NULL, 0, @@ -565,9 +600,9 @@ const bagl_element_t ui_approval_blue[] = { NULL, NULL}, - {{BAGL_LABELINE, 0x71, 30, 245, 100, 30, 0, 0, BAGL_FILL, 0x000000, - COLOR_BG_1, BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, - "Sender", + {{BAGL_LABEL, 0x71, 30, 296, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "From", 0, 0, 0, @@ -575,10 +610,51 @@ const bagl_element_t ui_approval_blue[] = { NULL, NULL}, // x-18 when ... - {{BAGL_LABELINE, 0x11, 130, 245, 160, 30, 0, 0, BAGL_FILL, 0x000000, + {{BAGL_LABEL, 0x11, 130, 296, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.from, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 309, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 322, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Transaction ID", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 322, 160, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, - (const char *)ui_context.line4, + (const char *)tmp_ctx.signing_context.first_data_hash, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 335, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, 0, 0, 0, @@ -613,7 +689,9 @@ const bagl_element_t ui_approval_blue[] = { }; -const bagl_element_t ui_address_blue[] = { +////////////////////////////////////////////////////////////////////////////// + +const bagl_element_t ui_verify_issue_blue[] = { {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, 0x000000, 0, 0}, NULL, @@ -636,9 +714,9 @@ const bagl_element_t ui_address_blue[] = { NULL}, /// TOP STATUS BAR - {{BAGL_LABELINE, 0x00, 0, 45, 320, 30, 0, 0, BAGL_FILL, 0xFFFFFF, COLOR_APP, + {{BAGL_LABELINE, 0x60, 0, 45, 320, 30, 0, 0, BAGL_FILL, 0xFFFFFF, COLOR_APP, BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX | BAGL_FONT_ALIGNMENT_CENTER, 0}, - "CONFIRM ACCOUNT", + "CONFIRM SIGNATURE", 0, 0, 0, @@ -646,9 +724,9 @@ const bagl_element_t ui_address_blue[] = { NULL, NULL}, - {{BAGL_LABELINE, 0x00, 30, 106, 320, 30, 0, 0, BAGL_FILL, 0x999999, - COLOR_BG_1, BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, - "ACCOUNT", + // BADGE_TRANSACTION.GIF + {{BAGL_ICON, 0x40, 30, 75, 50, 50, 0, 0, BAGL_FILL, 0, COLOR_BG_1, 0, 0}, + &C_badge_transaction, 0, 0, 0, @@ -656,9 +734,18 @@ const bagl_element_t ui_address_blue[] = { NULL, NULL}, - {{BAGL_LABELINE, 0x10, 30, 136, 260, 30, 0, 0, BAGL_FILL, 0x000000, + {{BAGL_LABELINE, 0x50, 100, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, - (const char *)tmp_ctx.address_context.address, + "Confirm", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + {{BAGL_LABELINE, 0x50, 154, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Asset issue", 0, 0, 0, @@ -666,36 +753,61 @@ const bagl_element_t ui_address_blue[] = { NULL, NULL}, - {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 40, 414, 115, 36, 0, 18, - BAGL_FILL, 0xCCCCCC, COLOR_BG_1, - BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | - BAGL_FONT_ALIGNMENT_MIDDLE, - 0}, - "REJECT", + {{BAGL_LABELINE, 0x00, 100, 115, 320, 30, 0, 0, BAGL_FILL, 0x999999, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_8_11PX, 0}, + "Check and confirm data", + 0, + 0, 0, - 0xB7B7B7, - COLOR_BG_1, - io_seproxyhal_cancel, + NULL, NULL, NULL}, - {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 165, 414, 115, 36, 0, 18, - BAGL_FILL, 0x41ccb4, COLOR_BG_1, - BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | - BAGL_FONT_ALIGNMENT_MIDDLE, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Name", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line1, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, 0}, - "CONFIRM", + NULL, 0, - 0x3ab7a2, - COLOR_BG_1, - io_seproxyhal_touch_address_ok, + 0, + 0, + NULL, NULL, NULL}, -}; -const bagl_element_t ui_processing_blue[] = { - {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, - 0x000000, 0, 0}, + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Description", + 0, + 0, + 0, NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line2, 0, 0, 0, @@ -703,9 +815,8 @@ const bagl_element_t ui_processing_blue[] = { NULL, NULL}, - // erase screen (only under the status bar) - {{BAGL_RECTANGLE, 0x00, 0, 20, 320, 48, 0, 0, BAGL_FILL, COLOR_APP, - COLOR_APP, 0, 0}, + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, NULL, 0, 0, @@ -714,10 +825,20 @@ const bagl_element_t ui_processing_blue[] = { NULL, NULL}, - /// TOP STATUS BAR - {{BAGL_LABELINE, 0x60, 0, 45, 320, 30, 0, 0, BAGL_FILL, 0xFFFFFF, COLOR_APP, - BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX | BAGL_FONT_ALIGNMENT_CENTER, 0}, - "PROCESSING", + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Amount", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line3, 0, 0, 0, @@ -725,10 +846,30 @@ const bagl_element_t ui_processing_blue[] = { NULL, NULL}, - {{BAGL_LABELINE, 0x00, 0, 270, 320, 30, 0, 0, BAGL_FILL, 0x000000, + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Decimals", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, - BAGL_FONT_OPEN_SANS_LIGHT_16_22PX | BAGL_FONT_ALIGNMENT_CENTER, 0}, - "Processing...", + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line4, 0, 0, 0, @@ -736,26 +877,4062 @@ const bagl_element_t ui_processing_blue[] = { NULL, NULL}, -}; + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, -unsigned int ui_idle_blue_button(unsigned int button_mask, - unsigned int button_mask_counter) { - return 0; -} -unsigned int ui_address_blue_button(unsigned int button_mask, - unsigned int button_mask_counter) { - return 0; -} -unsigned int ui_verify_transfer_blue_button(unsigned int button_mask, - unsigned int button_mask_counter) { - return 0; -} -unsigned int ui_approval_blue_button(unsigned int button_mask, - unsigned int button_mask_counter) { - return 0; -} -unsigned int ui_processing_blue_button(unsigned int button_mask, - unsigned int button_mask_counter) { + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Reissuable", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line5, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "hasScript", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line6, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_amount, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 244, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 244, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_asset, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 257, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 296, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "From", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 296, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.from, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 309, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 322, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Transaction ID", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 322, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.first_data_hash, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 335, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 40, 414, 115, 36, 0, 18, + BAGL_FILL, 0xCCCCCC, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "REJECT", + 0, + 0xB7B7B7, + COLOR_BG_1, + io_seproxyhal_cancel, + NULL, + NULL}, + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 165, 414, 115, 36, 0, 18, + BAGL_FILL, 0x41ccb4, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "CONFIRM", + 0, + 0x3ab7a2, + COLOR_BG_1, + io_seproxyhal_touch_sign_approve, + NULL, + NULL}, + +}; + +////////////////////////////////////////////////////////////////////////////// + +const bagl_element_t ui_verify_reissue_blue[] = { + {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, + 0x000000, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // erase screen (only under the status bar) + {{BAGL_RECTANGLE, 0x00, 0, 20, 320, 48, 0, 0, BAGL_FILL, COLOR_APP, + COLOR_APP, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + /// TOP STATUS BAR + {{BAGL_LABELINE, 0x60, 0, 45, 320, 30, 0, 0, BAGL_FILL, 0xFFFFFF, COLOR_APP, + BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX | BAGL_FONT_ALIGNMENT_CENTER, 0}, + "CONFIRM SIGNATURE", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // BADGE_TRANSACTION.GIF + {{BAGL_ICON, 0x40, 30, 75, 50, 50, 0, 0, BAGL_FILL, 0, COLOR_BG_1, 0, 0}, + &C_badge_transaction, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x50, 100, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Confirm", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + {{BAGL_LABELINE, 0x50, 154, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Asset reissue", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x00, 100, 115, 320, 30, 0, 0, BAGL_FILL, 0x999999, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_8_11PX, 0}, + "Check and confirm data", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Amount", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line1, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line2, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Reissuable", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line3, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_amount, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 244, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 244, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_asset, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 257, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 296, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "From", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 296, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.from, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 309, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 322, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Transaction ID", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 322, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.first_data_hash, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 335, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 40, 414, 115, 36, 0, 18, + BAGL_FILL, 0xCCCCCC, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "REJECT", + 0, + 0xB7B7B7, + COLOR_BG_1, + io_seproxyhal_cancel, + NULL, + NULL}, + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 165, 414, 115, 36, 0, 18, + BAGL_FILL, 0x41ccb4, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "CONFIRM", + 0, + 0x3ab7a2, + COLOR_BG_1, + io_seproxyhal_touch_sign_approve, + NULL, + NULL}, + +}; + +////////////////////////////////////////////////////////////////////////////// + +const bagl_element_t ui_verify_burn_blue[] = { + {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, + 0x000000, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // erase screen (only under the status bar) + {{BAGL_RECTANGLE, 0x00, 0, 20, 320, 48, 0, 0, BAGL_FILL, COLOR_APP, + COLOR_APP, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + /// TOP STATUS BAR + {{BAGL_LABELINE, 0x60, 0, 45, 320, 30, 0, 0, BAGL_FILL, 0xFFFFFF, COLOR_APP, + BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX | BAGL_FONT_ALIGNMENT_CENTER, 0}, + "CONFIRM SIGNATURE", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // BADGE_TRANSACTION.GIF + {{BAGL_ICON, 0x40, 30, 75, 50, 50, 0, 0, BAGL_FILL, 0, COLOR_BG_1, 0, 0}, + &C_badge_transaction, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x50, 100, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Confirm", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + {{BAGL_LABELINE, 0x50, 154, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Asset burn", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x00, 100, 115, 320, 30, 0, 0, BAGL_FILL, 0x999999, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_8_11PX, 0}, + "Check and confirm data", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Amount", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line1, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line2, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_amount, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 244, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 244, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_asset, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 257, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 296, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "From", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 296, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.from, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 309, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 322, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Transaction ID", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 322, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.first_data_hash, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 335, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 40, 414, 115, 36, 0, 18, + BAGL_FILL, 0xCCCCCC, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "REJECT", + 0, + 0xB7B7B7, + COLOR_BG_1, + io_seproxyhal_cancel, + NULL, + NULL}, + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 165, 414, 115, 36, 0, 18, + BAGL_FILL, 0x41ccb4, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "CONFIRM", + 0, + 0x3ab7a2, + COLOR_BG_1, + io_seproxyhal_touch_sign_approve, + NULL, + NULL}, + +}; + +////////////////////////////////////////////////////////////////////////////// + +const bagl_element_t ui_verify_lease_blue[] = { + {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, + 0x000000, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // erase screen (only under the status bar) + {{BAGL_RECTANGLE, 0x00, 0, 20, 320, 48, 0, 0, BAGL_FILL, COLOR_APP, + COLOR_APP, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + /// TOP STATUS BAR + {{BAGL_LABELINE, 0x60, 0, 45, 320, 30, 0, 0, BAGL_FILL, 0xFFFFFF, COLOR_APP, + BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX | BAGL_FONT_ALIGNMENT_CENTER, 0}, + "CONFIRM SIGNATURE", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // BADGE_TRANSACTION.GIF + {{BAGL_ICON, 0x40, 30, 75, 50, 50, 0, 0, BAGL_FILL, 0, COLOR_BG_1, 0, 0}, + &C_badge_transaction, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x50, 100, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Confirm", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + {{BAGL_LABELINE, 0x50, 154, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Asset leasing", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x00, 100, 115, 320, 30, 0, 0, BAGL_FILL, 0x999999, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_8_11PX, 0}, + "Check and confirm data", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Amount", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line1, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "To", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line3, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_amount, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 244, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 244, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_asset, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 257, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 296, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "From", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 296, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.from, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 309, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 322, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Transaction ID", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 322, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.first_data_hash, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 335, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 40, 414, 115, 36, 0, 18, + BAGL_FILL, 0xCCCCCC, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "REJECT", + 0, + 0xB7B7B7, + COLOR_BG_1, + io_seproxyhal_cancel, + NULL, + NULL}, + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 165, 414, 115, 36, 0, 18, + BAGL_FILL, 0x41ccb4, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "CONFIRM", + 0, + 0x3ab7a2, + COLOR_BG_1, + io_seproxyhal_touch_sign_approve, + NULL, + NULL}, + +}; + +////////////////////////////////////////////////////////////////////////////// + +const bagl_element_t ui_verify_cancel_lease_blue[] = { + {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, + 0x000000, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // erase screen (only under the status bar) + {{BAGL_RECTANGLE, 0x00, 0, 20, 320, 48, 0, 0, BAGL_FILL, COLOR_APP, + COLOR_APP, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + /// TOP STATUS BAR + {{BAGL_LABELINE, 0x60, 0, 45, 320, 30, 0, 0, BAGL_FILL, 0xFFFFFF, COLOR_APP, + BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX | BAGL_FONT_ALIGNMENT_CENTER, 0}, + "CONFIRM SIGNATURE", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // BADGE_TRANSACTION.GIF + {{BAGL_ICON, 0x40, 30, 75, 50, 50, 0, 0, BAGL_FILL, 0, COLOR_BG_1, 0, 0}, + &C_badge_transaction, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x50, 100, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Confirm", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + {{BAGL_LABELINE, 0x50, 154, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Asset leasing cancel", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x00, 100, 115, 320, 30, 0, 0, BAGL_FILL, 0x999999, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_8_11PX, 0}, + "Check and confirm data", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Lease id", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line1, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_amount, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 244, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 244, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_asset, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 257, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 296, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "From", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 296, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.from, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 309, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 322, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Transaction ID", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 322, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.first_data_hash, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 335, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 40, 414, 115, 36, 0, 18, + BAGL_FILL, 0xCCCCCC, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "REJECT", + 0, + 0xB7B7B7, + COLOR_BG_1, + io_seproxyhal_cancel, + NULL, + NULL}, + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 165, 414, 115, 36, 0, 18, + BAGL_FILL, 0x41ccb4, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "CONFIRM", + 0, + 0x3ab7a2, + COLOR_BG_1, + io_seproxyhal_touch_sign_approve, + NULL, + NULL}, + +}; + +////////////////////////////////////////////////////////////////////////////// + +const bagl_element_t ui_verify_create_alias_blue[] = { + {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, + 0x000000, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // erase screen (only under the status bar) + {{BAGL_RECTANGLE, 0x00, 0, 20, 320, 48, 0, 0, BAGL_FILL, COLOR_APP, + COLOR_APP, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + /// TOP STATUS BAR + {{BAGL_LABELINE, 0x60, 0, 45, 320, 30, 0, 0, BAGL_FILL, 0xFFFFFF, COLOR_APP, + BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX | BAGL_FONT_ALIGNMENT_CENTER, 0}, + "CONFIRM SIGNATURE", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // BADGE_TRANSACTION.GIF + {{BAGL_ICON, 0x40, 30, 75, 50, 50, 0, 0, BAGL_FILL, 0, COLOR_BG_1, 0, 0}, + &C_badge_transaction, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x50, 100, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Confirm", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + {{BAGL_LABELINE, 0x50, 154, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Creating alias", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x00, 100, 115, 320, 30, 0, 0, BAGL_FILL, 0x999999, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_8_11PX, 0}, + "Check and confirm data", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Alias", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line1, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_amount, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 244, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 244, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_asset, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 257, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 296, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "From", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 296, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.from, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 309, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 322, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Transaction ID", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 322, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.first_data_hash, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 335, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 40, 414, 115, 36, 0, 18, + BAGL_FILL, 0xCCCCCC, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "REJECT", + 0, + 0xB7B7B7, + COLOR_BG_1, + io_seproxyhal_cancel, + NULL, + NULL}, + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 165, 414, 115, 36, 0, 18, + BAGL_FILL, 0x41ccb4, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "CONFIRM", + 0, + 0x3ab7a2, + COLOR_BG_1, + io_seproxyhal_touch_sign_approve, + NULL, + NULL}, + +}; + +////////////////////////////////////////////////////////////////////////////// + +const bagl_element_t ui_verify_masstransfer_blue[] = { + {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, + 0x000000, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // erase screen (only under the status bar) + {{BAGL_RECTANGLE, 0x00, 0, 20, 320, 48, 0, 0, BAGL_FILL, COLOR_APP, + COLOR_APP, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + /// TOP STATUS BAR + {{BAGL_LABELINE, 0x60, 0, 45, 320, 30, 0, 0, BAGL_FILL, 0xFFFFFF, COLOR_APP, + BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX | BAGL_FONT_ALIGNMENT_CENTER, 0}, + "CONFIRM SIGNATURE", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // BADGE_TRANSACTION.GIF + {{BAGL_ICON, 0x40, 30, 75, 50, 50, 0, 0, BAGL_FILL, 0, COLOR_BG_1, 0, 0}, + &C_badge_transaction, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x50, 100, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Confirm", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + {{BAGL_LABELINE, 0x50, 154, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Mass Transfer", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x00, 100, 115, 320, 30, 0, 0, BAGL_FILL, 0x999999, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_8_11PX, 0}, + "Check and confirm data", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 166, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 166, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line1, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 179, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_amount, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 244, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 244, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_asset, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 257, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 270, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Attachment", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 270, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line2, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 283, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 296, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "From", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 296, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.from, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 309, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 322, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Transaction ID", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 322, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.first_data_hash, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 335, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 40, 414, 115, 36, 0, 18, + BAGL_FILL, 0xCCCCCC, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "REJECT", + 0, + 0xB7B7B7, + COLOR_BG_1, + io_seproxyhal_cancel, + NULL, + NULL}, + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 165, 414, 115, 36, 0, 18, + BAGL_FILL, 0x41ccb4, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "CONFIRM", + 0, + 0x3ab7a2, + COLOR_BG_1, + io_seproxyhal_touch_sign_approve, + NULL, + NULL}, + +}; + +////////////////////////////////////////////////////////////////////////////// + +const bagl_element_t ui_verify_set_ac_script_blue[] = { + {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, + 0x000000, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // erase screen (only under the status bar) + {{BAGL_RECTANGLE, 0x00, 0, 20, 320, 48, 0, 0, BAGL_FILL, COLOR_APP, + COLOR_APP, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + /// TOP STATUS BAR + {{BAGL_LABELINE, 0x60, 0, 45, 320, 30, 0, 0, BAGL_FILL, 0xFFFFFF, COLOR_APP, + BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX | BAGL_FONT_ALIGNMENT_CENTER, 0}, + "CONFIRM SIGNATURE", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // BADGE_TRANSACTION.GIF + {{BAGL_ICON, 0x40, 30, 75, 50, 50, 0, 0, BAGL_FILL, 0, COLOR_BG_1, 0, 0}, + &C_badge_transaction, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x50, 100, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Confirm", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + {{BAGL_LABELINE, 0x50, 154, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Set account script", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x00, 100, 115, 320, 30, 0, 0, BAGL_FILL, 0x999999, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_8_11PX, 0}, + "Check and confirm data", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_amount, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 244, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 244, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_asset, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 257, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 296, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "From", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 296, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.from, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 309, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 322, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Transaction ID", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 322, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.first_data_hash, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 335, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 40, 414, 115, 36, 0, 18, + BAGL_FILL, 0xCCCCCC, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "REJECT", + 0, + 0xB7B7B7, + COLOR_BG_1, + io_seproxyhal_cancel, + NULL, + NULL}, + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 165, 414, 115, 36, 0, 18, + BAGL_FILL, 0x41ccb4, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "CONFIRM", + 0, + 0x3ab7a2, + COLOR_BG_1, + io_seproxyhal_touch_sign_approve, + NULL, + NULL}, + +}; + +////////////////////////////////////////////////////////////////////////////// + +const bagl_element_t ui_verify_sponsorship_blue[] = { + {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, + 0x000000, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // erase screen (only under the status bar) + {{BAGL_RECTANGLE, 0x00, 0, 20, 320, 48, 0, 0, BAGL_FILL, COLOR_APP, + COLOR_APP, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + /// TOP STATUS BAR + {{BAGL_LABELINE, 0x60, 0, 45, 320, 30, 0, 0, BAGL_FILL, 0xFFFFFF, COLOR_APP, + BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX | BAGL_FONT_ALIGNMENT_CENTER, 0}, + "CONFIRM SIGNATURE", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // BADGE_TRANSACTION.GIF + {{BAGL_ICON, 0x40, 30, 75, 50, 50, 0, 0, BAGL_FILL, 0, COLOR_BG_1, 0, 0}, + &C_badge_transaction, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x50, 100, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Confirm", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + {{BAGL_LABELINE, 0x50, 154, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Fee sponsoring", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x00, 100, 115, 320, 30, 0, 0, BAGL_FILL, 0x999999, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_8_11PX, 0}, + "Check and confirm data", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Amount", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line1, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line2, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_amount, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 244, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 244, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_asset, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 257, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 296, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "From", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 296, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.from, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 309, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 322, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Transaction ID", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 322, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.first_data_hash, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 335, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 40, 414, 115, 36, 0, 18, + BAGL_FILL, 0xCCCCCC, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "REJECT", + 0, + 0xB7B7B7, + COLOR_BG_1, + io_seproxyhal_cancel, + NULL, + NULL}, + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 165, 414, 115, 36, 0, 18, + BAGL_FILL, 0x41ccb4, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "CONFIRM", + 0, + 0x3ab7a2, + COLOR_BG_1, + io_seproxyhal_touch_sign_approve, + NULL, + NULL}, + +}; + +////////////////////////////////////////////////////////////////////////////// + +const bagl_element_t ui_verify_set_as_script_blue[] = { + {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, + 0x000000, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // erase screen (only under the status bar) + {{BAGL_RECTANGLE, 0x00, 0, 20, 320, 48, 0, 0, BAGL_FILL, COLOR_APP, + COLOR_APP, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + /// TOP STATUS BAR + {{BAGL_LABELINE, 0x60, 0, 45, 320, 30, 0, 0, BAGL_FILL, 0xFFFFFF, COLOR_APP, + BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX | BAGL_FONT_ALIGNMENT_CENTER, 0}, + "CONFIRM SIGNATURE", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // BADGE_TRANSACTION.GIF + {{BAGL_ICON, 0x40, 30, 75, 50, 50, 0, 0, BAGL_FILL, 0, COLOR_BG_1, 0, 0}, + &C_badge_transaction, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x50, 100, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Confirm", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + {{BAGL_LABELINE, 0x50, 154, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Set asset script", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x00, 100, 115, 320, 30, 0, 0, BAGL_FILL, 0x999999, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_8_11PX, 0}, + "Check and confirm data", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line1, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_amount, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 244, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 244, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_asset, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 257, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 296, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "From", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 296, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.from, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 309, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 322, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Transaction ID", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 322, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.first_data_hash, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 335, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 40, 414, 115, 36, 0, 18, + BAGL_FILL, 0xCCCCCC, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "REJECT", + 0, + 0xB7B7B7, + COLOR_BG_1, + io_seproxyhal_cancel, + NULL, + NULL}, + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 165, 414, 115, 36, 0, 18, + BAGL_FILL, 0x41ccb4, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "CONFIRM", + 0, + 0x3ab7a2, + COLOR_BG_1, + io_seproxyhal_touch_sign_approve, + NULL, + NULL}, + +}; + +////////////////////////////////////////////////////////////////////////////// + +const bagl_element_t ui_verify_update_asset_blue[] = { + {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, + 0x000000, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // erase screen (only under the status bar) + {{BAGL_RECTANGLE, 0x00, 0, 20, 320, 48, 0, 0, BAGL_FILL, COLOR_APP, + COLOR_APP, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + /// TOP STATUS BAR + {{BAGL_LABELINE, 0x60, 0, 45, 320, 30, 0, 0, BAGL_FILL, 0xFFFFFF, COLOR_APP, + BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX | BAGL_FONT_ALIGNMENT_CENTER, 0}, + "CONFIRM SIGNATURE", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // BADGE_TRANSACTION.GIF + {{BAGL_ICON, 0x40, 30, 75, 50, 50, 0, 0, BAGL_FILL, 0, COLOR_BG_1, 0, 0}, + &C_badge_transaction, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x50, 100, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Confirm", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + {{BAGL_LABELINE, 0x50, 154, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Update asset info", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x00, 100, 115, 320, 30, 0, 0, BAGL_FILL, 0x999999, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_8_11PX, 0}, + "Check and confirm data", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line1, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Name", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line2, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Description", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line4, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_amount, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 244, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 244, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_asset, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 257, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 296, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "From", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 296, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.from, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 309, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 322, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Transaction ID", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 322, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.first_data_hash, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 335, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 40, 414, 115, 36, 0, 18, + BAGL_FILL, 0xCCCCCC, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "REJECT", + 0, + 0xB7B7B7, + COLOR_BG_1, + io_seproxyhal_cancel, + NULL, + NULL}, + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 165, 414, 115, 36, 0, 18, + BAGL_FILL, 0x41ccb4, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "CONFIRM", + 0, + 0x3ab7a2, + COLOR_BG_1, + io_seproxyhal_touch_sign_approve, + NULL, + NULL}, + +}; + +////////////////////////////////////////////////////////////////////////////// + +const bagl_element_t ui_verify_invoke_blue[] = { + {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, + 0x000000, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // erase screen (only under the status bar) + {{BAGL_RECTANGLE, 0x00, 0, 20, 320, 48, 0, 0, BAGL_FILL, COLOR_APP, + COLOR_APP, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + /// TOP STATUS BAR + {{BAGL_LABELINE, 0x60, 0, 45, 320, 30, 0, 0, BAGL_FILL, 0xFFFFFF, COLOR_APP, + BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX | BAGL_FONT_ALIGNMENT_CENTER, 0}, + "CONFIRM SIGNATURE", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // BADGE_TRANSACTION.GIF + {{BAGL_ICON, 0x40, 30, 75, 50, 50, 0, 0, BAGL_FILL, 0, COLOR_BG_1, 0, 0}, + &C_badge_transaction, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x50, 100, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Confirm", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + {{BAGL_LABELINE, 0x50, 154, 94, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Script invocation", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x00, 100, 115, 320, 30, 0, 0, BAGL_FILL, 0x999999, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_8_11PX, 0}, + "Check and confirm data", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "dApp", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line3, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Function", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line2, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Payment 1 amount", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line4, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Payment 1 asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line1, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Payment 2 amount", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line6, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Payment 2 asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line5, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_amount, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 244, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 244, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_asset, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 257, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 296, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "From", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 296, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.from, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 309, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 322, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Transaction ID", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 322, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.first_data_hash, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 335, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 40, 414, 115, 36, 0, 18, + BAGL_FILL, 0xCCCCCC, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "REJECT", + 0, + 0xB7B7B7, + COLOR_BG_1, + io_seproxyhal_cancel, + NULL, + NULL}, + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 165, 414, 115, 36, 0, 18, + BAGL_FILL, 0x41ccb4, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "CONFIRM", + 0, + 0x3ab7a2, + COLOR_BG_1, + io_seproxyhal_touch_sign_approve, + NULL, + NULL}, + +}; + +////////////////////////////////////////////////////////////////////////////// + +const bagl_element_t ui_approval_blue[] = { + {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, + 0x000000, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // erase screen (only under the status bar) + {{BAGL_RECTANGLE, 0x00, 0, 20, 320, 48, 0, 0, BAGL_FILL, COLOR_APP, + COLOR_APP, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + /// TOP STATUS BAR + {{BAGL_LABELINE, 0x60, 0, 45, 320, 30, 0, 0, BAGL_FILL, 0xFFFFFF, COLOR_APP, + BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX | BAGL_FONT_ALIGNMENT_CENTER, 0}, + "CONFIRM SIGNATURE", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // BADGE_TRANSACTION.GIF + {{BAGL_ICON, 0x40, 30, 98, 50, 50, 0, 0, BAGL_FILL, 0, COLOR_BG_1, 0, 0}, + &C_badge_transaction, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x50, 100, 117, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Confirm", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + {{BAGL_LABELINE, 0x50, 154, 117, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + (const char *)tmp_ctx.signing_context.ui.line1, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x00, 100, 138, 320, 30, 0, 0, BAGL_FILL, 0x999999, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_8_11PX, 0}, + "Check and confirm data", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x70, 30, 196, 100, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + (const char *)tmp_ctx.signing_context.ui.line2, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABELINE, 0x10, 130, 200, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_LIGHT_16_22PX | BAGL_FONT_ALIGNMENT_RIGHT, + 0}, + (const char *)tmp_ctx.signing_context.first_data_hash, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 216, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x71, 30, 245, 100, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Sender", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABELINE, 0x11, 130, 245, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.from, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 40, 414, 115, 36, 0, 18, + BAGL_FILL, 0xCCCCCC, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "REJECT", + 0, + 0xB7B7B7, + COLOR_BG_1, + io_seproxyhal_cancel, + NULL, + NULL}, + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 165, 414, 115, 36, 0, 18, + BAGL_FILL, 0x41ccb4, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "CONFIRM", + 0, + 0x3ab7a2, + COLOR_BG_1, + io_seproxyhal_touch_sign_approve, + NULL, + NULL}, + +}; + +////////////////////////////////////////////////////////////////////////////// + +const bagl_element_t ui_verify_order_blue[] = { + {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, + 0x000000, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // erase screen (only under the status bar) + {{BAGL_RECTANGLE, 0x00, 0, 20, 320, 48, 0, 0, BAGL_FILL, COLOR_APP, + COLOR_APP, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + /// TOP STATUS BAR + {{BAGL_LABELINE, 0x60, 0, 45, 320, 30, 0, 0, BAGL_FILL, 0xFFFFFF, COLOR_APP, + BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX | BAGL_FONT_ALIGNMENT_CENTER, 0}, + "CONFIRM SIGNATURE", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // BADGE_TRANSACTION.GIF + {{BAGL_ICON, 0x40, 30, 98, 50, 50, 0, 0, BAGL_FILL, 0, COLOR_BG_1, 0, 0}, + &C_badge_transaction, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x50, 100, 117, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + "Confirm", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + {{BAGL_LABELINE, 0x50, 154, 117, 320, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + (const char *)tmp_ctx.signing_context.ui.line3, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x00, 100, 115, 320, 30, 0, 0, BAGL_FILL, 0x999999, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_8_11PX, 0}, + "Check and confirm data", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Amount", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line4, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Amount asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line1, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "From", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.from, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Matcher", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.line2, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 218, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Matcher Fee", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 218, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_amount, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 231, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 244, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Fee asset", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 244, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.ui.fee_asset, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 257, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABEL, 0x71, 30, 322, 100, 30, 0, 0, BAGL_FILL, 0x000000, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "Hash", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + // x-18 when ... + {{BAGL_LABEL, 0x11, 130, 322, 160, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_10_13PX | BAGL_FONT_ALIGNMENT_RIGHT, 0}, + (const char *)tmp_ctx.signing_context.first_data_hash, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE, 0x31, 30, 335, 260, 1, 1, 0, 0, 0xEEEEEE, COLOR_BG_1, 0, + 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 40, 414, 115, 36, 0, 18, + BAGL_FILL, 0xCCCCCC, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "REJECT", + 0, + 0xB7B7B7, + COLOR_BG_1, + io_seproxyhal_cancel, + NULL, + NULL}, + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 165, 414, 115, 36, 0, 18, + BAGL_FILL, 0x41ccb4, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "CONFIRM", + 0, + 0x3ab7a2, + COLOR_BG_1, + io_seproxyhal_touch_sign_approve, + NULL, + NULL}, + +}; + +////////////////////////////////////////////////////////////////////////////// + +const bagl_element_t ui_address_blue[] = { + {{BAGL_RECTANGLE, 0x00, 0, 68, 320, 413, 0, 0, BAGL_FILL, COLOR_BG_1, + 0x000000, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + // erase screen (only under the status bar) + {{BAGL_RECTANGLE, 0x00, 0, 20, 320, 48, 0, 0, BAGL_FILL, COLOR_APP, + COLOR_APP, 0, 0}, + NULL, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + /// TOP STATUS BAR + {{BAGL_LABELINE, 0x00, 0, 45, 320, 30, 0, 0, BAGL_FILL, 0xFFFFFF, COLOR_APP, + BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX | BAGL_FONT_ALIGNMENT_CENTER, 0}, + "CONFIRM ACCOUNT", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x00, 30, 106, 320, 30, 0, 0, BAGL_FILL, 0x999999, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX, 0}, + "ACCOUNT", + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_LABELINE, 0x10, 30, 136, 260, 30, 0, 0, BAGL_FILL, 0x000000, + COLOR_BG_1, BAGL_FONT_OPEN_SANS_REGULAR_10_13PX, 0}, + (const char *)tmp_ctx.address_context.address, + 0, + 0, + 0, + NULL, + NULL, + NULL}, + + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 40, 414, 115, 36, 0, 18, + BAGL_FILL, 0xCCCCCC, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "REJECT", + 0, + 0xB7B7B7, + COLOR_BG_1, + io_seproxyhal_cancel, + NULL, + NULL}, + {{BAGL_RECTANGLE | BAGL_FLAG_TOUCHABLE, 0x00, 165, 414, 115, 36, 0, 18, + BAGL_FILL, 0x41ccb4, COLOR_BG_1, + BAGL_FONT_OPEN_SANS_REGULAR_11_14PX | BAGL_FONT_ALIGNMENT_CENTER | + BAGL_FONT_ALIGNMENT_MIDDLE, + 0}, + "CONFIRM", + 0, + 0x3ab7a2, + COLOR_BG_1, + io_seproxyhal_touch_address_ok, + NULL, + NULL}, +}; + +unsigned int ui_idle_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { + return 0; +} + +unsigned int ui_address_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { + return 0; +} + +unsigned int ui_verify_transfer_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { + return 0; +} + +unsigned int ui_verify_data_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { + return 0; +} + +unsigned int ui_verify_issue_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { + return 0; +} + +unsigned int ui_verify_reissue_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { + return 0; +} + +unsigned int ui_verify_burn_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { + return 0; +} + +unsigned int ui_verify_lease_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { + return 0; +} + +unsigned int +ui_verify_cancel_lease_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { + return 0; +} + +unsigned int +ui_verify_create_alias_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { + return 0; +} + +unsigned int +ui_verify_masstransfer_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { + return 0; +} + +unsigned int +ui_verify_set_ac_script_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { + return 0; +} + +unsigned int +ui_verify_sponsorship_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { + return 0; +} + +unsigned int +ui_verify_set_as_script_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { + return 0; +} + +unsigned int ui_verify_invoke_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { + return 0; +} + +unsigned int +ui_verify_update_asset_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { + return 0; +} + +unsigned int ui_verify_order_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { + return 0; +} + +unsigned int ui_approval_blue_button(unsigned int button_mask, + unsigned int button_mask_counter) { return 0; } diff --git a/src/ui/blue/ui_menus_blue_prepro.c b/src/ui/blue/ui_menus_blue_prepro.c index 78e95698..bc337e07 100644 --- a/src/ui/blue/ui_menus_blue_prepro.c +++ b/src/ui/blue/ui_menus_blue_prepro.c @@ -21,6 +21,7 @@ #include "ui_menus_blue_prepro.h" #include "../ui.h" +#include "ux.h" const bagl_element_t *ui_address_blue_prepro(const bagl_element_t *element) { return element; diff --git a/src/ui/blue/ui_menus_blue_prepro.h b/src/ui/blue/ui_menus_blue_prepro.h index befe4ea5..3c717690 100644 --- a/src/ui/blue/ui_menus_blue_prepro.h +++ b/src/ui/blue/ui_menus_blue_prepro.h @@ -22,6 +22,7 @@ #define __UI_MENUS_BLUE_PREPRO_H__ #include "os_io_seproxyhal.h" +#include "ux.h" const bagl_element_t *ui_address_blue_prepro(const bagl_element_t *element); const bagl_element_t *ui_idle_blue_prepro(const bagl_element_t *element); diff --git a/src/ui/nanox/ui_menus_nanox.h b/src/ui/nanox/ui_menus_nanox.h index 931554b5..e424a327 100644 --- a/src/ui/nanox/ui_menus_nanox.h +++ b/src/ui/nanox/ui_menus_nanox.h @@ -24,6 +24,7 @@ #include "os.h" #include "cx.h" +#include "ux.h" #include "../ui_logic.h" ////////////////////////////////////////////////////////////////////// @@ -90,50 +91,51 @@ void display_if_buffer_not_empty(const char *buffer, size_t buffer_len) { UX_STEP_NOCB(ux_transfer_1_step, pnn, { &C_icon_eye, - "Review", - "transfer", + "Confirm", + "Transfer", }); UX_STEP_NOCB(ux_transfer_2_step, bnnn_paging, { .title = "Amount", - .text = (const char *)ui_context.line1, + .text = (const char *)tmp_ctx.signing_context.ui.line1, }); UX_STEP_NOCB(ux_transfer_3_step, bnnn_paging, { .title = "Asset", - .text = (const char *)ui_context.line2, + .text = (const char *)tmp_ctx.signing_context.ui.line2, }); UX_STEP_NOCB(ux_transfer_4_step, bnnn_paging, { .title = "To", - .text = (const char *)ui_context.line3, + .text = (const char *)tmp_ctx.signing_context.ui.line3, }); UX_STEP_NOCB(ux_transfer_5_step, bnnn_paging, { .title = "Fee", - .text = (const char *)ui_context.line4, + .text = (const char *)tmp_ctx.signing_context.ui.fee_amount, }); UX_STEP_NOCB(ux_transfer_6_step, bnnn_paging, { .title = "Fee asset", - .text = (const char *)ui_context.line5, - }); -UX_STEP_NOCB_INIT(ux_transfer_7_step, bnnn_paging, - display_if_buffer_not_empty((const char *)ui_context.line6, - sizeof(ui_context.line6)), - { - .title = "Attachment", - .text = (const char *)ui_context.line6, - }); + .text = (const char *)tmp_ctx.signing_context.ui.fee_asset, + }); +UX_STEP_NOCB_INIT( + ux_transfer_7_step, bnnn_paging, + display_if_buffer_not_empty((const char *)tmp_ctx.signing_context.ui.line4, + sizeof(tmp_ctx.signing_context.ui.line4)), + { + .title = "Attachment", + .text = (const char *)tmp_ctx.signing_context.ui.line4, + }); UX_STEP_NOCB(ux_transfer_8_step, bnnn_paging, { .title = "From", - .text = (const char *)ui_context.line7, + .text = (const char *)tmp_ctx.signing_context.ui.from, }); UX_STEP_NOCB(ux_transfer_9_step, bnnn_paging, { .title = "Transaction Id", - .text = (const char *)ui_context.line8, + .text = (const char *)tmp_ctx.signing_context.first_data_hash, }); UX_STEP_VALID(ux_transfer_10_step, pbb, io_seproxyhal_touch_sign_approve(NULL), { @@ -154,17 +156,840 @@ UX_FLOW(ux_transfer_flow, &ux_transfer_1_step, &ux_transfer_2_step, ////////////////////////////////////////////////////////////////////// +UX_STEP_NOCB(ux_data_1_step, pnn, + { + &C_icon_eye, + "Confirm", + "Data transaction", + }); +UX_STEP_NOCB(ux_data_2_step, bnnn_paging, + { + .title = "Fee", + .text = (const char *)tmp_ctx.signing_context.ui.fee_amount, + }); +UX_STEP_NOCB(ux_data_3_step, bnnn_paging, + { + .title = "Fee asset", + .text = (const char *)tmp_ctx.signing_context.ui.fee_asset, + }); +UX_STEP_NOCB(ux_data_4_step, bnnn_paging, + { + .title = "From", + .text = (const char *)tmp_ctx.signing_context.ui.from, + }); + +UX_STEP_NOCB(ux_data_5_step, bnnn_paging, + { + .title = "Transaction Id", + .text = (const char *)tmp_ctx.signing_context.first_data_hash, + }); +UX_STEP_VALID(ux_data_6_step, pbb, io_seproxyhal_touch_sign_approve(NULL), + { + &C_icon_validate_14, + "Accept", + "and send", + }); +UX_STEP_VALID(ux_data_7_step, pb, io_seproxyhal_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +UX_FLOW(ux_data_flow, &ux_data_1_step, &ux_data_2_step, &ux_data_3_step, + &ux_data_4_step, &ux_data_5_step, &ux_data_6_step, &ux_data_7_step); + +////////////////////////////////////////////////////////////////////// + +UX_STEP_NOCB(ux_issue_1_step, pnn, + { + &C_icon_eye, + "Confirm", + "Asset issue", + }); +UX_STEP_NOCB(ux_issue_2_step, bnnn_paging, + { + .title = "Name", + .text = (const char *)tmp_ctx.signing_context.ui.line1, + }); +UX_STEP_NOCB(ux_issue_3_step, bnnn_paging, + { + .title = "Description", + .text = (const char *)tmp_ctx.signing_context.ui.line2, + }); +UX_STEP_NOCB(ux_issue_4_step, bnnn_paging, + { + .title = "Amount", + .text = (const char *)tmp_ctx.signing_context.ui.line3, + }); +UX_STEP_NOCB(ux_issue_5_step, bnnn_paging, + { + .title = "Decimals", + .text = (const char *)tmp_ctx.signing_context.ui.line4, + }); +UX_STEP_NOCB(ux_issue_6_step, bnnn_paging, + { + .title = "Reissuable", + .text = (const char *)tmp_ctx.signing_context.ui.line5, + }); +UX_STEP_NOCB(ux_issue_7_step, bnnn_paging, + { + .title = "hasScript", + .text = (const char *)tmp_ctx.signing_context.ui.line6, + }); +UX_STEP_NOCB(ux_issue_8_step, bnnn_paging, + { + .title = "Fee", + .text = (const char *)tmp_ctx.signing_context.ui.fee_amount, + }); +UX_STEP_NOCB(ux_issue_9_step, bnnn_paging, + { + .title = "Fee asset", + .text = (const char *)tmp_ctx.signing_context.ui.fee_asset, + }); +UX_STEP_NOCB(ux_issue_10_step, bnnn_paging, + { + .title = "From", + .text = (const char *)tmp_ctx.signing_context.ui.from, + }); + +UX_STEP_NOCB(ux_issue_11_step, bnnn_paging, + { + .title = "Transaction Id", + .text = (const char *)tmp_ctx.signing_context.first_data_hash, + }); +UX_STEP_VALID(ux_issue_12_step, pbb, io_seproxyhal_touch_sign_approve(NULL), + { + &C_icon_validate_14, + "Accept", + "and send", + }); +UX_STEP_VALID(ux_issue_13_step, pb, io_seproxyhal_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +UX_FLOW(ux_issue_flow, &ux_issue_1_step, &ux_issue_2_step, &ux_issue_3_step, + &ux_issue_4_step, &ux_issue_5_step, &ux_issue_6_step, &ux_issue_7_step, + &ux_issue_8_step, &ux_issue_9_step, &ux_issue_10_step, + &ux_issue_11_step, &ux_issue_12_step, &ux_issue_13_step); + +////////////////////////////////////////////////////////////////////// + +UX_STEP_NOCB(ux_reissue_1_step, pnn, + { + &C_icon_eye, + "Confirm", + "Asset reissue", + }); +UX_STEP_NOCB(ux_reissue_2_step, bnnn_paging, + { + .title = "Amount", + .text = (const char *)tmp_ctx.signing_context.ui.line1, + }); +UX_STEP_NOCB(ux_reissue_3_step, bnnn_paging, + { + .title = "Asset", + .text = (const char *)tmp_ctx.signing_context.ui.line2, + }); +UX_STEP_NOCB(ux_reissue_4_step, bnnn_paging, + { + .title = "Reissuable", + .text = (const char *)tmp_ctx.signing_context.ui.line3, + }); +UX_STEP_NOCB(ux_reissue_5_step, bnnn_paging, + { + .title = "Fee", + .text = (const char *)tmp_ctx.signing_context.ui.fee_amount, + }); +UX_STEP_NOCB(ux_reissue_6_step, bnnn_paging, + { + .title = "Fee asset", + .text = (const char *)tmp_ctx.signing_context.ui.fee_asset, + }); +UX_STEP_NOCB(ux_reissue_7_step, bnnn_paging, + { + .title = "From", + .text = (const char *)tmp_ctx.signing_context.ui.from, + }); + +UX_STEP_NOCB(ux_reissue_8_step, bnnn_paging, + { + .title = "Transaction Id", + .text = (const char *)tmp_ctx.signing_context.first_data_hash, + }); +UX_STEP_VALID(ux_reissue_9_step, pbb, io_seproxyhal_touch_sign_approve(NULL), + { + &C_icon_validate_14, + "Accept", + "and send", + }); +UX_STEP_VALID(ux_reissue_10_step, pb, io_seproxyhal_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +UX_FLOW(ux_reissue_flow, &ux_reissue_1_step, &ux_reissue_2_step, + &ux_reissue_3_step, &ux_reissue_4_step, &ux_reissue_5_step, + &ux_reissue_6_step, &ux_reissue_7_step, &ux_reissue_8_step, + &ux_reissue_9_step, &ux_reissue_10_step); + +////////////////////////////////////////////////////////////////////// + +UX_STEP_NOCB(ux_burn_1_step, pnn, + { + &C_icon_eye, + "Confirm", + "Asset burn", + }); +UX_STEP_NOCB(ux_burn_2_step, bnnn_paging, + { + .title = "Amount", + .text = (const char *)tmp_ctx.signing_context.ui.line1, + }); +UX_STEP_NOCB(ux_burn_3_step, bnnn_paging, + { + .title = "Asset", + .text = (const char *)tmp_ctx.signing_context.ui.line2, + }); +UX_STEP_NOCB(ux_burn_4_step, bnnn_paging, + { + .title = "Fee", + .text = (const char *)tmp_ctx.signing_context.ui.fee_amount, + }); +UX_STEP_NOCB(ux_burn_5_step, bnnn_paging, + { + .title = "Fee asset", + .text = (const char *)tmp_ctx.signing_context.ui.fee_asset, + }); +UX_STEP_NOCB(ux_burn_6_step, bnnn_paging, + { + .title = "From", + .text = (const char *)tmp_ctx.signing_context.ui.from, + }); + +UX_STEP_NOCB(ux_burn_7_step, bnnn_paging, + { + .title = "Transaction Id", + .text = (const char *)tmp_ctx.signing_context.first_data_hash, + }); +UX_STEP_VALID(ux_burn_8_step, pbb, io_seproxyhal_touch_sign_approve(NULL), + { + &C_icon_validate_14, + "Accept", + "and send", + }); +UX_STEP_VALID(ux_burn_9_step, pb, io_seproxyhal_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +UX_FLOW(ux_burn_flow, &ux_burn_1_step, &ux_burn_2_step, &ux_burn_3_step, + &ux_burn_4_step, &ux_burn_5_step, &ux_burn_6_step, &ux_burn_7_step, + &ux_burn_8_step, &ux_burn_9_step); + +////////////////////////////////////////////////////////////////////// + +UX_STEP_NOCB(ux_lease_1_step, pnn, + { + &C_icon_eye, + "Confirm", + "Asset leasing", + }); +UX_STEP_NOCB(ux_lease_2_step, bnnn_paging, + { + .title = "Amount", + .text = (const char *)tmp_ctx.signing_context.ui.line1, + }); +UX_STEP_NOCB(ux_lease_3_step, bnnn_paging, + { + .title = "To", + .text = (const char *)tmp_ctx.signing_context.ui.line3, + }); +UX_STEP_NOCB(ux_lease_4_step, bnnn_paging, + { + .title = "Fee", + .text = (const char *)tmp_ctx.signing_context.ui.fee_amount, + }); +UX_STEP_NOCB(ux_lease_5_step, bnnn_paging, + { + .title = "Fee asset", + .text = (const char *)tmp_ctx.signing_context.ui.fee_asset, + }); +UX_STEP_NOCB(ux_lease_6_step, bnnn_paging, + { + .title = "From", + .text = (const char *)tmp_ctx.signing_context.ui.from, + }); + +UX_STEP_NOCB(ux_lease_7_step, bnnn_paging, + { + .title = "Transaction Id", + .text = (const char *)tmp_ctx.signing_context.first_data_hash, + }); +UX_STEP_VALID(ux_lease_8_step, pbb, io_seproxyhal_touch_sign_approve(NULL), + { + &C_icon_validate_14, + "Accept", + "and send", + }); +UX_STEP_VALID(ux_lease_9_step, pb, io_seproxyhal_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +UX_FLOW(ux_lease_flow, &ux_lease_1_step, &ux_lease_2_step, &ux_lease_3_step, + &ux_lease_4_step, &ux_lease_5_step, &ux_lease_6_step, &ux_lease_7_step, + &ux_lease_8_step, &ux_lease_9_step); + +////////////////////////////////////////////////////////////////////// + +UX_STEP_NOCB(ux_cancel_lease_1_step, pnn, + { + &C_icon_eye, + "Confirm", + "Asset leasing cancel", + }); +UX_STEP_NOCB(ux_cancel_lease_2_step, bnnn_paging, + { + .title = "Lease id", + .text = (const char *)tmp_ctx.signing_context.ui.line1, + }); +UX_STEP_NOCB(ux_cancel_lease_3_step, bnnn_paging, + { + .title = "Fee", + .text = (const char *)tmp_ctx.signing_context.ui.fee_amount, + }); +UX_STEP_NOCB(ux_cancel_lease_4_step, bnnn_paging, + { + .title = "Fee asset", + .text = (const char *)tmp_ctx.signing_context.ui.fee_asset, + }); +UX_STEP_NOCB(ux_cancel_lease_5_step, bnnn_paging, + { + .title = "From", + .text = (const char *)tmp_ctx.signing_context.ui.from, + }); + +UX_STEP_NOCB(ux_cancel_lease_6_step, bnnn_paging, + { + .title = "Transaction Id", + .text = (const char *)tmp_ctx.signing_context.first_data_hash, + }); +UX_STEP_VALID(ux_cancel_lease_7_step, pbb, + io_seproxyhal_touch_sign_approve(NULL), + { + &C_icon_validate_14, + "Accept", + "and send", + }); +UX_STEP_VALID(ux_cancel_lease_8_step, pb, io_seproxyhal_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +UX_FLOW(ux_cancel_lease_flow, &ux_cancel_lease_1_step, &ux_cancel_lease_2_step, + &ux_cancel_lease_3_step, &ux_cancel_lease_4_step, + &ux_cancel_lease_5_step, &ux_cancel_lease_6_step, + &ux_cancel_lease_7_step, &ux_cancel_lease_8_step); + +////////////////////////////////////////////////////////////////////// + +UX_STEP_NOCB(ux_create_alias_1_step, pnn, + { + &C_icon_eye, + "Confirm", + "Creating alias", + }); +UX_STEP_NOCB(ux_create_alias_2_step, bnnn_paging, + { + .title = "Alias", + .text = (const char *)tmp_ctx.signing_context.ui.line1, + }); +UX_STEP_NOCB(ux_create_alias_3_step, bnnn_paging, + { + .title = "Fee", + .text = (const char *)tmp_ctx.signing_context.ui.fee_amount, + }); +UX_STEP_NOCB(ux_create_alias_4_step, bnnn_paging, + { + .title = "Fee asset", + .text = (const char *)tmp_ctx.signing_context.ui.fee_asset, + }); +UX_STEP_NOCB(ux_create_alias_5_step, bnnn_paging, + { + .title = "From", + .text = (const char *)tmp_ctx.signing_context.ui.from, + }); + +UX_STEP_NOCB(ux_create_alias_6_step, bnnn_paging, + { + .title = "Transaction Id", + .text = (const char *)tmp_ctx.signing_context.first_data_hash, + }); +UX_STEP_VALID(ux_create_alias_7_step, pbb, + io_seproxyhal_touch_sign_approve(NULL), + { + &C_icon_validate_14, + "Accept", + "and send", + }); +UX_STEP_VALID(ux_create_alias_8_step, pb, io_seproxyhal_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +UX_FLOW(ux_create_alias_flow, &ux_create_alias_1_step, &ux_create_alias_2_step, + &ux_create_alias_3_step, &ux_create_alias_4_step, + &ux_create_alias_5_step, &ux_create_alias_6_step, + &ux_create_alias_7_step, &ux_create_alias_8_step); + +////////////////////////////////////////////////////////////////////// + +UX_STEP_NOCB(ux_masstransfer_1_step, pnn, + { + &C_icon_eye, + "Confirm", + "Mass transfer", + }); +UX_STEP_NOCB(ux_masstransfer_2_step, bnnn_paging, + { + .title = "Asset", + .text = (const char *)tmp_ctx.signing_context.ui.line1, + }); +UX_STEP_NOCB(ux_masstransfer_3_step, bnnn_paging, + { + .title = "Fee", + .text = (const char *)tmp_ctx.signing_context.ui.fee_amount, + }); +UX_STEP_NOCB(ux_masstransfer_4_step, bnnn_paging, + { + .title = "Fee asset", + .text = (const char *)tmp_ctx.signing_context.ui.fee_asset, + }); +UX_STEP_NOCB_INIT( + ux_masstransfer_5_step, bnnn_paging, + display_if_buffer_not_empty((const char *)tmp_ctx.signing_context.ui.line2, + sizeof(tmp_ctx.signing_context.ui.line2)), + { + .title = "Attachment", + .text = (const char *)tmp_ctx.signing_context.ui.line2, + }); +UX_STEP_NOCB(ux_masstransfer_6_step, bnnn_paging, + { + .title = "From", + .text = (const char *)tmp_ctx.signing_context.ui.from, + }); +UX_STEP_NOCB(ux_masstransfer_7_step, bnnn_paging, + { + .title = "Transaction Id", + .text = (const char *)tmp_ctx.signing_context.first_data_hash, + }); +UX_STEP_VALID(ux_masstransfer_8_step, pbb, + io_seproxyhal_touch_sign_approve(NULL), + { + &C_icon_validate_14, + "Accept", + "and send", + }); +UX_STEP_VALID(ux_masstransfer_9_step, pb, io_seproxyhal_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +UX_FLOW(ux_masstransfer_flow, &ux_masstransfer_1_step, &ux_masstransfer_2_step, + &ux_masstransfer_3_step, &ux_masstransfer_4_step, + &ux_masstransfer_5_step, &ux_masstransfer_6_step, + &ux_masstransfer_7_step, &ux_masstransfer_8_step, + &ux_masstransfer_9_step); + +////////////////////////////////////////////////////////////////////// + +UX_STEP_NOCB(ux_set_ac_script_1_step, pnn, + { + &C_icon_eye, + "Confirm", + "Set account script", + }); +UX_STEP_NOCB(ux_set_ac_script_2_step, bnnn_paging, + { + .title = "Fee", + .text = (const char *)tmp_ctx.signing_context.ui.fee_amount, + }); +UX_STEP_NOCB(ux_set_ac_script_3_step, bnnn_paging, + { + .title = "Fee asset", + .text = (const char *)tmp_ctx.signing_context.ui.fee_asset, + }); +UX_STEP_NOCB(ux_set_ac_script_4_step, bnnn_paging, + { + .title = "From", + .text = (const char *)tmp_ctx.signing_context.ui.from, + }); + +UX_STEP_NOCB(ux_set_ac_script_5_step, bnnn_paging, + { + .title = "Transaction Id", + .text = (const char *)tmp_ctx.signing_context.first_data_hash, + }); +UX_STEP_VALID(ux_set_ac_script_6_step, pbb, + io_seproxyhal_touch_sign_approve(NULL), + { + &C_icon_validate_14, + "Accept", + "and send", + }); +UX_STEP_VALID(ux_set_ac_script_7_step, pb, io_seproxyhal_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +UX_FLOW(ux_set_ac_script_flow, &ux_set_ac_script_1_step, + &ux_set_ac_script_2_step, &ux_set_ac_script_3_step, + &ux_set_ac_script_4_step, &ux_set_ac_script_5_step, + &ux_set_ac_script_6_step, &ux_set_ac_script_7_step); + +////////////////////////////////////////////////////////////////////// + +UX_STEP_NOCB(ux_set_as_script_1_step, pnn, + { + &C_icon_eye, + "Confirm", + "Set asset script", + }); +UX_STEP_NOCB(ux_set_as_script_2_step, bnnn_paging, + { + .title = "Asset", + .text = (const char *)tmp_ctx.signing_context.ui.line1, + }); +UX_STEP_NOCB(ux_set_as_script_3_step, bnnn_paging, + { + .title = "Fee", + .text = (const char *)tmp_ctx.signing_context.ui.fee_amount, + }); +UX_STEP_NOCB(ux_set_as_script_4_step, bnnn_paging, + { + .title = "Fee asset", + .text = (const char *)tmp_ctx.signing_context.ui.fee_asset, + }); +UX_STEP_NOCB(ux_set_as_script_5_step, bnnn_paging, + { + .title = "From", + .text = (const char *)tmp_ctx.signing_context.ui.from, + }); + +UX_STEP_NOCB(ux_set_as_script_6_step, bnnn_paging, + { + .title = "Transaction Id", + .text = (const char *)tmp_ctx.signing_context.first_data_hash, + }); +UX_STEP_VALID(ux_set_as_script_7_step, pbb, + io_seproxyhal_touch_sign_approve(NULL), + { + &C_icon_validate_14, + "Accept", + "and send", + }); +UX_STEP_VALID(ux_set_as_script_8_step, pb, io_seproxyhal_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +UX_FLOW(ux_set_as_script_flow, &ux_set_as_script_1_step, + &ux_set_as_script_2_step, &ux_set_as_script_3_step, + &ux_set_as_script_4_step, &ux_set_as_script_5_step, + &ux_set_as_script_6_step, &ux_set_as_script_7_step, + &ux_set_as_script_8_step); + +////////////////////////////////////////////////////////////////////// + +UX_STEP_NOCB(ux_sponsorship_1_step, pnn, + { + &C_icon_eye, + "Confirm", + "Fee sponsoring", + }); +UX_STEP_NOCB(ux_sponsorship_2_step, bnnn_paging, + { + .title = "Amount", + .text = (const char *)tmp_ctx.signing_context.ui.line1, + }); +UX_STEP_NOCB(ux_sponsorship_3_step, bnnn_paging, + { + .title = "Asset", + .text = (const char *)tmp_ctx.signing_context.ui.line2, + }); +UX_STEP_NOCB(ux_sponsorship_4_step, bnnn_paging, + { + .title = "Fee", + .text = (const char *)tmp_ctx.signing_context.ui.fee_amount, + }); +UX_STEP_NOCB(ux_sponsorship_5_step, bnnn_paging, + { + .title = "Fee asset", + .text = (const char *)tmp_ctx.signing_context.ui.fee_asset, + }); +UX_STEP_NOCB(ux_sponsorship_6_step, bnnn_paging, + { + .title = "From", + .text = (const char *)tmp_ctx.signing_context.ui.from, + }); + +UX_STEP_NOCB(ux_sponsorship_7_step, bnnn_paging, + { + .title = "Transaction Id", + .text = (const char *)tmp_ctx.signing_context.first_data_hash, + }); +UX_STEP_VALID(ux_sponsorship_8_step, pbb, + io_seproxyhal_touch_sign_approve(NULL), + { + &C_icon_validate_14, + "Accept", + "and send", + }); +UX_STEP_VALID(ux_sponsorship_9_step, pb, io_seproxyhal_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +UX_FLOW(ux_sponsorship_flow, &ux_sponsorship_1_step, &ux_sponsorship_2_step, + &ux_sponsorship_3_step, &ux_sponsorship_4_step, &ux_sponsorship_5_step, + &ux_sponsorship_6_step, &ux_sponsorship_7_step, &ux_sponsorship_8_step, + &ux_sponsorship_9_step); + +////////////////////////////////////////////////////////////////////// + +UX_STEP_NOCB(ux_update_asset_1_step, pnn, + { + &C_icon_eye, + "Confirm", + "Update asset info", + }); +UX_STEP_NOCB(ux_update_asset_2_step, bnnn_paging, + { + .title = "Asset", + .text = (const char *)tmp_ctx.signing_context.ui.line1, + }); +UX_STEP_NOCB(ux_update_asset_3_step, bnnn_paging, + { + .title = "Name", + .text = (const char *)tmp_ctx.signing_context.ui.line2, + }); +UX_STEP_NOCB(ux_update_asset_4_step, bnnn_paging, + { + .title = "Description", + .text = (const char *)tmp_ctx.signing_context.ui.line4, + }); +UX_STEP_NOCB(ux_update_asset_5_step, bnnn_paging, + { + .title = "Fee", + .text = (const char *)tmp_ctx.signing_context.ui.fee_amount, + }); +UX_STEP_NOCB(ux_update_asset_6_step, bnnn_paging, + { + .title = "Fee asset", + .text = (const char *)tmp_ctx.signing_context.ui.fee_asset, + }); +UX_STEP_NOCB(ux_update_asset_7_step, bnnn_paging, + { + .title = "From", + .text = (const char *)tmp_ctx.signing_context.ui.from, + }); + +UX_STEP_NOCB(ux_update_asset_8_step, bnnn_paging, + { + .title = "Transaction Id", + .text = (const char *)tmp_ctx.signing_context.first_data_hash, + }); +UX_STEP_VALID(ux_update_asset_9_step, pbb, + io_seproxyhal_touch_sign_approve(NULL), + { + &C_icon_validate_14, + "Accept", + "and send", + }); +UX_STEP_VALID(ux_update_asset_10_step, pb, io_seproxyhal_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +UX_FLOW(ux_update_asset_flow, &ux_update_asset_1_step, &ux_update_asset_2_step, + &ux_update_asset_3_step, &ux_update_asset_4_step, + &ux_update_asset_5_step, &ux_update_asset_6_step, + &ux_update_asset_7_step, &ux_update_asset_8_step, + &ux_update_asset_9_step, &ux_update_asset_10_step); + +////////////////////////////////////////////////////////////////////// +UX_STEP_NOCB(ux_invoke_1_step, pnn, + { + &C_icon_eye, + "Confirm", + "Script invocation", + }); +UX_STEP_NOCB(ux_invoke_2_step, bnnn_paging, + { + .title = "dApp", + .text = (const char *)tmp_ctx.signing_context.ui.line3, + }); +UX_STEP_NOCB(ux_invoke_3_step, bnnn_paging, + { + .title = "Function", + .text = (const char *)tmp_ctx.signing_context.ui.line2, + }); +UX_STEP_NOCB_INIT( + ux_invoke_4_step, bnnn_paging, + display_if_buffer_not_empty((const char *)tmp_ctx.signing_context.ui.line4, + sizeof(tmp_ctx.signing_context.ui.line4)), + { + .title = "Payment 1 amount", + .text = (const char *)tmp_ctx.signing_context.ui.line4, + }); +UX_STEP_NOCB_INIT( + ux_invoke_5_step, bnnn_paging, + display_if_buffer_not_empty((const char *)tmp_ctx.signing_context.ui.line1, + sizeof(tmp_ctx.signing_context.ui.line1)), + { + .title = "Payment 1 asset", + .text = (const char *)tmp_ctx.signing_context.ui.line1, + }); +UX_STEP_NOCB_INIT( + ux_invoke_6_step, bnnn_paging, + display_if_buffer_not_empty((const char *)tmp_ctx.signing_context.ui.line6, + sizeof(tmp_ctx.signing_context.ui.line6)), + { + .title = "Payment 2 amount", + .text = (const char *)tmp_ctx.signing_context.ui.line6, + }); +UX_STEP_NOCB_INIT( + ux_invoke_7_step, bnnn_paging, + display_if_buffer_not_empty((const char *)tmp_ctx.signing_context.ui.line5, + sizeof(tmp_ctx.signing_context.ui.line5)), + { + .title = "Payment 2 asset", + .text = (const char *)tmp_ctx.signing_context.ui.line5, + }); +UX_STEP_NOCB(ux_invoke_8_step, bnnn_paging, + { + .title = "Fee", + .text = (const char *)tmp_ctx.signing_context.ui.fee_amount, + }); +UX_STEP_NOCB(ux_invoke_9_step, bnnn_paging, + { + .title = "Fee asset", + .text = (const char *)tmp_ctx.signing_context.ui.fee_asset, + }); +UX_STEP_NOCB(ux_invoke_10_step, bnnn_paging, + { + .title = "From", + .text = (const char *)tmp_ctx.signing_context.ui.from, + }); +UX_STEP_NOCB(ux_invoke_11_step, bnnn_paging, + { + .title = "Transaction Id", + .text = (const char *)tmp_ctx.signing_context.first_data_hash, + }); +UX_STEP_VALID(ux_invoke_12_step, pbb, io_seproxyhal_touch_sign_approve(NULL), + { + &C_icon_validate_14, + "Accept", + "and send", + }); +UX_STEP_VALID(ux_invoke_13_step, pb, io_seproxyhal_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +UX_FLOW(ux_invoke_flow, &ux_invoke_1_step, &ux_invoke_2_step, &ux_invoke_3_step, + &ux_invoke_4_step, &ux_invoke_5_step, &ux_invoke_6_step, + &ux_invoke_7_step, &ux_invoke_8_step, &ux_invoke_9_step, + &ux_invoke_10_step, &ux_invoke_11_step, &ux_invoke_12_step, + &ux_invoke_13_step); + +////////////////////////////////////////////////////////////////////// + +UX_STEP_NOCB(ux_order_1_step, pnn, + { + &C_icon_eye, + "Confirm", + (const char *)tmp_ctx.signing_context.ui.line3, + }); +UX_STEP_NOCB(ux_order_2_step, bnnn_paging, + { + .title = "Amount", + .text = (const char *)tmp_ctx.signing_context.ui.line4, + }); +UX_STEP_NOCB(ux_order_3_step, bnnn_paging, + { + .title = "Amount asset", + .text = (const char *)tmp_ctx.signing_context.ui.line1, + }); +UX_STEP_NOCB(ux_order_4_step, bnnn_paging, + { + .title = "From", + .text = (const char *)tmp_ctx.signing_context.ui.from, + }); +UX_STEP_NOCB(ux_order_5_step, bnnn_paging, + { + .title = "Matcher", + .text = (const char *)tmp_ctx.signing_context.ui.line2, + }); +UX_STEP_NOCB(ux_order_6_step, bnnn_paging, + { + .title = "Matcher Fee", + .text = (const char *)tmp_ctx.signing_context.ui.fee_amount, + }); +UX_STEP_NOCB(ux_order_7_step, bnnn_paging, + { + .title = "Fee asset", + .text = (const char *)tmp_ctx.signing_context.ui.fee_asset, + }); + +UX_STEP_NOCB(ux_order_8_step, bnnn_paging, + { + .title = "Hash", + .text = (const char *)tmp_ctx.signing_context.first_data_hash, + }); +UX_STEP_VALID(ux_order_9_step, pbb, io_seproxyhal_touch_sign_approve(NULL), + { + &C_icon_validate_14, + "Accept", + "and send", + }); +UX_STEP_VALID(ux_order_10_step, pb, io_seproxyhal_cancel(NULL), + { + &C_icon_crossmark, + "Reject", + }); + +UX_FLOW(ux_order_flow, &ux_order_1_step, &ux_order_2_step, &ux_order_3_step, + &ux_order_4_step, &ux_order_5_step, &ux_order_6_step, &ux_order_7_step, + &ux_order_8_step, &ux_order_9_step, &ux_order_10_step); + +////////////////////////////////////////////////////////////////////// + UX_STEP_NOCB(ux_verify_transaction_1_step, bnnn_paging, - {.title = "Confirm", .text = (const char *)ui_context.line1}); + {.title = "Confirm", + .text = (const char *)tmp_ctx.signing_context.ui.line1}); UX_STEP_NOCB(ux_verify_transaction_2_step, bnnn_paging, { - .title = (const char *)ui_context.line2, - .text = (const char *)ui_context.line3, + .title = (const char *)tmp_ctx.signing_context.ui.line2, + .text = (const char *)tmp_ctx.signing_context.first_data_hash, }); UX_STEP_NOCB(ux_verify_transaction_3_step, bnnn_paging, { .title = "From", - .text = (const char *)ui_context.line4, + .text = (const char *)tmp_ctx.signing_context.ui.from, }); UX_STEP_VALID(ux_verify_transaction_4_step, pbb, io_seproxyhal_touch_sign_approve(NULL), diff --git a/src/ui/print_amount.c b/src/ui/print_amount.c new file mode 100644 index 00000000..a8e788a2 --- /dev/null +++ b/src/ui/print_amount.c @@ -0,0 +1,65 @@ +/******************************************************************************* + * Waves Platform Wallet App for Nano Ledger devices + * Copyright (c) 2017-2020 Sergey Tolmachev (Tolsi) + * + * Based on Sample code provided (c) 2016 Ledger and + * (c) 2017-2018 Jake B. (Burstcoin app) + * + * 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 "string.h" +#include "print_amount.h" + +bool print_amount(uint64_t amount, int decimals, unsigned char *out, + uint8_t len) { + uint64_t dVal = amount; + int i, j; + + if (decimals == 0) + decimals--; + + memset(tmp_ctx.signing_context.ui.tmp, 0, len); + for (i = 0; dVal > 0 || i < decimals + 2; i++) { + if (dVal > 0) { + tmp_ctx.signing_context.ui.tmp[i] = (char)((dVal % 10) + '0'); + dVal /= 10; + } else { + tmp_ctx.signing_context.ui.tmp[i] = '0'; + } + if (i == decimals - 1) { + i += 1; + tmp_ctx.signing_context.ui.tmp[i] = '.'; + } + if (i >= len) { + return false; + } + } + // reverse order + for (i -= 1, j = 0; i >= 0 && j < len - 1; i--, j++) { + out[j] = tmp_ctx.signing_context.ui.tmp[i]; + } + if (decimals > 0) { + // strip trailing 0s + for (j -= 1; j > 0; j--) { + if (out[j] != '0') + break; + } + j += 1; + if (out[j - 1] == '.') + j -= 1; + } + + out[j] = '\0'; + return true; +} \ No newline at end of file diff --git a/src/ui/print_amount.h b/src/ui/print_amount.h index c3df0a10..ed6a36f0 100644 --- a/src/ui/print_amount.h +++ b/src/ui/print_amount.h @@ -21,48 +21,10 @@ #ifndef __PRINT_AMOUNT_H__ #define __PRINT_AMOUNT_H__ +#include "../main.h" +#include "os.h" // borrowed from the Stellar wallet code and modified bool print_amount(uint64_t amount, int decimals, unsigned char *out, - uint8_t len) { - uint64_t dVal = amount; - int i, j; - - if (decimals == 0) - decimals--; - - memset(ui_context.tmp, 0, len); - for (i = 0; dVal > 0 || i < decimals + 2; i++) { - if (dVal > 0) { - ui_context.tmp[i] = (char)((dVal % 10) + '0'); - dVal /= 10; - } else { - ui_context.tmp[i] = '0'; - } - if (i == decimals - 1) { - i += 1; - ui_context.tmp[i] = '.'; - } - if (i >= len) { - return false; - } - } - // reverse order - for (i -= 1, j = 0; i >= 0 && j < len - 1; i--, j++) { - out[j] = ui_context.tmp[i]; - } - if (decimals > 0) { - // strip trailing 0s - for (j -= 1; j > 0; j--) { - if (out[j] != '0') - break; - } - j += 1; - if (out[j - 1] == '.') - j -= 1; - } - - out[j] = '\0'; - return true; -} + uint8_t len); #endif \ No newline at end of file diff --git a/src/ui/transactions/protobuf.c b/src/ui/transactions/protobuf.c new file mode 100644 index 00000000..a09fab9d --- /dev/null +++ b/src/ui/transactions/protobuf.c @@ -0,0 +1,521 @@ +/******************************************************************************* + * Waves Platform Wallet App for Nano Ledger devices + * Copyright (c) 2017-2020 Vladislav Petushkov + * + * Based on Sample code provided (c) 2016 Ledger and + * (c) 2017-2018 Jake B. (Burstcoin app) + * + * 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 "protobuf.h" +#include "../ui.h" +#include "../print_amount.h" +#include "../../crypto/waves.h" + +bool asset_callback(pb_istream_t *stream, const pb_field_t *field, void **arg) { + PRINTF("Start asset callback\n"); + size_t length = 45; + int len = stream->bytes_left; + memset(&G_io_apdu_buffer[150], 0, len); + if (!pb_read(stream, &G_io_apdu_buffer[150], (size_t)stream->bytes_left)) { + return false; + } + if (len == 32) { + if (!b58enc((char *)*arg, &length, (const void *)&G_io_apdu_buffer[150], + 32)) { + return false; + } + } else { + memmove((char *)*arg, WAVES_CONST, 5); + } + PRINTF("End asset callback\n"); + return true; +} + +bool from_callback(pb_istream_t *stream, const pb_field_t *field, void **arg) { + memset(&G_io_apdu_buffer[150], 0, 32); + PRINTF("Start from callback\n"); + if (!pb_read(stream, &G_io_apdu_buffer[150], (size_t)stream->bytes_left)) { + return false; + } + memmove((char *)*arg, &G_io_apdu_buffer[150], 32); + PRINTF("End from callback\n"); + return true; +} + +bool string_callback(pb_istream_t *stream, const pb_field_t *field, + void **arg) { + PRINTF("Start string callback\n"); + int len = stream->bytes_left; + memset(&G_io_apdu_buffer[150], 0, len); + if (!pb_read(stream, &G_io_apdu_buffer[150], (size_t)stream->bytes_left)) { + return false; + } + memmove((char *)*arg, &G_io_apdu_buffer[150], len); + PRINTF("End string callback\n"); + return true; +} + +bool text_callback(pb_istream_t *stream, const pb_field_t *field, void **arg) { + int len = stream->bytes_left; + PRINTF("Start text callback\n"); + if (len > 41) { + size_t length = 41; + memset(&G_io_apdu_buffer[150], 0, 45); + size_t left = stream->bytes_left - length; + if (!pb_read(stream, &G_io_apdu_buffer[150], length)) { + return false; + } + memmove((char *)&G_io_apdu_buffer[191], &"...\0", 4); + memmove((char *)*arg, &G_io_apdu_buffer[150], 45); + if (!pb_read(stream, NULL, left)) { + return false; + } + } else { + memset(&G_io_apdu_buffer[150], 0, len); + if (!pb_read(stream, &G_io_apdu_buffer[150], (size_t)stream->bytes_left)) { + return false; + } + memmove((char *)*arg, &G_io_apdu_buffer[150], len); + } + PRINTF("End text callback\n"); + return true; +} + +bool issue_script_callback(pb_istream_t *stream, const pb_field_t *field, + void **arg) { + PRINTF("Start issue script callback\n"); + int len = stream->bytes_left; + if (!pb_read(stream, NULL, len)) { // read other data + return false; + } + memmove((char *)*arg, &"True\0", 5); + PRINTF("End issue script callback\n"); +} + +bool function_call_callback(pb_istream_t *stream, const pb_field_t *field, + void **arg) { + uint32_t name_len; + PRINTF("Start function call callback\n"); + memset(&G_io_apdu_buffer[150], 0, 45); + int len = stream->bytes_left; + if (len <= 7) { + memmove((char *)*arg, &"default\0", 45); + return true; + } + if (!pb_read(stream, &G_io_apdu_buffer[150], + 7)) { // read setting 3 bytes and 4 byte of function name size + return false; + } + len -= 7; + name_len = deserialize_uint32_t(&G_io_apdu_buffer[153]); + if (name_len > 41) { // if function name len is + if (!pb_read(stream, &G_io_apdu_buffer[150], + 41)) { // read 41 byte of the name + return false; + } + len -= 41; + memmove((char *)&G_io_apdu_buffer[191], &"...\0", 4); + memmove((char *)*arg, &G_io_apdu_buffer[150], 45); + if (!pb_read(stream, NULL, len)) { // read last str to null + return false; + } + } else { + if (!pb_read(stream, &G_io_apdu_buffer[150], + name_len)) { // read all name str + return false; + } + len -= name_len; + memmove((char *)*arg, &G_io_apdu_buffer[150], 45); + if (!pb_read(stream, NULL, len)) { // read other data + return false; + } + } + PRINTF("End function call callback\n"); + return true; +} + +bool transaction_data_callback(pb_istream_t *stream, const pb_field_t *field, + void **arg) { + if (!pb_read(stream, NULL, stream->bytes_left)) { + return false; + } + return true; +} + +uint32_t pb_find_child(pb_istream_t *stream) { + pb_wire_type_t wire_type; + uint32_t tag; + bool eof; + PRINTF("Start finding child msg\n"); + while (pb_decode_tag(stream, &wire_type, &tag, &eof)) { + if (wire_type == PB_WT_STRING) { + pb_field_iter_t iter; + if (pb_field_iter_begin(&iter, waves_Transaction_fields, NULL) && + pb_field_iter_find(&iter, tag)) { + if (tag >= waves_Transaction_issue_tag && + tag <= waves_Transaction_update_asset_info_tag) { + return tag; + } + } + } + + /* Wasn't our field.. */ + pb_skip_field(stream, wire_type); + } + return 0; + PRINTF("End finding child msg\n"); +} + +void pb_decode_child(pb_istream_t *stream, const pb_msgdesc_t *msg, + void *dest) { + PRINTF("Start decoding child msg\n"); + pb_istream_t substream; + uint8_t status; + if (!pb_make_string_substream(stream, &substream)) + THROW(SW_PROTOBUF_DECODING_FAILED); + + status = pb_decode(&substream, msg, dest); + pb_close_string_substream(stream, &substream); + if (!status) { + PRINTF("Decoding failed: %s\n", PB_GET_ERROR(stream)); + THROW(SW_PROTOBUF_DECODING_FAILED); + } + PRINTF("End decoding child msg\n"); +} + +void build_issue_protobuf(pb_istream_t *stream) { + waves_IssueTransactionData tx = waves_IssueTransactionData_init_default; + tx.name.funcs.decode = text_callback; + tx.name.arg = &tmp_ctx.signing_context.ui.line1; + tx.description.funcs.decode = text_callback; + tx.description.arg = &tmp_ctx.signing_context.ui.line2; + tx.script.funcs.decode = issue_script_callback; + tx.script.arg = &tmp_ctx.signing_context.ui.line6; + pb_decode_child(stream, waves_IssueTransactionData_fields, &tx); + snprintf((char *)tmp_ctx.signing_context.ui.line4, + sizeof(tmp_ctx.signing_context.ui.line4), "%d", tx.decimals); + print_amount(tx.amount, (unsigned char)tx.decimals, + (unsigned char *)tmp_ctx.signing_context.ui.line3, 22); + if (tx.reissuable == true) { + memmove((unsigned char *)&tmp_ctx.signing_context.ui.line5, &"True\0", + 5); + } else { + memmove((unsigned char *)&tmp_ctx.signing_context.ui.line5, &"False\0", + 6); + } + if(strlen((const char *)tmp_ctx.signing_context.ui.line6) == 0) { + memmove((unsigned char *)&tmp_ctx.signing_context.ui.line6, &"False\0", + 6); + } +} + +void build_transfer_protobuf(pb_istream_t *stream) { + waves_TransferTransactionData tx = waves_TransferTransactionData_init_default; + tx.amount.asset_id.funcs.decode = asset_callback; + tx.amount.asset_id.arg = &tmp_ctx.signing_context.ui.line2; + tx.attachment.funcs.decode = text_callback; + tx.attachment.arg = &tmp_ctx.signing_context.ui.line4; + pb_decode_child(stream, waves_TransferTransactionData_fields, &tx); + print_amount(tx.amount.amount, tmp_ctx.signing_context.amount_decimals, + (unsigned char *)tmp_ctx.signing_context.ui.line1, 22); + if (tx.recipient.which_recipient == waves_Recipient_public_key_hash_tag) { + waves_public_key_hash_to_address(tx.recipient.recipient.public_key_hash, + tmp_ctx.signing_context.network_byte, + tmp_ctx.signing_context.ui.line3); + } else { + memmove(tmp_ctx.signing_context.ui.line3, tx.recipient.recipient.alias, + 31); + } + if (strlen((const char *)tmp_ctx.signing_context.ui.line2) == 0) { + memmove(tmp_ctx.signing_context.ui.line2, WAVES_CONST, 5); + } +} + +void build_reissue_protobuf(pb_istream_t *stream) { + waves_ReissueTransactionData tx = waves_ReissueTransactionData_init_default; + tx.asset_amount.asset_id.funcs.decode = asset_callback; + tx.asset_amount.asset_id.arg = &tmp_ctx.signing_context.ui.line2; + pb_decode_child(stream, waves_ReissueTransactionData_fields, &tx); + print_amount(tx.asset_amount.amount, tmp_ctx.signing_context.amount_decimals, + (unsigned char *)tmp_ctx.signing_context.ui.line1, 22); + if (tx.reissuable == true) { + memmove((unsigned char *)&tmp_ctx.signing_context.ui.line3, &"True\0", + 5); + } else { + memmove((unsigned char *)&tmp_ctx.signing_context.ui.line3, &"False\0", + 6); + } +} + +void build_burn_protobuf(pb_istream_t *stream) { + waves_BurnTransactionData tx = waves_BurnTransactionData_init_default; + tx.asset_amount.asset_id.funcs.decode = asset_callback; + tx.asset_amount.asset_id.arg = &tmp_ctx.signing_context.ui.line2; + pb_decode_child(stream, waves_BurnTransactionData_fields, &tx); + print_amount(tx.asset_amount.amount, tmp_ctx.signing_context.amount_decimals, + (unsigned char *)tmp_ctx.signing_context.ui.line1, 22); +} + +void build_lease_protobuf(pb_istream_t *stream) { + waves_LeaseTransactionData tx = waves_LeaseTransactionData_init_default; + pb_decode_child(stream, waves_LeaseTransactionData_fields, &tx); + print_amount(tx.amount, tmp_ctx.signing_context.amount_decimals, + (unsigned char *)tmp_ctx.signing_context.ui.line1, 22); + if (tx.recipient.which_recipient == waves_Recipient_public_key_hash_tag) { + waves_public_key_hash_to_address(tx.recipient.recipient.public_key_hash, + tmp_ctx.signing_context.network_byte, + tmp_ctx.signing_context.ui.line3); + } else { + memmove(tmp_ctx.signing_context.ui.line3, tx.recipient.recipient.alias, + 31); + } +} + +void build_lease_cancel_protobuf(pb_istream_t *stream) { + waves_LeaseCancelTransactionData tx = + waves_LeaseCancelTransactionData_init_default; + tx.lease_id.funcs.decode = asset_callback; + tx.lease_id.arg = &tmp_ctx.signing_context.ui.line1; + pb_decode_child(stream, waves_LeaseCancelTransactionData_fields, &tx); +} + +void build_create_alias_protobuf(pb_istream_t *stream) { + waves_CreateAliasTransactionData tx = + waves_CreateAliasTransactionData_init_default; + tx.alias.funcs.decode = string_callback; + tx.alias.arg = &tmp_ctx.signing_context.ui.line1; + pb_decode_child(stream, waves_CreateAliasTransactionData_fields, &tx); +} + +void build_mass_transfer_protobuf(pb_istream_t *stream) { + waves_MassTransferTransactionData tx = + waves_MassTransferTransactionData_init_default; + tx.asset_id.funcs.decode = asset_callback; + tx.asset_id.arg = &tmp_ctx.signing_context.ui.line1; + tx.attachment.funcs.decode = text_callback; + tx.attachment.arg = &tmp_ctx.signing_context.ui.line2; + pb_decode_child(stream, waves_MassTransferTransactionData_fields, &tx); + if (strlen((const char *)tmp_ctx.signing_context.ui.line1) == 0) { + memmove(tmp_ctx.signing_context.ui.line1, WAVES_CONST, 5); + } +} + +void build_data_transaction_protobuf(pb_istream_t *stream) { + waves_DataTransactionData tx = waves_DataTransactionData_init_default; + pb_decode_child(stream, waves_DataTransactionData_fields, &tx); +} + +void build_set_script_protobuf(pb_istream_t *stream) { + waves_SetScriptTransactionData tx = + waves_SetScriptTransactionData_init_default; + pb_decode_child(stream, waves_SetScriptTransactionData_fields, &tx); +} + +void build_sponsor_fee_protobuf(pb_istream_t *stream) { + waves_SponsorFeeTransactionData tx = + waves_SponsorFeeTransactionData_init_default; + tx.min_fee.asset_id.funcs.decode = asset_callback; + tx.min_fee.asset_id.arg = &tmp_ctx.signing_context.ui.line2; + pb_decode_child(stream, waves_SponsorFeeTransactionData_fields, &tx); + print_amount(tx.min_fee.amount, tmp_ctx.signing_context.amount_decimals, + (unsigned char *)tmp_ctx.signing_context.ui.line1, 22); +} + +void build_set_asset_script_protobuf(pb_istream_t *stream) { + waves_SetAssetScriptTransactionData tx = + waves_SetAssetScriptTransactionData_init_default; + tx.asset_id.funcs.decode = asset_callback; + tx.asset_id.arg = &tmp_ctx.signing_context.ui.line1; + pb_decode_child(stream, waves_SetAssetScriptTransactionData_fields, &tx); +} + +void build_invoke_script_protobuf(pb_istream_t *stream) { + waves_InvokeScriptTransactionData tx = + waves_InvokeScriptTransactionData_init_default; + tx.function_call.funcs.decode = function_call_callback; + tx.function_call.arg = &tmp_ctx.signing_context.ui.line2; + tx.payments[0].asset_id.funcs.decode = asset_callback; + tx.payments[0].asset_id.arg = &tmp_ctx.signing_context.ui.line1; + tx.payments[1].asset_id.funcs.decode = asset_callback; + tx.payments[1].asset_id.arg = &tmp_ctx.signing_context.ui.line5; + pb_decode_child(stream, waves_InvokeScriptTransactionData_fields, &tx); + if (tx.payments_count >= 1) { + print_amount(tx.payments[0].amount, tmp_ctx.signing_context.amount_decimals, + (unsigned char *)&tmp_ctx.signing_context.ui.line4, 22); + if (strlen((const char *)tmp_ctx.signing_context.ui.line1) == 0) { + memmove(tmp_ctx.signing_context.ui.line1, WAVES_CONST, 5); + } + } + if (tx.payments_count == 2) { + print_amount(tx.payments[1].amount, tmp_ctx.signing_context.amount2_decimals, + (unsigned char *)&tmp_ctx.signing_context.ui.line6, 22); + if (strlen((const char *)tmp_ctx.signing_context.ui.line5) == 0) { + memmove(tmp_ctx.signing_context.ui.line1, WAVES_CONST, 5); + } + } + if (tx.d_app.which_recipient == waves_Recipient_public_key_hash_tag) { + waves_public_key_hash_to_address(tx.d_app.recipient.public_key_hash, + tmp_ctx.signing_context.network_byte, + tmp_ctx.signing_context.ui.line3); + } else { + memmove(tmp_ctx.signing_context.ui.line3, tx.d_app.recipient.alias, 31); + } +} + +void build_update_asset_info_protobuf(pb_istream_t *stream) { + waves_UpdateAssetInfoTransactionData tx = + waves_UpdateAssetInfoTransactionData_init_default; + tx.asset_id.funcs.decode = asset_callback; + tx.asset_id.arg = &tmp_ctx.signing_context.ui.line1; + tx.name.funcs.decode = string_callback; + tx.name.arg = &tmp_ctx.signing_context.ui.line2; + tx.description.funcs.decode = text_callback; + tx.description.arg = &tmp_ctx.signing_context.ui.line4; + pb_decode_child(stream, waves_UpdateAssetInfoTransactionData_fields, &tx); +} + +void build_protobuf_child_tx(uiProtobuf_t *ctx, uint8_t *init_buffer, + uint8_t init_buffer_size, + uint16_t total_buffer_size) { + uint32_t tag; + pb_istream_t stream = pb_istream_from_apdu(ctx, init_buffer, init_buffer_size, + total_buffer_size, 0); + tag = pb_find_child(&stream); + switch (tag) { + case waves_Transaction_issue_tag: + build_issue_protobuf(&stream); + break; + case waves_Transaction_transfer_tag: + build_transfer_protobuf(&stream); + break; + case waves_Transaction_reissue_tag: + build_reissue_protobuf(&stream); + break; + case waves_Transaction_burn_tag: + build_burn_protobuf(&stream); + break; + case waves_Transaction_lease_tag: + build_lease_protobuf(&stream); + break; + case waves_Transaction_lease_cancel_tag: + build_lease_cancel_protobuf(&stream); + break; + case waves_Transaction_create_alias_tag: + build_create_alias_protobuf(&stream); + break; + case waves_Transaction_mass_transfer_tag: + build_mass_transfer_protobuf(&stream); + break; + case waves_Transaction_data_transaction_tag: + build_data_transaction_protobuf(&stream); + break; + case waves_Transaction_set_script_tag: + build_set_script_protobuf(&stream); + break; + case waves_Transaction_sponsor_fee_tag: + build_sponsor_fee_protobuf(&stream); + break; + case waves_Transaction_set_asset_script_tag: + build_set_asset_script_protobuf(&stream); + break; + case waves_Transaction_invoke_script_tag: + build_invoke_script_protobuf(&stream); + break; + case waves_Transaction_update_asset_info_tag: + build_update_asset_info_protobuf(&stream); + break; + default: + PRINTF("Error with child tag"); + THROW(SW_PROTOBUF_DECODING_FAILED); + break; + } + + tmp_ctx.signing_context.ui.finished = true; + tmp_ctx.signing_context.step = 8; +} + +void build_protobuf_root_tx(uiProtobuf_t *ctx, uint8_t *init_buffer, + uint8_t init_buffer_size, + uint16_t total_buffer_size, uint8_t start_index) { + uint8_t status; + pb_istream_t stream = pb_istream_from_apdu(ctx, init_buffer, init_buffer_size, + total_buffer_size, start_index); + PRINTF("Start decoding root msg\n"); + // init variable for parsing + waves_Transaction tx = waves_Transaction_init_zero; + // set callback for parsing tx data field(transactions) + tx.cb_data.funcs.decode = transaction_data_callback; + tx.sender_public_key.funcs.decode = from_callback; + tx.sender_public_key.arg = &tmp_ctx.signing_context.ui.from; + tx.fee.asset_id.funcs.decode = asset_callback; + tx.fee.asset_id.arg = &tmp_ctx.signing_context.ui.fee_asset; + status = pb_decode_ex(&stream, waves_Transaction_fields, &tx, 0); + if (!status) { + PRINTF("Decoding failed: %s\n", PB_GET_ERROR(&stream)); + THROW(SW_PROTOBUF_DECODING_FAILED); + } + print_amount(tx.fee.amount, tmp_ctx.signing_context.fee_decimals, + (unsigned char *)tmp_ctx.signing_context.ui.fee_amount, 22); + if (strlen((const char *)tmp_ctx.signing_context.ui.fee_asset) == 0) { + memmove(tmp_ctx.signing_context.ui.fee_asset, WAVES_CONST, 5); + } + PRINTF("End decoding root msg\n"); + tmp_ctx.signing_context.step = 7; +} + +void build_protobuf_order(uiProtobuf_t *ctx, uint8_t *init_buffer, + uint8_t init_buffer_size, uint16_t total_buffer_size, + uint8_t start_index) { + uint8_t status; + // init variable for parsing + waves_Order order = waves_Order_init_default; + order.sender_public_key.funcs.decode = from_callback; + order.sender_public_key.arg = &tmp_ctx.signing_context.ui.from; + order.matcher_public_key.funcs.decode = from_callback; + order.matcher_public_key.arg = &tmp_ctx.signing_context.ui.line2; + order.matcher_fee.asset_id.funcs.decode = asset_callback; + order.matcher_fee.asset_id.arg = &tmp_ctx.signing_context.ui.fee_asset; + order.asset_pair.amount_asset_id.funcs.decode = asset_callback; + order.asset_pair.amount_asset_id.arg = &tmp_ctx.signing_context.ui.line1; + // create stream for parsing + pb_istream_t stream = pb_istream_from_apdu(ctx, init_buffer, init_buffer_size, + total_buffer_size, start_index); + // decoding order message + PRINTF("Start decoding\n"); + status = pb_decode(&stream, waves_Order_fields, &order); + if (!status) { + PRINTF("Decoding failed: %s\n", PB_GET_ERROR(&stream)); + THROW(0x6D00); + } + PRINTF("End decoding\n"); + print_amount(order.amount, tmp_ctx.signing_context.amount_decimals, + (unsigned char *)tmp_ctx.signing_context.ui.line4, 22); + print_amount(order.matcher_fee.amount, tmp_ctx.signing_context.fee_decimals, + (unsigned char *)tmp_ctx.signing_context.ui.fee_amount, 22); + if (order.order_side == waves_Order_Side_BUY) { + memmove((unsigned char *)&tmp_ctx.signing_context.ui.line3, + &"Buy order\0", 10); + } else { + memmove((unsigned char *)&tmp_ctx.signing_context.ui.line3, + &"Sell order\0", 11); + } + if (strlen((const char *)tmp_ctx.signing_context.ui.fee_asset) == 0) { + memmove(tmp_ctx.signing_context.ui.fee_asset, WAVES_CONST, 5); + } + waves_public_key_to_address(tmp_ctx.signing_context.ui.line2, + tmp_ctx.signing_context.network_byte, + tmp_ctx.signing_context.ui.line2); + tmp_ctx.signing_context.step = 7; +} diff --git a/src/ui/transactions/protobuf.h b/src/ui/transactions/protobuf.h new file mode 100644 index 00000000..1ce25abb --- /dev/null +++ b/src/ui/transactions/protobuf.h @@ -0,0 +1,39 @@ +/******************************************************************************* + * Waves Platform Wallet App for Nano Ledger devices + * Copyright (c) 2017-2020 Vladislav Petushkov + * + * Based on Sample code provided (c) 2016 Ledger and + * (c) 2017-2018 Jake B. (Burstcoin app) + * + * 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. + ********************************************************************************/ + +#ifndef __PROTOBUF_H__ +#define __PROTOBUF_H__ + +#include +#include "../../main.h" +#include "../../nanopb/pb.h" +#include "../../nanopb/pb_decode.h" +#include "../../nanopb/pb_custom.h" +#include "../../nanopb_stubs/order.pb.h" +#include "../../nanopb_stubs/transaction.pb.h" + +void build_protobuf_root_tx(uiProtobuf_t *ctx, uint8_t *init_buffer, + uint8_t init_buffer_size, uint16_t total_buffer_size, uint8_t start_index); +void build_protobuf_child_tx(uiProtobuf_t *ctx, uint8_t *init_buffer, + uint8_t init_buffer_size, uint16_t total_buffer_size); +void build_protobuf_order(uiProtobuf_t *ctx, uint8_t *init_buffer, + uint8_t init_buffer_size, uint16_t total_buffer_size, uint8_t start_index); + +#endif \ No newline at end of file diff --git a/src/ui/transactions/transfer.c b/src/ui/transactions/transfer.c index c1fb3ba6..484853ac 100644 --- a/src/ui/transactions/transfer.c +++ b/src/ui/transactions/transfer.c @@ -21,245 +21,240 @@ #include "transfer.h" #include "../../main.h" #include "../ui.h" -#include "../print_amount.h" #include "../../crypto/waves.h" +#include "../print_amount.h" void update_transfer_wait_in_buffer() { - ui_context.buffer_used = 0; - switch (ui_context.step) { + tmp_ctx.signing_context.ui.byte.buffer_used = 0; + switch (tmp_ctx.signing_context.ui.byte.step) { case 2: case 4: case 9: - ui_context.wait_in_buffer = 1; + tmp_ctx.signing_context.ui.byte.wait_in_buffer = 1; break; case 11: - ui_context.wait_in_buffer = 4; + tmp_ctx.signing_context.ui.byte.wait_in_buffer = 3; break; case 13: - ui_context.wait_in_buffer = 2; + tmp_ctx.signing_context.ui.byte.wait_in_buffer = 2; break; case 6: case 7: case 8: - ui_context.wait_in_buffer = 8; + tmp_ctx.signing_context.ui.byte.wait_in_buffer = 8; break; case 10: // use first byte from step 9 - ui_context.chunk_used -= 1; - ui_context.wait_in_buffer = 26; + tmp_ctx.signing_context.ui.byte.chunk_used -= 1; + tmp_ctx.signing_context.ui.byte.wait_in_buffer = 26; break; case 1: case 3: case 5: - ui_context.wait_in_buffer = 32; + tmp_ctx.signing_context.ui.byte.wait_in_buffer = 32; break; case 12: - ui_context.wait_in_buffer = ui_context.alias_size; + tmp_ctx.signing_context.ui.byte.wait_in_buffer = + tmp_ctx.signing_context.ui.byte.alias_size; break; case 14: - ui_context.wait_in_buffer = ui_context.attachment_size; + tmp_ctx.signing_context.ui.byte.wait_in_buffer = + tmp_ctx.signing_context.ui.byte.attachment_size; break; case 15: // last - ui_context.wait_in_buffer = 0; + tmp_ctx.signing_context.ui.byte.wait_in_buffer = 0; break; } } -void build_transfer_ui_step(bool is_last) { - uint8_t chunk_data_start_index = 5; +void build_transfer_ui_step() { uint8_t chunk_data_size = G_io_apdu_buffer[4]; + uint8_t chunk_data_start_index = 5; - if (tmp_ctx.signing_context.chunk == 0) { - chunk_data_start_index += 28; - chunk_data_size -= 28; - } - - if (ui_context.wait_in_buffer > 0) { + if (tmp_ctx.signing_context.ui.byte.wait_in_buffer > 0) { try_to_fill_buffer(chunk_data_start_index, chunk_data_size); } - if (ui_context.wait_in_buffer == 0 && !ui_context.finished) { + if (tmp_ctx.signing_context.ui.byte.wait_in_buffer == 0 && + !tmp_ctx.signing_context.ui.finished) { size_t length = 45; - bool is_flag_set = ui_context.buffer[0] == 1; + bool is_flag_set = tmp_ctx.signing_context.ui.byte.buffer[0] == 1; uint64_t amount = 0; uint64_t fee = 0; - PRINTF("build_ui_step step %d\n", ui_context.step); + PRINTF("build_ui_step step %d\n", tmp_ctx.signing_context.ui.byte.step); - switch (ui_context.step) { + switch (tmp_ctx.signing_context.ui.byte.step) { case 0: // type - ui_context.chunk_used = 1; + tmp_ctx.signing_context.ui.byte.chunk_used = + tmp_ctx.signing_context.chunk_used + 1; // skip version if (tmp_ctx.signing_context.data_version == 2) { - ui_context.chunk_used += 1; + tmp_ctx.signing_context.ui.byte.chunk_used += 1; } - ui_context.step = 1; + tmp_ctx.signing_context.ui.byte.step = 1; update_transfer_wait_in_buffer(); break; case 1: // sender public key 32 bytes - waves_public_key_to_address((const unsigned char *)ui_context.buffer, - tmp_ctx.signing_context.network_byte, - (unsigned char *)ui_context.line7); - - ui_context.step = 2; + memmove(&tmp_ctx.signing_context.ui.from, + tmp_ctx.signing_context.ui.byte.buffer, 32); + tmp_ctx.signing_context.ui.byte.step = 2; update_transfer_wait_in_buffer(); break; case 2: // amount asset flag if (is_flag_set) { - ui_context.step = 3; + tmp_ctx.signing_context.ui.byte.step = 3; } else { - os_memmove((char *)ui_context.line2, WAVES_CONST, 5); - ui_context.step = 4; + memmove((char *)tmp_ctx.signing_context.ui.line2, WAVES_CONST, 5); + tmp_ctx.signing_context.ui.byte.step = 4; } update_transfer_wait_in_buffer(); break; case 3: // amount asset - if (!b58enc((char *)ui_context.line2, &length, - (const void *)ui_context.buffer, 32)) { + if (!b58enc((char *)tmp_ctx.signing_context.ui.line2, &length, + (const void *)tmp_ctx.signing_context.ui.byte.buffer, 32)) { return THROW(SW_CONDITIONS_NOT_SATISFIED); } - ui_context.step = 4; + tmp_ctx.signing_context.ui.byte.step = 4; update_transfer_wait_in_buffer(); break; case 4: // fee asset flag if (is_flag_set) { - ui_context.step = 5; + tmp_ctx.signing_context.ui.byte.step = 5; } else { - os_memmove((char *)ui_context.line5, WAVES_CONST, 5); - ui_context.step = 6; + memmove((char *)tmp_ctx.signing_context.ui.fee_asset, WAVES_CONST, + 5); + tmp_ctx.signing_context.ui.byte.step = 6; } update_transfer_wait_in_buffer(); break; case 5: // fee asset - if (!b58enc((char *)ui_context.line5, &length, - (const void *)ui_context.buffer, 32)) { + if (!b58enc((char *)tmp_ctx.signing_context.ui.fee_asset, &length, + (const void *)tmp_ctx.signing_context.ui.byte.buffer, 32)) { return THROW(SW_CONDITIONS_NOT_SATISFIED); } - ui_context.step = 6; + tmp_ctx.signing_context.ui.byte.step = 6; update_transfer_wait_in_buffer(); break; case 6: // timestamp, skip it - ui_context.step = 7; + tmp_ctx.signing_context.ui.byte.step = 7; update_transfer_wait_in_buffer(); break; case 7: // amount - copy_in_reverse_order((unsigned char *)&amount, - (const unsigned char *)ui_context.buffer, 8); + copy_in_reverse_order( + (unsigned char *)&amount, + (const unsigned char *)tmp_ctx.signing_context.ui.byte.buffer, 8); print_amount(amount, tmp_ctx.signing_context.amount_decimals, - (unsigned char *)ui_context.line1, 20); + (unsigned char *)tmp_ctx.signing_context.ui.line1, 20); - ui_context.step = 8; + tmp_ctx.signing_context.ui.byte.step = 8; update_transfer_wait_in_buffer(); break; case 8: // fee - copy_in_reverse_order((unsigned char *)&fee, - (const unsigned char *)ui_context.buffer, 8); + copy_in_reverse_order( + (unsigned char *)&fee, + (const unsigned char *)tmp_ctx.signing_context.ui.byte.buffer, 8); print_amount(fee, tmp_ctx.signing_context.fee_decimals, - (unsigned char *)ui_context.line4, 20); - - ui_context.step = 9; + (unsigned char *)tmp_ctx.signing_context.ui.fee_amount, 20); + tmp_ctx.signing_context.ui.byte.step = 9; update_transfer_wait_in_buffer(); break; case 9: // address or alias flag is a part of address - if (ui_context.buffer[0] == 1) { - ui_context.step = 10; - } else if (ui_context.buffer[0] == 2) { - ui_context.step = 11; + if (tmp_ctx.signing_context.ui.byte.buffer[0] == 1) { + tmp_ctx.signing_context.ui.byte.step = 10; + } else if (tmp_ctx.signing_context.ui.byte.buffer[0] == 2) { + tmp_ctx.signing_context.ui.byte.step = 11; } else { return THROW(SW_CONDITIONS_NOT_SATISFIED); } - update_transfer_wait_in_buffer(); break; case 10: // address - if (!b58enc((char *)ui_context.line3, &length, - (const void *)ui_context.buffer, 26)) { + if (!b58enc((char *)tmp_ctx.signing_context.ui.line3, &length, + (const void *)tmp_ctx.signing_context.ui.byte.buffer, 26)) { return THROW(SW_CONDITIONS_NOT_SATISFIED); } - - ui_context.step = 13; - + tmp_ctx.signing_context.ui.byte.step = 13; update_transfer_wait_in_buffer(); break; case 11: // alias len // also skip address scheme byte (first 2) - copy_in_reverse_order((unsigned char *)&ui_context.alias_size, - (unsigned char *)&ui_context.buffer[2], 2); - - ui_context.step = 12; + tmp_ctx.signing_context.ui.byte.alias_size = + tmp_ctx.signing_context.ui.byte.buffer[1] << 8 | + tmp_ctx.signing_context.ui.byte.buffer[2]; + tmp_ctx.signing_context.ui.byte.step = 12; update_transfer_wait_in_buffer(); break; case 12: // alias - os_memmove((unsigned char *)ui_context.line3, - (const unsigned char *)ui_context.buffer, - ui_context.alias_size); + if (tmp_ctx.signing_context.ui.byte.alias_size > 30 || + tmp_ctx.signing_context.ui.byte.alias_size < 4) { + THROW(SW_BYTE_DECODING_FAILED); + } + memmove((unsigned char *)tmp_ctx.signing_context.ui.line3, + (const unsigned char *)tmp_ctx.signing_context.ui.byte.buffer, + tmp_ctx.signing_context.ui.byte.alias_size); - ui_context.step = 13; + tmp_ctx.signing_context.ui.byte.step = 13; update_transfer_wait_in_buffer(); break; case 13: // attachment size in bytes - copy_in_reverse_order((unsigned char *)&ui_context.attachment_size, - (unsigned char *)ui_context.buffer, 2); + copy_in_reverse_order( + (unsigned char *)&tmp_ctx.signing_context.ui.byte.attachment_size, + (unsigned char *)tmp_ctx.signing_context.ui.byte.buffer, 2); - ui_context.step = 14; + tmp_ctx.signing_context.ui.byte.step = 14; update_transfer_wait_in_buffer(); break; case 14: // attachment - if (ui_context.attachment_size > 41) { - os_memmove((unsigned char *)&ui_context.line6[41], &"...\0", 4); - ui_context.attachment_size = 41; + if (tmp_ctx.signing_context.ui.byte.attachment_size > 41) { + memmove((unsigned char *)&tmp_ctx.signing_context.ui.line4[41], + &"...\0", 4); + tmp_ctx.signing_context.ui.byte.attachment_size = 41; } - os_memmove((unsigned char *)ui_context.line6, - (const unsigned char *)ui_context.buffer, - ui_context.attachment_size); + memmove((unsigned char *)tmp_ctx.signing_context.ui.line4, + (const unsigned char *)tmp_ctx.signing_context.ui.byte.buffer, + tmp_ctx.signing_context.ui.byte.attachment_size); - ui_context.step = 15; + tmp_ctx.signing_context.ui.byte.step = 15; update_transfer_wait_in_buffer(); break; case 15: - if (is_last) { - size_t length = 45; - // id should be calculated on sign step - if (!b58enc((char *)ui_context.line8, &length, - (const void *)&ui_context.id, 32)) { - return THROW(SW_CONDITIONS_NOT_SATISFIED); - } - ui_context.finished = true; - } + tmp_ctx.signing_context.ui.finished = true; + tmp_ctx.signing_context.step = 7; break; default: THROW(INVALID_COUNTER); diff --git a/src/ui/transactions/transfer.h b/src/ui/transactions/transfer.h index 0fa0a17d..991354d9 100644 --- a/src/ui/transactions/transfer.h +++ b/src/ui/transactions/transfer.h @@ -23,6 +23,6 @@ #include -void build_transfer_ui_step(bool is_last); +void build_transfer_ui_step(); #endif \ No newline at end of file diff --git a/src/ui/ui.c b/src/ui/ui.c index bb2046b6..3260fffa 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -24,6 +24,8 @@ #include "../main.h" #include "../crypto/waves.h" #include "transactions/transfer.h" +#include "transactions/protobuf.h" +#include "cx.h" #ifdef TARGET_BLUE #include "blue/ui_menus_blue.h" @@ -41,9 +43,6 @@ enum UI_STATE ui_state; int ux_step, ux_step_count; -bool print_amount(uint64_t amount, int decimals, unsigned char *out, - uint8_t len); - void menu_address_init() { ux_step = 0; ux_step_count = 2; @@ -72,78 +71,76 @@ void ui_idle() { void try_to_fill_buffer(uint8_t chunk_data_start_index, uint8_t chunk_data_size) { - uint32_t chunk_data_left = chunk_data_size - ui_context.chunk_used; + uint32_t chunk_data_left = + chunk_data_size - tmp_ctx.signing_context.ui.byte.chunk_used; uint32_t step_read_bytes_left = - MIN(chunk_data_left, ui_context.wait_in_buffer); - if (ui_context.wait_in_buffer <= 0 || - chunk_data_start_index + ui_context.chunk_used > 150) { + MIN(chunk_data_left, tmp_ctx.signing_context.ui.byte.wait_in_buffer); + if (tmp_ctx.signing_context.ui.byte.wait_in_buffer <= 0 || + chunk_data_start_index + tmp_ctx.signing_context.ui.byte.chunk_used > + 150) { return THROW(EXCEPTION_OVERFLOW); } - os_memmove((unsigned char *)&ui_context.buffer[ui_context.buffer_used], - &G_io_apdu_buffer[chunk_data_start_index + ui_context.chunk_used], + memmove((unsigned char *)&tmp_ctx.signing_context.ui.byte + .buffer[tmp_ctx.signing_context.ui.byte.buffer_used], + &G_io_apdu_buffer[chunk_data_start_index + + tmp_ctx.signing_context.ui.byte.chunk_used], step_read_bytes_left); - ui_context.chunk_used += step_read_bytes_left; - ui_context.buffer_used += step_read_bytes_left; - ui_context.wait_in_buffer -= step_read_bytes_left; + tmp_ctx.signing_context.ui.byte.chunk_used += step_read_bytes_left; + tmp_ctx.signing_context.ui.byte.buffer_used += step_read_bytes_left; + tmp_ctx.signing_context.ui.byte.wait_in_buffer -= step_read_bytes_left; } void build_other_data_ui() { unsigned char tx_type = tmp_ctx.signing_context.data_type; // just one step here - os_memmove(&ui_context.line2, &"Transaction Id\0", 15); + memmove(&tmp_ctx.signing_context.ui.line2, &"Transaction Id\0", 15); if (tx_type == 3) { - os_memmove(&ui_context.line1, &"issue\0", 6); + memmove(&tmp_ctx.signing_context.ui.line1, &"issue\0", 6); } else if (tx_type == 4) { - os_memmove(&ui_context.line1, &"transfer\0", 9); + memmove(&tmp_ctx.signing_context.ui.line1, &"transfer\0", 9); } else if (tx_type == 5) { - os_memmove(&ui_context.line1, &"reissue\0", 8); + memmove(&tmp_ctx.signing_context.ui.line1, &"reissue\0", 8); } else if (tx_type == 6) { - os_memmove(&ui_context.line1, &"burn\0", 5); + memmove(&tmp_ctx.signing_context.ui.line1, &"burn\0", 5); } else if (tx_type == 8) { - os_memmove(&ui_context.line1, &"start leasing\0", 14); + memmove(&tmp_ctx.signing_context.ui.line1, &"start leasing\0", 14); } else if (tx_type == 9) { - os_memmove(&ui_context.line1, &"cancel leasing\0", 15); + memmove(&tmp_ctx.signing_context.ui.line1, &"cancel leasing\0", 15); } else if (tx_type == 10) { - os_memmove(&ui_context.line2, &"Transaction Hash\0", 17); - os_memmove(&ui_context.line1, &"creating an alias\0", 18); + memmove(&tmp_ctx.signing_context.ui.line2, &"Transaction Hash\0", 17); + memmove(&tmp_ctx.signing_context.ui.line1, &"creating an alias\0", 18); } else if (tx_type == 11) { - os_memmove(&ui_context.line1, &"mass transfer\0", 14); + memmove(&tmp_ctx.signing_context.ui.line1, &"mass transfer\0", 14); } else if (tx_type == 12) { - os_memmove(&ui_context.line1, &"data\0", 5); + memmove(&tmp_ctx.signing_context.ui.line1, &"data\0", 5); } else if (tx_type == 13) { - os_memmove(&ui_context.line1, &"set script\0", 11); + memmove(&tmp_ctx.signing_context.ui.line1, &"set script\0", 11); } else if (tx_type == 14) { - os_memmove(&ui_context.line1, &"sponsorship\0", 12); + memmove(&tmp_ctx.signing_context.ui.line1, &"sponsorship\0", 12); } else if (tx_type == 15) { - os_memmove(&ui_context.line1, &"asset script\0", 13); + memmove(&tmp_ctx.signing_context.ui.line1, &"asset script\0", 13); } else if (tx_type == 16) { - os_memmove(&ui_context.line1, &"script invocation\0", 18); + memmove(&tmp_ctx.signing_context.ui.line1, &"script invocation\0", 18); } else if (tx_type == 17) { - os_memmove(&ui_context.line1, &"update asset info\0", 18); + memmove(&tmp_ctx.signing_context.ui.line1, &"update asset info\0", 18); } else if (tx_type > 200) { // type byte >200 are 'reserved', it will not be signed - os_memmove(&ui_context.line2, &"Hash\0", 5); + memmove(&tmp_ctx.signing_context.ui.line2, &"Hash\0", 5); if (tx_type == 252) { - os_memmove(&ui_context.line1, &"order\0", 6); + memmove(&tmp_ctx.signing_context.ui.line1, &"order\0", 6); } else if (tx_type == 253) { - os_memmove(&ui_context.line1, &"data\0", 5); + memmove(&tmp_ctx.signing_context.ui.line1, &"data\0", 5); } else if (tx_type == 254) { - os_memmove(&ui_context.line1, &"request\0", 8); + memmove(&tmp_ctx.signing_context.ui.line1, &"request\0", 8); } else if (tx_type == 255) { - os_memmove(&ui_context.line1, &"message\0", 8); + memmove(&tmp_ctx.signing_context.ui.line1, &"message\0", 8); } else { - os_memmove(&ui_context.line1, &"something\0", 10); + memmove(&tmp_ctx.signing_context.ui.line1, &"something\0", 10); } } - if (strlen((const char *)ui_context.line1) == 0) { - os_memmove(&ui_context.line1, &"transaction\0", 12); - } - // id should be calculated on sign step - size_t length = 45; - if (!b58enc((char *)ui_context.line3, &length, (const void *)&ui_context.id, - 32)) { - THROW(SW_CONDITIONS_NOT_SATISFIED); + if (strlen((const char *)tmp_ctx.signing_context.ui.line1) == 0) { + memmove(&tmp_ctx.signing_context.ui.line1, &"transaction\0", 12); } // Get the public key and return it. @@ -154,24 +151,249 @@ void build_other_data_ui() { THROW(INVALID_PARAMETER); } - waves_public_key_to_address( - public_key.W, tmp_ctx.signing_context.network_byte, ui_context.line4); + memmove(&tmp_ctx.signing_context.ui.from, public_key.W, 32); + tmp_ctx.signing_context.ui.finished = true; +} + +// getting message type based on tx type and version +int getMessageType() { + unsigned char tx_type = tmp_ctx.signing_context.data_type; + unsigned char tx_ver = tmp_ctx.signing_context.data_version; + // just one step here + if (tx_type == 3) { + if (tx_ver <= 2) { + return BYTE_DATA; + } else if (tx_ver >= 3) { + return PROTOBUF_DATA; + } + } else if (tx_type == 4) { + if (tx_ver <= 2) { + return BYTE_DATA; + } else if (tx_ver >= 3) { + return PROTOBUF_DATA; + } + } else if (tx_type == 5) { + if (tx_ver <= 2) { + return BYTE_DATA; + } else if (tx_ver >= 3) { + return PROTOBUF_DATA; + } + } else if (tx_type == 6) { + if (tx_ver <= 2) { + return BYTE_DATA; + } else if (tx_ver >= 3) { + return PROTOBUF_DATA; + } + } else if (tx_type == 8) { + if (tx_ver <= 2) { + return BYTE_DATA; + } else if (tx_ver >= 3) { + return PROTOBUF_DATA; + } + } else if (tx_type == 9) { + if (tx_ver <= 2) { + return BYTE_DATA; + } else if (tx_ver >= 3) { + return PROTOBUF_DATA; + } + } else if (tx_type == 10) { + if (tx_ver <= 2) { + return BYTE_DATA; + } else if (tx_ver >= 3) { + return PROTOBUF_DATA; + } + } else if (tx_type == 11) { + if (tx_ver == 1) { + return BYTE_DATA; + } else if (tx_ver >= 2) { + return PROTOBUF_DATA; + } + } else if (tx_type == 12) { + if (tx_ver == 1) { + return BYTE_DATA; + } else if (tx_ver >= 2) { + return PROTOBUF_DATA; + } + } else if (tx_type == 13) { + if (tx_ver == 1) { + return BYTE_DATA; + } else if (tx_ver >= 2) { + return PROTOBUF_DATA; + } + } else if (tx_type == 14) { + if (tx_ver == 1) { + return BYTE_DATA; + } else if (tx_ver >= 2) { + return PROTOBUF_DATA; + } + } else if (tx_type == 15) { + if (tx_ver == 1) { + return BYTE_DATA; + } else if (tx_ver >= 2) { + return PROTOBUF_DATA; + } + } else if (tx_type == 16) { + if (tx_ver == 1) { + return BYTE_DATA; + } else if (tx_ver >= 2) { + return PROTOBUF_DATA; + } + } else if (tx_type == 17) { + return PROTOBUF_DATA; + } else if (tx_type > 200) { + if (tx_type == 252) { + if (tx_ver <= 3) { + return BYTE_DATA; + } else if (tx_ver >= 4) { + return PROTOBUF_DATA; + } + } else if (tx_type == 253) { + return BYTE_DATA; + } else if (tx_type == 254) { + return BYTE_DATA; + } else if (tx_type == 255) { + return BYTE_DATA; + } else { + return BYTE_DATA; + } + } + THROW(SW_INCORRECT_TRANSACTION_TYPE_VERSION); } void make_allowed_ui_steps(bool is_last) { + uint8_t start_index; + uint8_t chunk_size; PRINTF("make_allowed_ui_steps start\n"); - if (tmp_ctx.signing_context.data_type == 4) { - uint8_t chunk_data_size = G_io_apdu_buffer[4]; - if (tmp_ctx.signing_context.chunk == 0) { - chunk_data_size -= 28; - } - while ( - (chunk_data_size - ui_context.chunk_used > 0 && ui_context.step < 15) || - (ui_context.step == 15 && !ui_context.finished && is_last)) { - build_transfer_ui_step(is_last); - } - } else if (is_last) { - build_other_data_ui(); + if (tmp_ctx.signing_context.message_type == PROTOBUF_DATA) { // if protobuf + if (is_last && G_io_apdu_buffer[4] == tmp_ctx.signing_context.chunk_used && + tmp_ctx.signing_context.step == 6) { + THROW(SW_DEPRECATED_SIGN_PROTOCOL); + } + if (tmp_ctx.signing_context.ui.finished != true) { + start_index = 5 + tmp_ctx.signing_context.chunk_used; + chunk_size = G_io_apdu_buffer[4] - tmp_ctx.signing_context.chunk_used; + if (tmp_ctx.signing_context.chunk == 0) { + start_index += 29; + chunk_size -= 29; + } + if (tmp_ctx.signing_context.data_type == 252) { + if (tmp_ctx.signing_context.step == 6) { + build_protobuf_order(&tmp_ctx.signing_context.ui.proto, + G_io_apdu_buffer + start_index, chunk_size, + tmp_ctx.signing_context.data_size, start_index); + memset(&tmp_ctx.signing_context.ui.proto.data, 0, 64); + cx_hash(&tmp_ctx.signing_context.ui.hash_ctx.header, CX_LAST, NULL, 0, + tmp_ctx.signing_context.ui.proto.data, 32); + // check view data eq to signed data + if (memcmp(&tmp_ctx.signing_context.first_data_hash, + &tmp_ctx.signing_context.ui.proto.data, 32) != 0) { + THROW(SW_SIGN_DATA_NOT_MATCH); + } + } + //not parse 4 tx data because no child message in order proto message + if (is_last) { + tmp_ctx.signing_context.step = 8; + tmp_ctx.signing_context.ui.finished = true; + return; + } else { + THROW(SW_OK); + } + + } else { + build_protobuf_root_tx(&tmp_ctx.signing_context.ui.proto, + G_io_apdu_buffer + start_index, chunk_size, + tmp_ctx.signing_context.data_size, start_index); + memset(&tmp_ctx.signing_context.ui.proto.data, 0, 64); + cx_hash(&tmp_ctx.signing_context.ui.hash_ctx.header, CX_LAST, NULL, 0, + tmp_ctx.signing_context.ui.proto.data, 32); + // check view data eq to signed data + if (memcmp(&tmp_ctx.signing_context.first_data_hash, + &tmp_ctx.signing_context.ui.proto.data, 32) != 0) { + THROW(SW_SIGN_DATA_NOT_MATCH); + } + memset(&tmp_ctx.signing_context.ui.proto, 0, + sizeof(tmp_ctx.signing_context.ui.proto)); + memset(&tmp_ctx.signing_context.ui.hash_ctx, 0, + sizeof(tmp_ctx.signing_context.ui.hash_ctx)); + cx_blake2b_init(&tmp_ctx.signing_context.ui.hash_ctx, 256); + build_protobuf_child_tx( + &tmp_ctx.signing_context.ui.proto, + G_io_apdu_buffer + 5 + tmp_ctx.signing_context.sign_from, + G_io_apdu_buffer[4] - tmp_ctx.signing_context.sign_from, + tmp_ctx.signing_context.data_size); + } + memset(&tmp_ctx.signing_context.ui.proto.data, 0, 64); + cx_hash(&tmp_ctx.signing_context.ui.hash_ctx.header, CX_LAST, NULL, 0, + tmp_ctx.signing_context.ui.proto.data, 32); + // check view data eq to signed data + if (memcmp(&tmp_ctx.signing_context.first_data_hash, + &tmp_ctx.signing_context.ui.proto.data, 32) != 0) { + THROW(SW_SIGN_DATA_NOT_MATCH); + } + } else { + THROW(SW_INS_NOT_SUPPORTED); + } + } else { + if (tmp_ctx.signing_context.ui.byte.step == 0 && + tmp_ctx.signing_context.step == 6) { + if (is_last && + G_io_apdu_buffer[4] == tmp_ctx.signing_context.chunk_used) { + THROW(SW_DEPRECATED_SIGN_PROTOCOL); + } + start_index = tmp_ctx.signing_context.chunk_used; + // if all data in one apdu move start index on 29 bytes to skip options + // data + if (tmp_ctx.signing_context.chunk == 0) { + start_index += 29; + } + } else { + start_index = tmp_ctx.signing_context.ui.byte.chunk_used; + } + if (tmp_ctx.signing_context.step == 6) { + if (tmp_ctx.signing_context.data_type == 4) { + uint8_t chunk_data_size = G_io_apdu_buffer[4]; + while ( + (chunk_data_size - tmp_ctx.signing_context.ui.byte.chunk_used > 0 && + tmp_ctx.signing_context.ui.byte.step < 15) || + (tmp_ctx.signing_context.ui.byte.step == 15 && + !tmp_ctx.signing_context.ui.finished)) { + build_transfer_ui_step(); + } + } else { + tmp_ctx.signing_context.ui.byte.step++; + } + uint8_t hash_data_size = G_io_apdu_buffer[4] - start_index; + bool last_hash = false; + if (tmp_ctx.signing_context.ui.byte.total_received + hash_data_size >= + tmp_ctx.signing_context.data_size) { + hash_data_size = tmp_ctx.signing_context.data_size - + tmp_ctx.signing_context.ui.byte.total_received; + last_hash = true; + tmp_ctx.signing_context.ui.byte.total_received = 0; + if (tmp_ctx.signing_context.data_type != 4) { + build_other_data_ui(); + tmp_ctx.signing_context.step = 7; + } + } + tmp_ctx.signing_context.ui.byte.total_received += hash_data_size; + cx_hash(&tmp_ctx.signing_context.ui.hash_ctx.header, CX_NONE, + G_io_apdu_buffer + 5 + start_index, hash_data_size, NULL, 0); + if (last_hash) { + memset(&tmp_ctx.signing_context.ui.byte.buffer, 0, 64); + cx_hash(&tmp_ctx.signing_context.ui.hash_ctx.header, CX_LAST, NULL, 0, + tmp_ctx.signing_context.ui.byte.buffer, 32); + // check view data eq to signed data + if (memcmp(&tmp_ctx.signing_context.first_data_hash, + &tmp_ctx.signing_context.ui.byte.buffer, 32) != 0) { + THROW(SW_SIGN_DATA_NOT_MATCH); + } + } + } + if (is_last) { + tmp_ctx.signing_context.step = 8; + } + + tmp_ctx.signing_context.ui.byte.chunk_used = 0; } PRINTF("make_allowed_ui_steps end\n"); } @@ -202,9 +424,122 @@ void show_sign_ui() { } } +void show_sign_protobuf_ui() { + unsigned char tx_type = tmp_ctx.signing_context.data_type; + ux_step = 0; + ui_state = UI_VERIFY; + if (tx_type == 3) { + ux_step_count = 10; +#if defined(TARGET_BLUE) + UX_DISPLAY(ui_verify_issue_blue, NULL); +#else + ux_flow_init(0, ux_issue_flow, NULL); +#endif // #if TARGET_ID + } else if (tx_type == 4) { + ux_step_count = 9; +#if defined(TARGET_BLUE) + UX_DISPLAY(ui_verify_transfer_blue, NULL); +#else + ux_flow_init(0, ux_transfer_flow, NULL); +#endif // #if TARGET_ID + } else if (tx_type == 5) { + ux_step_count = 7; +#if defined(TARGET_BLUE) + UX_DISPLAY(ui_verify_reissue_blue, NULL); +#else + ux_flow_init(0, ux_reissue_flow, NULL); +#endif // #if TARGET_ID + } else if (tx_type == 6) { + ux_step_count = 7; +#if defined(TARGET_BLUE) + UX_DISPLAY(ui_verify_burn_blue, NULL); +#else + ux_flow_init(0, ux_burn_flow, NULL); +#endif // #if TARGET_ID + } else if (tx_type == 8) { + ux_step_count = 7; +#if defined(TARGET_BLUE) + UX_DISPLAY(ui_verify_lease_blue, NULL); +#else + ux_flow_init(0, ux_lease_flow, NULL); +#endif // #if TARGET_ID + } else if (tx_type == 9) { + ux_step_count = 6; +#if defined(TARGET_BLUE) + UX_DISPLAY(ui_verify_cancel_lease_blue, NULL); +#else + ux_flow_init(0, ux_cancel_lease_flow, NULL); +#endif // #if TARGET_ID + } else if (tx_type == 10) { + ux_step_count = 6; +#if defined(TARGET_BLUE) + UX_DISPLAY(ui_verify_create_alias_blue, NULL); +#else + ux_flow_init(0, ux_create_alias_flow, NULL); +#endif // #if TARGET_ID + } else if (tx_type == 11) { + ux_step_count = 7; +#if defined(TARGET_BLUE) + UX_DISPLAY(ui_verify_masstransfer_blue, NULL); +#else + ux_flow_init(0, ux_masstransfer_flow, NULL); +#endif // #if TARGET_ID + } else if (tx_type == 12) { + ux_step_count = 5; +#if defined(TARGET_BLUE) + UX_DISPLAY(ui_verify_data_blue, NULL); +#else + ux_flow_init(0, ux_data_flow, NULL); +#endif // #if TARGET_ID + } else if (tx_type == 13) { + ux_step_count = 5; +#if defined(TARGET_BLUE) + UX_DISPLAY(ui_verify_set_ac_script_blue, NULL); +#else + ux_flow_init(0, ux_set_ac_script_flow, NULL); +#endif // #if TARGET_ID + } else if (tx_type == 14) { + ux_step_count = 7; +#if defined(TARGET_BLUE) + UX_DISPLAY(ui_verify_sponsorship_blue, NULL); +#else + ux_flow_init(0, ux_sponsorship_flow, NULL); +#endif // #if TARGET_ID + } else if (tx_type == 15) { + ux_step_count = 6; +#if defined(TARGET_BLUE) + UX_DISPLAY(ui_verify_set_as_script_blue, NULL); +#else + ux_flow_init(0, ux_set_as_script_flow, NULL); +#endif // #if TARGET_ID + } else if (tx_type == 16) { + ux_step_count = 11; +#if defined(TARGET_BLUE) + UX_DISPLAY(ui_verify_invoke_blue, NULL); +#else + ux_flow_init(0, ux_invoke_flow, NULL); +#endif // #if TARGET_ID + } else if (tx_type == 17) { + ux_step_count = 8; +#if defined(TARGET_BLUE) + UX_DISPLAY(ui_verify_update_asset_blue, NULL); +#else + ux_flow_init(0, ux_update_asset_flow, NULL); +#endif // #if TARGET_ID + } else if (tx_type == 252) { + ux_step_count = 8; +#if defined(TARGET_BLUE) + UX_DISPLAY(ui_verify_order_blue, NULL); +#else + ux_flow_init(0, ux_order_flow, NULL); +#endif // #if TARGET_ID + } +} + void show_processing() { #if defined(TARGET_BLUE) - UX_DISPLAY(ui_processing_blue, NULL); +// this freeze device after pb update +// UX_DISPLAY(ui_processing_blue, NULL); #else ux_flow_init(0, ux_processing_flow, NULL); #endif diff --git a/src/ui/ui.h b/src/ui/ui.h index 28751631..e4ea8690 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -23,6 +23,7 @@ #include "os.h" #include "cx.h" +#include "ux.h" #include #include "../main.h" #include "../crypto/ledger_crypto.h" @@ -46,8 +47,10 @@ extern int ux_step_count; void make_allowed_ui_steps(bool is_last); void show_sign_ui(); +void show_sign_protobuf_ui(); void menu_address_init(); void show_processing(); +int getMessageType(); void try_to_fill_buffer(uint8_t chunk_data_start_index, uint8_t chunk_data_size); diff --git a/src/ui/ui_logic.c b/src/ui/ui_logic.c index 48e46f75..362a022a 100644 --- a/src/ui/ui_logic.c +++ b/src/ui/ui_logic.c @@ -21,6 +21,7 @@ #include "ui_logic.h" #include "main.h" #include "ui.h" +#include "ux.h" // UI unsigned int io_seproxyhal_touch_address_ok(const bagl_element_t *e) { diff --git a/src/ui/ui_logic.h b/src/ui/ui_logic.h index 2132344e..ab33b8d9 100644 --- a/src/ui/ui_logic.h +++ b/src/ui/ui_logic.h @@ -22,6 +22,7 @@ #define __UI_LOGIC_H__ #include "os_io_seproxyhal.h" +#include "ux.h" unsigned int io_seproxyhal_touch_address_ok(const bagl_element_t *e); unsigned int io_seproxyhal_cancel(const bagl_element_t *e);