From b67734867e1a1698376e77d7cdf87e08e6137b3d Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Thu, 15 Jul 2021 18:23:53 +0800 Subject: [PATCH 01/27] Update combined.proto.txt --- protob/combined.proto.txt | 655 ++++++++++++++++++++++++-------------- 1 file changed, 421 insertions(+), 234 deletions(-) diff --git a/protob/combined.proto.txt b/protob/combined.proto.txt index 6e1f0bb..ad25a88 100644 --- a/protob/combined.proto.txt +++ b/protob/combined.proto.txt @@ -1,5 +1,7 @@ syntax = "proto2"; -import "google/protobuf/descriptor.proto.txt"; +import "google/protobuf/descriptor.proto"; + +// Sugar for easier handling in Java /** * Request: Ask the device for a Binance address. @@ -40,7 +42,7 @@ message BinancePublicKey { /** * Request: Starts the Binance transaction protocol flow. - * A transaction consists of these common fields and a series of BinanceMsg messages. + * A transaction consists of these common fields and a series of BinanceMsg messages. * These parts form a JSON structure (a string) in Trezor's memory, which is signed to produce a BinanceSignedTx. * @start * @next BinanceTxRequest @@ -67,6 +69,7 @@ message BinanceTxRequest { /** * Request: Ask the device to include a Binance transfer msg in the tx. + * @next BinanceTxRequest * @next BinanceSignedTx * @next Failure */ @@ -87,6 +90,7 @@ message BinanceTransferMsg { /** * Request: Ask the device to include a Binance order msg in the tx. + * @next BinanceTxRequest * @next BinanceSignedTx * @next Failure */ @@ -123,6 +127,7 @@ message BinanceOrderMsg { /** * Request: Ask the device to include a Binance cancel msg in the tx. + * @next BinanceTxRequest * @next BinanceSignedTx * @next Failure */ @@ -139,6 +144,7 @@ message BinanceCancelMsg { message BinanceSignedTx { optional bytes signature = 1; optional bytes public_key = 2; + optional string json = 3; } @@ -530,8 +536,6 @@ message CardanoSignedTx { optional bytes tx_body = 2; // serialised body of the signed transaction } -// Sugar for easier handling in Java - /** * Response: Success of the previous request * @end @@ -560,7 +564,6 @@ message Failure { Failure_NotEnoughFunds = 10; Failure_NotInitialized = 11; Failure_PinMismatch = 12; - Failure_WipeCodeMismatch = 13; Failure_FirmwareError = 99; } } @@ -572,6 +575,7 @@ message Failure { */ message ButtonRequest { optional ButtonRequestType code = 1; + optional string data = 2; /** * Type of button request */ @@ -591,9 +595,6 @@ message ButtonRequest { ButtonRequest_MnemonicInput = 13; ButtonRequest_PassphraseType = 14; ButtonRequest_UnknownDerivationPath = 15; - ButtonRequest_RecoveryHomepage = 16; - ButtonRequest_Success = 17; - ButtonRequest_Warning = 18; ButtonRequest_EnterPinOnDevice = 101; ButtonRequest_EnterNewPinOnDevice = 102; ButtonRequest_ReEnterNewPinOnDevice = 103; @@ -622,8 +623,6 @@ message PinMatrixRequest { PinMatrixRequestType_Current = 1; PinMatrixRequestType_NewFirst = 2; PinMatrixRequestType_NewSecond = 3; - PinMatrixRequestType_WipeCodeFirst = 4; - PinMatrixRequestType_WipeCodeSecond = 5; } } @@ -811,33 +810,12 @@ message CosiSignature { /** * Request: "Press" the button on the device * @start - * @next DebugLinkLayout + * @next Success */ message DebugLinkDecision { optional bool yes_no = 1; // true for "Confirm", false for "Cancel" - optional DebugSwipeDirection swipe = 2; // swipe direction + optional bool up_down = 2; // true for scroll up, false for scroll down optional string input = 3; // keyboard input - /** - * Structure representing swipe direction - */ - enum DebugSwipeDirection { - UP = 0; - DOWN = 1; - LEFT = 2; - RIGHT = 3; - } - - optional uint32 x = 4; // touch X coordinate - optional uint32 y = 5; // touch Y coordinate - optional bool wait = 6; // wait for layout change -} - -/** - * Response: Device text layout - * @end - */ -message DebugLinkLayout { - repeated string lines = 1; } /** @@ -846,9 +824,6 @@ message DebugLinkLayout { * @next DebugLinkState */ message DebugLinkGetState { - optional bool wait_word_list = 1; // Trezor T only - wait until mnemonic words are shown - optional bool wait_word_pos = 2; // Trezor T only - wait until reset word position is requested - optional bool wait_layout = 3; // wait until current layout changes } /** @@ -868,7 +843,6 @@ message DebugLinkState { optional uint32 recovery_word_pos = 10; // index of mnemonic word the device is expecting during RecoveryDevice workflow optional uint32 reset_word_pos = 11; // index of mnemonic word the device is expecting during ResetDevice workflow optional uint32 mnemonic_type = 12; // current mnemonic type (BIP-39/SLIP-39) - repeated string layout_lines = 13; // current layout text } /** @@ -1204,7 +1178,9 @@ message EosTxActionAck { * @end */ message EosSignedTx { - optional string signature = 1; // Computed signature + optional uint32 signature_v = 1; // Computed signature (recovery parameter, limited to 31 or 32) + optional bytes signature_r = 2; // Computed signature R component (256 bit) + optional bytes signature_s = 3; // Computed signature S component (256 bit) } // Sugar for easier handling in Java @@ -1475,14 +1451,6 @@ message LiskVerifyMessage { // Sugar for easier handling in Java -/** - * Type of the mnemonic backup given/received by the device during reset/recovery. - */ -enum BackupType { - Bip39 = 0; // also called "Single Backup", see BIP-0039 - Slip39_Basic = 1; // also called "Shamir Backup", see SLIP-0039 - Slip39_Advanced = 2; // also called "Super Shamir" or "Shamir with Groups", see SLIP-0039#two-level-scheme -} /** * Request: Reset device to default state and ask for device details @@ -1507,7 +1475,7 @@ message GetFeatures { * @end */ message Features { - optional string vendor = 1; // name of the manufacturer, e.g. "prokey.io" + optional string vendor = 1; // name of the manufacturer, e.g. "trezor.io" optional uint32 major_version = 2; // major version of the firmware/bootloader, e.g. 1 optional uint32 minor_version = 3; // minor version of the firmware/bootloader, e.g. 0 optional uint32 patch_version = 4; // patch version of the firmware/bootloader, e.g. 0 @@ -1534,34 +1502,10 @@ message Features { optional bytes fw_vendor_keys = 26; // reported firmware vendor keys (their hash) optional bool unfinished_backup = 27; // report unfinished backup (equals to Storage.unfinished_backup) optional bool no_backup = 28; // report no backup (equals to Storage.no_backup) - optional bool recovery_mode = 29; // is recovery mode in progress - repeated Capability capabilities = 30; // list of supported capabilities - enum Capability { - Capability_Bitcoin = 1; - Capability_Bitcoin_like = 2; // Altcoins based on the Bitcoin source code - Capability_Binance = 3; - Capability_Cardano = 4; - Capability_Crypto = 5; // generic crypto operations for GPG, SSH, etc. - Capability_EOS = 6; - Capability_Ethereum = 7; - Capability_Lisk = 8; - Capability_Monero = 9; - Capability_NEM = 10; - Capability_Ripple = 11; - Capability_Stellar = 12; - Capability_Tezos = 13; - Capability_U2F = 14; - Capability_Shamir = 15; - Capability_ShamirGroups = 16; - } - optional BackupType backup_type = 31; // type of device backup (BIP-39 / SLIP-39 basic / SLIP-39 advanced) - optional bool sd_card_present = 32; // is SD card present - optional bool sd_protection = 33; // is SD Protect enabled - optional bool wipe_code_protection = 34; // is wipe code protection enabled - optional bool pin_on_device = 100; - optional uint32 view_major_version = 101; - optional uint32 view_minor_version = 102; - optional uint32 view_patch_version = 103; + optional bool pin_on_device = 100; // Support pin on device + optional uint32 view_major_version = 101; // major version of the firmware to show in UI + optional uint32 view_minor_version = 102; // minor version of the firmware to show in UI + optional uint32 view_patch_version = 103; // patch version of the firmware to show in UI } /** @@ -1616,34 +1560,6 @@ message ChangePin { optional bool remove = 1; // is PIN removal requested? } -/** - * Request: Starts workflow for setting/removing the wipe code - * @start - * @next Success - * @next Failure - */ -message ChangeWipeCode { - optional bool remove = 1; // is wipe code removal requested? -} - -/** - * Request: Starts workflow for enabling/regenerating/disabling SD card protection - * @start - * @next Success - * @next Failure - */ -message SdProtect { - optional SdProtectOperationType operation = 1; - /** - * Structure representing SD card protection operation - */ - enum SdProtectOperationType { - DISABLE = 0; - ENABLE = 1; - REFRESH = 2; - } -} - /** * Request: Test if the device is alive, device sends back the message in Success response * @start @@ -1698,15 +1614,14 @@ message WipeDevice { * @next Failure */ message LoadDevice { - repeated string mnemonics = 1; // seed encoded as mnemonic (12, 18 or 24 words for BIP39, 20 or 33 for SLIP39) + optional string mnemonic = 1; // seed encoded as BIP-39 mnemonic (12, 18 or 24 words) + optional HDNodeType node = 2; // BIP-32 node optional string pin = 3; // set PIN protection optional bool passphrase_protection = 4; // enable master node encryption using passphrase optional string language = 5 [default='english']; // device language optional string label = 6; // device label optional bool skip_checksum = 7; // do not test mnemonic for valid BIP-39 checksum optional uint32 u2f_counter = 8; // U2F counter - optional bool needs_backup = 9; // set "needs backup" flag - optional bool no_backup = 10; // indicate that no backup is going to be made } /** @@ -1716,16 +1631,15 @@ message LoadDevice { * @next Failure */ message ResetDevice { - optional bool display_random = 1; // display entropy generated by the device before asking for additional entropy - optional uint32 strength = 2 [default=256]; // strength of seed in bits - optional bool passphrase_protection = 3; // enable master node encryption using passphrase - optional bool pin_protection = 4; // enable PIN protection - optional string language = 5 [default='english']; // device language - optional string label = 6; // device label - optional uint32 u2f_counter = 7; // U2F counter - optional bool skip_backup = 8; // postpone seed backup to BackupDevice workflow - optional bool no_backup = 9; // indicate that no backup is going to be made - optional BackupType backup_type = 10 [default=Bip39]; // type of the mnemonic backup + optional bool display_random = 1; // display entropy generated by the device before asking for additional entropy + optional uint32 strength = 2 [default=256]; // strength of seed in bits + optional bool passphrase_protection = 3; // enable master node encryption using passphrase + optional bool pin_protection = 4; // enable PIN protection + optional string language = 5 [default='english']; // device language + optional string label = 6; // device label + optional uint32 u2f_counter = 7; // U2F counter + optional bool skip_backup = 8; // postpone seed backup to BackupDevice workflow + optional bool no_backup = 9; // indicate that no backup is going to be made } /** @@ -1816,23 +1730,7 @@ message WordAck { * @next Success */ message SetU2FCounter { - optional uint32 u2f_counter = 1; -} - -/** - * Request: Set U2F counter - * @start - * @next NextU2FCounter - */ -message GetNextU2FCounter { -} - -/** - * Request: Set U2F counter - * @end - */ -message NextU2FCounter { - optional uint32 u2f_counter = 1; + optional uint32 u2f_counter = 1; // counter } // Sugar for easier handling in Java @@ -1913,7 +1811,6 @@ message MoneroGetAddress { optional uint32 network_type = 3; // Main-net / testnet / stagenet optional uint32 account = 4; // Major subaddr index optional uint32 minor = 5; // Minor subaddr index - optional bytes payment_id = 6; // Payment ID for integrated address } /** @@ -2027,7 +1924,7 @@ message MoneroTransactionInputsPermutationAck { * @next MoneroTransactionInputViniAck */ message MoneroTransactionInputViniRequest { - optional MoneroTransactionSourceEntry src_entr = 1; + optional MoneroTransactionSourceEntry src_entr = 1; optional bytes vini = 2; // xmrtypes.TxinToKey optional bytes vini_hmac = 3; optional bytes pseudo_out = 4; @@ -2531,14 +2428,200 @@ message NEMDecryptedMessage { // Sugar for easier handling in Java +/** + * Ontology Transaction + * @embed + */ +message OntologyTransaction { + optional uint32 version = 1; + optional uint32 type = 2; + optional uint32 nonce = 3; + optional uint64 gas_price = 4; + optional uint64 gas_limit = 5; + optional string payer = 6; + repeated OntologyTxAttribute tx_attributes = 7; + /** + * Attribute of Ontology transaction + */ + message OntologyTxAttribute { + optional uint32 usage = 1; + optional bytes data = 2; + } +} + +/** + * Request: Ask device for Ontology public key corresponding to address_n path + * @start + * @next OntologyPublicKey + */ +message OntologyGetPublicKey { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bool show_display = 2; // Optionally show on display before sending the result +} + +/** + * Response: Contains Ontology public key derived from device private seed + * @end + */ +message OntologyPublicKey { + optional bytes public_key = 1; // Ontology public key +} + +/** + * Request: Ask device for Ontology address corresponding to address_n path + * @start + * @next OntologyAddress + */ +message OntologyGetAddress { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bool show_display = 2; // Optionally show on display before sending the result +} + +/** + * Response: Contains Ontology address derived from device private seed + * @end + */ +message OntologyAddress { + optional string address = 1; // Ontology address +} + +/** + * Request: Ask device to sign Ontology transfer + * @start + * @next OntologySignedTransfer + */ +message OntologySignTransfer { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional OntologyTransaction transaction = 2; + optional OntologyTransfer transfer = 3; + /** + * Ontology Transfer + */ + message OntologyTransfer { + optional OntologyAsset asset = 1; + optional uint64 amount = 2; + optional string from_address = 3; + optional string to_address = 4; + /** + * Ontology Asset + */ + enum OntologyAsset { + ONT = 1; + ONG = 2; + } + } +} + +/** + * Response: Contains Ontology transfer signature + * @end + */ +message OntologySignedTransfer { + optional bytes signature = 1; + optional bytes payload = 2; +} + +/** + * Request: Ask device to sign Ontology ONG withdrawal + * @start + * @next OntologySignedWithdrawOng + */ +message OntologySignWithdrawOng { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional OntologyTransaction transaction = 2; + optional OntologyWithdrawOng withdraw_ong = 3; + /** + * Ontology ONG Withdrawal + */ + message OntologyWithdrawOng { + optional uint64 amount = 1; + optional string from_address = 2; + optional string to_address = 3; + } +} + +/** + * Response: Contains Ontology ONG withdrawal signature + * @end + */ +message OntologySignedWithdrawOng { + optional bytes signature = 1; + optional bytes payload = 2; +} + +/** + * Request: Ask device to sign Ontology ONT ID registration + * @start + * @next OntologySignedOntIdRegister + */ +message OntologySignOntIdRegister { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional OntologyTransaction transaction = 2; + optional OntologyOntIdRegister ont_id_register = 3; + /** + * Ontology ONT ID registration + */ + message OntologyOntIdRegister { + optional string ont_id = 1; + optional bytes public_key = 2; + } +} + +/** + * Response: Contains Ontology ONT ID registration signature + * @end + */ +message OntologySignedOntIdRegister { + optional bytes signature = 1; + optional bytes payload = 2; +} + +/** + * Request: Ask device to sign Ontology ONT ID attributes adding + * @start + * @next OntologySignedOntIdAddAttributes + */ +message OntologySignOntIdAddAttributes { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional OntologyTransaction transaction = 2; + optional OntologyOntIdAddAttributes ont_id_add_attributes = 3; + /** + * Ontology ONT ID attributes adding + */ + message OntologyOntIdAddAttributes { + optional string ont_id = 1; + optional bytes public_key = 2; + repeated OntologyOntIdAttribute ont_id_attributes = 3; + /** + * Attribute of Ontology ONT ID + */ + message OntologyOntIdAttribute { + optional string key = 1; + optional string type = 2; + optional string value = 3; + } + } +} + +/** + * Response: Contains Ontology ONT ID attributes adding signature + * @end + */ +message OntologySignedOntIdAddAttributes { + optional bytes signature = 1; + optional bytes payload = 2; +} + +// Sugar for easier handling in Java + /** * Request: Address at the specified index * @start * @next RippleAddress */ message RippleGetAddress { - repeated uint32 address_n = 1; // BIP-32 path. For compatibility with other wallets, must be m/44'/144'/index' - optional bool show_display = 2; // optionally show on display before sending the result + repeated uint32 address_n = 1; // BIP-32 path. For compatibility with other wallets, must be m/44'/144'/index' + optional bool show_display = 2; // optionally show on display before sending the result } /** @@ -2546,7 +2629,7 @@ message RippleGetAddress { * @end */ message RippleAddress { - optional string address = 1; // Address in Ripple format (base58 of a pubkey with checksum) + optional string address = 1; // Address in Ripple format (base58 of a pubkey with checksum) } /** @@ -2555,24 +2638,24 @@ message RippleAddress { * @next RippleSignedTx */ message RippleSignTx { - repeated uint32 address_n = 1; // BIP-32 path. For compatibility with other wallets, must be m/44'/144'/index' - optional uint64 fee = 2; // fee (in drops) for the transaction - optional uint32 flags = 3; // transaction flags - optional uint32 sequence = 4; // transaction sequence number - optional uint32 last_ledger_sequence = 5; // see https://developers.ripple.com/reliable-transaction-submission.html#lastledgersequence - optional RipplePayment payment = 6; // Payment transaction type - - /** - * Payment transaction type - * - simple A sends money to B - * - only a subset of fields is supported - * - see https://developers.ripple.com/payment.html - */ - message RipplePayment { - optional uint64 amount = 1; // only XRP is supported at the moment so this an integer - optional string destination = 2; // destination account address - optional uint32 destination_tag = 3; // destination tag to identify payments - } + repeated uint32 address_n = 1; // BIP-32 path. For compatibility with other wallets, must be m/44'/144'/index' + optional uint64 fee = 2; // fee (in drops) for the transaction + optional uint32 flags = 3; // transaction flags + optional uint32 sequence = 4; // transaction sequence number + optional uint32 last_ledger_sequence = 5; // see https://developers.ripple.com/reliable-transaction-submission.html#lastledgersequence + optional RipplePayment payment = 6; // Payment transaction type + + /** + * Payment transaction type + * - simple A sends money to B + * - only a subset of fields is supported + * - see https://developers.ripple.com/payment.html + */ + message RipplePayment { + optional uint64 amount = 1; // only XRP is supported at the moment so this an integer + optional string destination = 2; // destination account address + optional uint32 destination_tag = 3; // destination tag to identify payments + } } /** @@ -2580,8 +2663,8 @@ message RippleSignTx { * @end */ message RippleSignedTx { - optional bytes signature = 1; - optional bytes serialized_tx = 2; + optional bytes signature = 1; + optional bytes serialized_tx = 2; } // Sugar for easier handling in Java @@ -2874,7 +2957,7 @@ message TezosSignTx { * Structure representing information for reveal */ message TezosRevealOp { - optional bytes source = 7; + optional TezosContractID source = 1; optional uint64 fee = 2; optional uint64 counter = 3; optional uint64 gas_limit = 4; @@ -2885,7 +2968,7 @@ message TezosSignTx { * Structure representing information for transaction */ message TezosTransactionOp { - optional bytes source = 9; + optional TezosContractID source = 1; optional uint64 fee = 2; optional uint64 counter = 3; optional uint64 gas_limit = 4; @@ -2893,24 +2976,12 @@ message TezosSignTx { optional uint64 amount = 6; optional TezosContractID destination = 7; optional bytes parameters = 8; - optional TezosParametersManager parameters_manager = 10; - - message TezosParametersManager { - optional bytes set_delegate = 1; - optional bool cancel_delegate = 2; - optional TezosManagerTransfer transfer = 3; - - message TezosManagerTransfer { - optional TezosContractID destination = 1; - optional uint64 amount = 2; - } - } } /** * Structure representing information for origination */ message TezosOriginationOp { - optional bytes source = 12; + optional TezosContractID source = 1; optional uint64 fee = 2; optional uint64 counter = 3; optional uint64 gas_limit = 4; @@ -2926,7 +2997,7 @@ message TezosSignTx { * Structure representing information for delegation */ message TezosDelegationOp { - optional bytes source = 7; + optional TezosContractID source = 1; optional uint64 fee = 2; optional uint64 counter = 3; optional uint64 gas_limit = 4; @@ -2971,62 +3042,171 @@ message TezosSignedTx { // Sugar for easier handling in Java /** - * Request: List resident credentials + * Request: Ask device for Tron address corresponding to address_n path * @start - * @next WebAuthnCredentials + * @next TronAddress * @next Failure */ -message WebAuthnListResidentCredentials { +message TronGetAddress { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bool show_display = 2; // Optionally show on display before sending the result } /** - * Request: Add resident credential - * @start - * @next Success - * @next Failure + * Response: Contains Tron address derived from device private seed + * @end */ -message WebAuthnAddResidentCredential { - optional bytes credential_id = 1; +message TronAddress { + optional string address = 1; // Tron address (base58) } /** - * Request: Remove resident credential + * Request: Ask device to sign Tron transaction * @start - * @next Success - * @next Failure + * @next TronSignedTx */ -message WebAuthnRemoveResidentCredential { - optional uint32 index = 1; -} - +message TronSignTx { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + // Common part of transaction + optional uint64 timestamp = 2; // UTC timestamp + optional uint64 expiration = 3; // Transaction expiration + optional TronBlockHeader block_header = 4; // Now block data + optional TronContract contract = 6; // Contract messages + optional uint64 fee_limit = 8; // fee limit -/** - * Response: Resident credential list - * @start - * @next end - */ -message WebAuthnCredentials { - repeated WebAuthnCredential credentials = 1; - message WebAuthnCredential { - optional uint32 index = 1; - optional bytes id = 2; - optional string rp_id = 3; - optional string rp_name = 4; - optional bytes user_id = 5; - optional string user_name = 6; - optional string user_display_name = 7; - optional uint32 creation_time = 8; - optional bool hmac_secret = 9; - optional bool use_sign_count = 10; + message TronBlockHeader { + optional int64 timestamp = 1; + optional string tx_trie_root = 2; + optional string parent_hash = 3; + optional int64 number = 7; + optional string witness_address = 9; + optional int32 version = 10; } -} -message RebootDevice { - + /*** + * Tron Contracts Messages + * + */ + message TronContract { + // Update account name + message TronAccountUpdateContract { + optional string account_name = 1; // Account name is not unique + } + // Transfer TRX + message TronTransferContract { + optional string to_address = 1; // To address + optional uint64 amount = 2; // TRX amount in sun (10^-6) + } + // Transfer asset + message TronTransferAssetContract { + optional string asset_name = 1; // Asset name + optional string to_address = 2; // To address + optional uint64 amount = 3; // Amount to transfer + } + // Vote witness + message TronVoteWitnessContract { + message TronVote { + optional string vote_address = 1; // Candidate Address + optional uint64 vote_count = 2; // Amount of votes + } + repeated TronVote votes = 1; // votes + } + // Upgrade account to witness + message TronWitnessCreateContract { + optional string url = 1; // Witness URL + } + // Update witness URL + message TronWitnessUpdateContract { + optional string update_url = 2; // Witness URL + } + // Issue Asset + message TronAssetIssueContract { + message TronFrozenSupply { + optional uint64 frozen_amount = 1; // Amount frozen + optional uint64 frozen_days = 2; // Days from issue date + } + optional string name = 2; // Asset name + optional string abbr = 3; // Asset abbreviation + optional uint64 total_supply = 4; // Total supply including frozen + repeated TronFrozenSupply frozen_supply = 5; // Frozen supply + optional uint32 trx_num = 6; // Amount of TRX (exchange ratio) + optional uint32 num = 7; // Amount of tokens (exchange ratio) + optional uint64 start_time = 8; // Negotiation start date and time + optional uint64 end_time = 9; // Negotiation end date and time + optional string description = 10; // Asset description + optional string url = 11; // Asset URL + } + // Participate in an asset + message TronParticipateAssetIssueContract { + optional string to_address = 1; // Asset issuer address + optional string asset_name = 2; // The name of target asset + optional uint64 amount = 3; // TRX amount in sun + } + // Freeze TRX balance + message TronFreezeBalanceContract { + optional uint64 frozen_balance = 1; // Amount to freeze + optional uint64 frozen_duration = 2; // Freeze minimal duration in days + } + // Unfreeze TRX Balance + message TronUnfreezeBalanceContract { + } + // Unfreeze Asset Balance + message TronUnfreezeAssetContract { + } + // Withdraw witness balance + message TronWithdrawBalanceContract { + } + // Update Asset + message TronUpdateAssetContract { + optional string description = 1; // New description + optional string url = 2; // New URL + } + // Network proposal contract + message TronProposalCreateContract { + message TronProposalParameters { + optional uint64 key = 1; // Parameter key + optional uint64 value = 2; // Parameter value + } + repeated TronProposalParameters parameters = 1; // Parameter to be changed + } + // Approval contract + message TronProposalApproveContract { + optional uint64 proposal_id = 1; // Proposal ID + optional bool is_add_approval = 2; // Add or remove approval + } + // Delete proposal + message TronProposalDeleteContract { + optional uint64 proposal_id = 1; // Proposal ID + } + optional TronTransferContract transfer_contract = 1; + optional TronTransferAssetContract transfer_asset_contract = 2; + optional TronVoteWitnessContract vote_witness_contract = 4; + optional TronWitnessCreateContract witness_create_contract = 5; + optional TronAssetIssueContract asset_issue_contract = 6; + optional TronWitnessUpdateContract witness_update_contract = 8; + optional TronParticipateAssetIssueContract participate_asset_issue_contract = 9; + optional TronAccountUpdateContract account_update_contract = 10; + optional TronFreezeBalanceContract freeze_balance_contract = 11; + optional TronUnfreezeBalanceContract unfreeze_balance_contract = 12; + optional TronWithdrawBalanceContract withdraw_balance_contract = 13; + optional TronUnfreezeAssetContract unfreeze_asset_contract = 14; + optional TronUpdateAssetContract update_asset_contract = 15; + optional TronProposalCreateContract proposal_create_contract = 16; + optional TronProposalApproveContract proposal_approve_contract = 17; + optional TronProposalDeleteContract proposal_delete_contract = 18; + } +} + +/** + * Response: Contains Tron transaction signature + * @end + */ +message TronSignedTx { + optional bytes serialized_tx = 1; // Serialized transaction } /** - * Messages for Trezor communication + * Messages for TREZOR communication */ // Sugar for easier handling in Java @@ -3036,17 +3216,17 @@ message RebootDevice { * Options for specifying message direction and type of wire (normal/debug) */ extend google.protobuf.EnumValueOptions { - optional bool wire_in = 50002; // message can be transmitted via wire from PC to Trezor - optional bool wire_out = 50003; // message can be transmitted via wire from Trezor to PC - optional bool wire_debug_in = 50004; // message can be transmitted via debug wire from PC to Trezor - optional bool wire_debug_out = 50005; // message can be transmitted via debug wire from Trezor to PC - optional bool wire_tiny = 50006; // message is handled by Trezor when the USB stack is in tiny mode - optional bool wire_bootloader = 50007; // message is only handled by Trezor Bootloader - optional bool wire_no_fsm = 50008; // message is not handled by Trezor unless the USB stack is in tiny mode + optional bool wire_in = 50002; // message can be transmitted via wire from PC to TREZOR + optional bool wire_out = 50003; // message can be transmitted via wire from TREZOR to PC + optional bool wire_debug_in = 50004; // message can be transmitted via debug wire from PC to TREZOR + optional bool wire_debug_out = 50005; // message can be transmitted via debug wire from TREZOR to PC + optional bool wire_tiny = 50006; // message is handled by TREZOR when the USB stack is in tiny mode + optional bool wire_bootloader = 50007; // message is only handled by TREZOR Bootloader + optional bool wire_no_fsm = 50008; // message is not handled by TREZOR unless the USB stack is in tiny mode } /** - * Mapping between Trezor wire identifier (uint) and a protobuf message + * Mapping between TREZOR wire identifier (uint) and a protobuf message */ enum MessageType { @@ -3082,10 +3262,6 @@ enum MessageType { MessageType_WordAck = 47 [(wire_in) = true]; MessageType_GetFeatures = 55 [(wire_in) = true]; MessageType_SetU2FCounter = 63 [(wire_in) = true]; - MessageType_SdProtect = 79 [(wire_in) = true]; - MessageType_GetNextU2FCounter = 80 [(wire_in) = true]; - MessageType_NextU2FCounter = 81 [(wire_out) = true]; - MessageType_ChangeWipeCode = 82 [(wire_in) = true]; // Bootloader MessageType_FirmwareErase = 6 [(wire_in) = true, (wire_bootloader) = true]; @@ -3127,7 +3303,6 @@ enum MessageType { MessageType_DebugLinkMemory = 111 [(wire_debug_out) = true]; MessageType_DebugLinkMemoryWrite = 112 [(wire_debug_in) = true]; MessageType_DebugLinkFlashErase = 113 [(wire_debug_in) = true]; - MessageType_DebugLinkLayout = 9001 [(wire_debug_out) = true]; // Ethereum MessageType_EthereumGetPublicKey = 450 [(wire_in) = true]; @@ -3187,6 +3362,12 @@ enum MessageType { MessageType_StellarBumpSequenceOp = 221 [(wire_in) = true]; MessageType_StellarSignedTx = 230 [(wire_out) = true]; + // TRON + MessageType_TronGetAddress = 250 [(wire_in) = true]; + MessageType_TronAddress = 251 [(wire_out) = true]; + MessageType_TronSignTx = 252 [(wire_in) = true]; + MessageType_TronSignedTx = 253 [(wire_out) = true]; + // Cardano // dropped Sign/VerifyMessage ids 300-302 MessageType_CardanoSignTx = 303 [(wire_in) = true]; @@ -3198,11 +3379,25 @@ enum MessageType { MessageType_CardanoTxAck = 309 [(wire_in) = true]; MessageType_CardanoSignedTx = 310 [(wire_out) = true]; + // Ontology + MessageType_OntologyGetAddress = 350 [(wire_in) = true]; + MessageType_OntologyAddress = 351 [(wire_out) = true]; + MessageType_OntologyGetPublicKey = 352 [(wire_in) = true]; + MessageType_OntologyPublicKey = 353 [(wire_out) = true]; + MessageType_OntologySignTransfer = 354 [(wire_in) = true]; + MessageType_OntologySignedTransfer = 355 [(wire_out) = true]; + MessageType_OntologySignWithdrawOng = 356 [(wire_in) = true]; + MessageType_OntologySignedWithdrawOng = 357 [(wire_out) = true]; + MessageType_OntologySignOntIdRegister = 358 [(wire_in) = true]; + MessageType_OntologySignedOntIdRegister = 359 [(wire_out) = true]; + MessageType_OntologySignOntIdAddAttributes = 360 [(wire_in) = true]; + MessageType_OntologySignedOntIdAddAttributes = 361 [(wire_out) = true]; + // Ripple MessageType_RippleGetAddress = 400 [(wire_in) = true]; MessageType_RippleAddress = 401 [(wire_out) = true]; MessageType_RippleSignTx = 402 [(wire_in) = true]; - MessageType_RippleSignedTx = 403 [(wire_in) = true]; + MessageType_RippleSignedTx = 403 [(wire_out) = true]; // Monero MessageType_MoneroTransactionInitRequest = 501 [(wire_out) = true]; @@ -3263,12 +3458,4 @@ enum MessageType { MessageType_BinanceOrderMsg = 707 [(wire_in) = true]; MessageType_BinanceCancelMsg = 708 [(wire_in) = true]; MessageType_BinanceSignedTx = 709 [(wire_out) = true]; - - // WebAuthn - MessageType_WebAuthnListResidentCredentials = 800 [(wire_in) = true]; - MessageType_WebAuthnCredentials = 801 [(wire_out) = true]; - MessageType_WebAuthnAddResidentCredential = 802 [(wire_in) = true]; - MessageType_WebAuthnRemoveResidentCredential = 803 [(wire_in) = true]; - - MessageType_RebootDevice = 65520 [(wire_in) = true]; } From 2d5d7baccde8c2b2a1e99fe7271130591a7186a5 Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Thu, 15 Jul 2021 18:29:24 +0800 Subject: [PATCH 02/27] Update combined.proto.txt --- protob/combined.proto.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protob/combined.proto.txt b/protob/combined.proto.txt index ad25a88..b42186f 100644 --- a/protob/combined.proto.txt +++ b/protob/combined.proto.txt @@ -1,5 +1,5 @@ syntax = "proto2"; -import "google/protobuf/descriptor.proto"; +import "google/protobuf/descriptor.proto.txt"; // Sugar for easier handling in Java From 73a679a609b1f20dc70928ff8136930ffbb38726 Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Wed, 21 Jul 2021 03:43:27 +0800 Subject: [PATCH 03/27] Add BaseCommands --- src/device/BaseCommands.ts | 191 +++++++++++++++++++++++++++++++++++ src/device/RippleCommands.ts | 120 ++-------------------- src/models/Prokey.ts | 5 + 3 files changed, 205 insertions(+), 111 deletions(-) create mode 100644 src/device/BaseCommands.ts diff --git a/src/device/BaseCommands.ts b/src/device/BaseCommands.ts new file mode 100644 index 0000000..80b2452 --- /dev/null +++ b/src/device/BaseCommands.ts @@ -0,0 +1,191 @@ +/* + * This is part of PROKEY HARDWARE WALLET project + * Copyright (C) Prokey.io + * + * Ali Akbar Mohammadi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +import { Device } from "./Device"; +import * as PathUtil from '../utils/pathUtils'; +import * as Utility from '../utils/utils'; +import { GeneralErrors } from "../models/GeneralResponse"; +import { MessageSignature, PublicKey, Success } from "../models/Prokey"; + +export abstract class BaseCommands { + + /** + * Get coin address from device + * @param device Prokey device instance + * @param path BIP path + * @param showOnProkey true means show the address on device display + */ + protected async GetAddressBase( + deviceCommand: string, + returnType: string, + device: Device, + path: Array | string, + showOnProkey?: boolean): Promise { + if (device == null || path == null) { + return Promise.reject({ success: false, errorCode: GeneralErrors.INVALID_PARAM }); + } + + let showDisplay = (showOnProkey == null) ? true : showOnProkey; + + // convert path to array of num + let address_n: Array; + if (typeof path == "string") { + try { + address_n = PathUtil.getHDPath(path); + } + catch (e) { + return Promise.reject({ success: false, errorCode: GeneralErrors.PATH_NOT_VALID }); + } + + } else { + address_n = path; + } + + let param = { + address_n: address_n, + show_display: showDisplay, + } + + return await device.SendMessage(deviceCommand, param, returnType); + } + + /** + * Get List of addresses, This function is useful in account discovery + * @param device the prokey device instance + * @param paths list of paths to retrive the addresses + */ + protected async GetAddressesBase( + deviceCommand: string, + returnType: string, + device: Device, + paths: Array>): Promise> { + + if (device == null || paths == null) { + return Promise.reject({ + success: false, + errorCode: GeneralErrors.INVALID_PARAM + }); + } + + let lstAddress = new Array(); + lstAddress.length = paths.length; + + paths.forEach(async (path) => { + lstAddress.push(await this.GetAddressBase( + deviceCommand, + returnType, + device, + path, + false)); + }); + + return lstAddress; + } + + /** + * Get Public key + * @param device The prokey device + * @param path BIP path + * @param showOnProkey true means show the public key on prokey display + */ + protected async GetPublicKeyBase(device: Device, + path: Array | string, + showOnProkey?: boolean): Promise { + + if (device == null || path == null) { + return Promise.reject({ success: false, errorCode: GeneralErrors.INVALID_PARAM }); + } + + let showDisplay = (showOnProkey == null) ? true : showOnProkey; + + // convert path to array of num + let address_n: Array; + if (typeof path == "string") { + try { + address_n = PathUtil.getHDPath(path); + } + catch (e) { + return Promise.reject({ success: false, errorCode: GeneralErrors.PATH_NOT_VALID }); + } + + } else { + address_n = path; + } + + let param = { + address_n: address_n, + show_display: showDisplay, + } + + return await device.SendMessage('GetPublicKey', param, 'PublicKey'); + } + + /** + * Sign Message + * @param device Prokey device instance + * @param address_n array of BIP32/44 Path + * @param message message to be signed + * @param coin coin name + */ + protected async SignMessageBase( + device: Device, + address_n: Array, + message: Uint8Array, + coin: string): Promise { + + let scriptType = PathUtil.GetScriptType(address_n); + + let res = await device.SendMessage('SignMessage', { + address_n: address_n, + message: message, + coin_name: coin, + script_type: scriptType, + }, 'MessageSignature'); + + if (res.signature) { + res.signature = Utility.ByteArrayToHexString(res.signature); + } + + return res; + } + + /** + * Verify Message + * @param device Prokey device instance + * @param address address + * @param message message + * @param signature signature data + * @param coinName coin name + */ + public async VerifyMessageBase( + device: Device, + address: string, + message: Uint8Array, + signature: Uint8Array, + coinName: string): Promise { + + return await device.SendMessage('VerifyMessage', { + address: address, + signature: signature, + message: message, + coin_name: coinName, + }, 'Success'); + } +} \ No newline at end of file diff --git a/src/device/RippleCommands.ts b/src/device/RippleCommands.ts index e173ab2..5d69ab7 100644 --- a/src/device/RippleCommands.ts +++ b/src/device/RippleCommands.ts @@ -31,12 +31,14 @@ import { RippleTransaction } from '../models/Responses-V6'; import { RippleAddress } from '../models/Prokey'; import { MyConsole } from '../utils/console'; import { validateParams } from '../utils/paramsValidator'; +import { BaseCommands } from './BaseCommands'; -export class RippleCommands implements ICoinCommands { +export class RippleCommands extends BaseCommands implements ICoinCommands { private _coinInfo: RippleCoinInfoModel; constructor(coinName: string) { + super(); this._coinInfo = CoinInfo.Get(coinName, CoinBaseType.Ripple); if (this._coinInfo == null) { throw new Error(`Cannot load CoinInfo for ${coinName}`); @@ -51,38 +53,13 @@ export class RippleCommands implements ICoinCommands { } /** - * Get Bitcoin/Litecoin and etc address + * Get Ripple address * @param device Prokey device instance * @param path BIP path * @param showOnProkey true means show the address on device display */ public async GetAddress(device: Device, path: Array, showOnProkey?: boolean): Promise { - if (device == null || path == null) { - return Promise.reject({ success: false, errorCode: GeneralErrors.INVALID_PARAM }); - } - - let showDisplay = (showOnProkey == null) ? true : showOnProkey; - - // convert path to array of num - let address_n: Array; - if (typeof path == "string") { - try { - address_n = PathUtil.getHDPath(path); - } - catch (e) { - return Promise.reject({ success: false, errorCode: GeneralErrors.PATH_NOT_VALID }); - } - - } else { - address_n = path; - } - - let param = { - address_n: address_n, - show_display: showDisplay, - } - - return await device.SendMessage('RippleGetAddress', param, 'RippleAddress'); + return await this.GetAddressBase('RippleGetAddress', 'RippleAddress', device, path, showOnProkey); } /** @@ -91,43 +68,7 @@ export class RippleCommands implements ICoinCommands { * @param paths list of paths to retrive the addresses */ public async GetAddresses(device: Device, paths: Array>): Promise> { - if (device == null || paths == null) { - return Promise.reject({ - success: false, - errorCode: GeneralErrors.INVALID_PARAM - }); - } - - let lstAddress = new Array(); - - paths.forEach(async (path) => { - let pn: Array; - if (typeof path == "string") { - try { - pn = PathUtil.getHDPath(path); - } - catch (e) { - return Promise.reject({ success: false, errorCode: GeneralErrors.PATH_NOT_VALID }); - } - } - else { - pn = path; - } - - let param = { - address_n: pn, - show_display: false, - } - - try { - let address = await device.SendMessage('RippleGetAddress', param, 'RippleAddress'); - lstAddress.push(address); - } catch (e) { - Promise.reject(e); - } - }); - - return lstAddress; + return await this.GetAddressesBase('RippleGetAddress', 'RippleAddress', device, paths); } /** @@ -140,32 +81,7 @@ export class RippleCommands implements ICoinCommands { path: Array | string, showOnProkey?: boolean): Promise { - if (device == null || path == null) { - return Promise.reject({ success: false, errorCode: GeneralErrors.INVALID_PARAM }); - } - - let showDisplay = (showOnProkey == null) ? true : showOnProkey; - - // convert path to array of num - let address_n: Array; - if (typeof path == "string") { - try { - address_n = PathUtil.getHDPath(path); - } - catch (e) { - return Promise.reject({ success: false, errorCode: GeneralErrors.PATH_NOT_VALID }); - } - - } else { - address_n = path; - } - - let param = { - address_n: address_n, - show_display: showDisplay, - } - - return await device.SendMessage('GetPublicKey', param, 'PublicKey'); + return await this.GetPublicKeyBase(device, path, showOnProkey); } /** @@ -250,20 +166,7 @@ export class RippleCommands implements ICoinCommands { message: Uint8Array, coin?: string): Promise { - let scriptType = PathUtil.GetScriptType(address_n); - - let res = await device.SendMessage('SignMessage', { - address_n: address_n, - message: message, - coin_name: coin || 'Ripple', - script_type: scriptType, - }, 'MessageSignature'); - - if (res.signature) { - res.signature = Utility.ByteArrayToHexString(res.signature); - } - - return res; + return await this.SignMessageBase(device, address_n, message, coin || 'Ripple'); } /** @@ -281,12 +184,7 @@ export class RippleCommands implements ICoinCommands { signature: Uint8Array, coinName: string): Promise { - return await device.SendMessage('VerifyMessage', { - address: address, - signature: signature, - message: message, - coin_name: coinName || 'Ripple', - }, 'Success'); + return await this.VerifyMessageBase(device, address, message, signature, coinName || 'Ripple'); } } \ No newline at end of file diff --git a/src/models/Prokey.ts b/src/models/Prokey.ts index ea8fd12..f00cc9e 100644 --- a/src/models/Prokey.ts +++ b/src/models/Prokey.ts @@ -735,6 +735,11 @@ export type RippleSignedTx = { serialized_tx: string, } +// TRON types +export type TronAddress = { + address: string, +} + // EOS types export type EosPublicKey = { wif_public_key: string, From 71e052161066eaddf110cf99f7b50a11c065258d Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Wed, 21 Jul 2021 04:05:59 +0800 Subject: [PATCH 04/27] Add tron commands --- src/coins/CoinInfo.ts | 1 + src/device/TronCommands.ts | 72 +++++++++++++++++++++++++++++++++++++ src/models/CoinInfoModel.ts | 11 ++++++ 3 files changed, 84 insertions(+) create mode 100644 src/device/TronCommands.ts diff --git a/src/coins/CoinInfo.ts b/src/coins/CoinInfo.ts index becc5cb..92b8a81 100644 --- a/src/coins/CoinInfo.ts +++ b/src/coins/CoinInfo.ts @@ -30,6 +30,7 @@ export enum CoinBaseType { NEM, OMNI, Ripple, + Tron, OTHERS } diff --git a/src/device/TronCommands.ts b/src/device/TronCommands.ts new file mode 100644 index 0000000..f39ae26 --- /dev/null +++ b/src/device/TronCommands.ts @@ -0,0 +1,72 @@ +/* + * This is part of PROKEY HARDWARE WALLET project + * Copyright (C) Prokey.io + * + * Hadi Robati, hadi@prokey.io + * Ali Akbar Mohammadi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +import { CoinBaseType, CoinInfo } from "../coins/CoinInfo"; +import { BitcoinTx } from "../models/BitcoinTx"; +import { BitcoinBaseCoinInfoModel, EthereumBaseCoinInfoModel, OmniCoinInfoModel, RippleCoinInfoModel, TronCoinInfoModel } from "../models/CoinInfoModel"; +import { EthereumTx } from "../models/EthereumTx"; +import { AddressModel, EthereumAddress, LiskAddress, NEMAddress, RippleAddress, CardanoAddress, StellarAddress, PublicKey, EosPublicKey, LiskPublicKey, TezosPublicKey, BinancePublicKey, CardanoPublicKey, SignedTx, EthereumSignedTx, EosSignedTx, LiskSignedTx, TezosSignedTx, BinanceSignTx, CardanoSignedTx, RippleSignedTx, MessageSignature, LiskMessageSignature, Success, TronAddress } from "../models/Prokey"; +import { RippleTransaction } from "../models/Responses-V6"; +import { BaseCommands } from "./BaseCommands"; +import { Device } from "./Device"; +import { ICoinCommands } from "./ICoinCommand"; + +export class TronCommands extends BaseCommands implements ICoinCommands { + + private _coinInfo: TronCoinInfoModel; + + public constructor(coinName: string) + { + super(); + this._coinInfo = CoinInfo.Get(coinName, CoinBaseType.Tron); + if (this._coinInfo == null) { + throw new Error(`Cannot load CoinInfo for ${coinName}`); + } + } + + GetCoinInfo(): TronCoinInfoModel { + return this._coinInfo; + } + + public async GetAddress(device: Device, path: Array, showOnProkey?: boolean): Promise { + return await this.GetAddressBase('TronGetAddress', 'TronAddress', device, path, showOnProkey); + } + + public async GetAddresses(device: Device, paths: Array>): Promise { + return await this.GetAddressesBase('TronGetAddress', 'TronAddress', device, paths); + } + + public async GetPublicKey(device: Device, path: string | number[], showOnProkey?: boolean): Promise { + return this.GetPublicKeyBase(device, path, showOnProkey); + } + + public async SignTransaction(device: Device, transaction: BitcoinTx | EthereumTx | RippleTransaction): Promise { + throw new Error("Method not implemented."); + } + + public async SignMessage(device: Device, path: number[], message: Uint8Array, coinName?: string): Promise { + return await this.SignMessageBase(device, path, message, coinName || 'TRON'); + } + + public async VerifyMessage(device: Device, address: string, message: Uint8Array, signature: Uint8Array, coinName?: string): Promise { + return await this.VerifyMessageBase(device, address, message, signature, coinName || 'TRON'); + } +} diff --git a/src/models/CoinInfoModel.ts b/src/models/CoinInfoModel.ts index 3dc596b..eacec48 100644 --- a/src/models/CoinInfoModel.ts +++ b/src/models/CoinInfoModel.ts @@ -125,3 +125,14 @@ export interface RippleCoinInfoModel { test?: boolean, tx_url: string, } + +export type TronCoinInfoModel { + name: string, + shortcut: string, + slip44: number, + decimals: number, + on_device: string, + support: ProkeySupport; + test?: boolean, + tx_url: string, +} \ No newline at end of file From 5a11c72f44de47541b2b2e0aa1b82c62d20cad0a Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Wed, 21 Jul 2021 04:16:17 +0800 Subject: [PATCH 05/27] Remove unused Responses-V6.ts --- src/device/ICoinCommand.ts | 2 +- src/device/RippleCommands.ts | 3 +- src/device/TronCommands.ts | 13 +- src/models/CoinInfoModel.ts | 2 +- src/models/Prokey.ts | 5 + src/models/Responses-V6.ts | 637 ----------------------------------- src/wallet/BaseWallet.ts | 2 +- 7 files changed, 14 insertions(+), 650 deletions(-) delete mode 100644 src/models/Responses-V6.ts diff --git a/src/device/ICoinCommand.ts b/src/device/ICoinCommand.ts index 6fb5dfb..fb29643 100644 --- a/src/device/ICoinCommand.ts +++ b/src/device/ICoinCommand.ts @@ -27,7 +27,7 @@ import { EthereumBaseCoinInfoModel, OmniCoinInfoModel, RippleCoinInfoModel } from '../models/CoinInfoModel'; -import { RippleTransaction } from '../models/Responses-V6'; +import { RippleTransaction } from '../models/Prokey'; export interface ICoinCommands { GetCoinInfo() : BitcoinBaseCoinInfoModel | EthereumBaseCoinInfoModel | OmniCoinInfoModel | RippleCoinInfoModel | null; diff --git a/src/device/RippleCommands.ts b/src/device/RippleCommands.ts index 5d69ab7..c8725cd 100644 --- a/src/device/RippleCommands.ts +++ b/src/device/RippleCommands.ts @@ -27,8 +27,7 @@ import { RippleCoinInfoModel } from '../models/CoinInfoModel'; import { CoinInfo, CoinBaseType } from '../coins/CoinInfo'; import { Device } from './Device'; import { GeneralResponse, GeneralErrors } from '../models/GeneralResponse'; -import { RippleTransaction } from '../models/Responses-V6'; -import { RippleAddress } from '../models/Prokey'; +import { RippleTransaction } from '../models/Prokey'; import { MyConsole } from '../utils/console'; import { validateParams } from '../utils/paramsValidator'; import { BaseCommands } from './BaseCommands'; diff --git a/src/device/TronCommands.ts b/src/device/TronCommands.ts index f39ae26..cf1a4d0 100644 --- a/src/device/TronCommands.ts +++ b/src/device/TronCommands.ts @@ -20,11 +20,8 @@ */ import { CoinBaseType, CoinInfo } from "../coins/CoinInfo"; -import { BitcoinTx } from "../models/BitcoinTx"; -import { BitcoinBaseCoinInfoModel, EthereumBaseCoinInfoModel, OmniCoinInfoModel, RippleCoinInfoModel, TronCoinInfoModel } from "../models/CoinInfoModel"; -import { EthereumTx } from "../models/EthereumTx"; -import { AddressModel, EthereumAddress, LiskAddress, NEMAddress, RippleAddress, CardanoAddress, StellarAddress, PublicKey, EosPublicKey, LiskPublicKey, TezosPublicKey, BinancePublicKey, CardanoPublicKey, SignedTx, EthereumSignedTx, EosSignedTx, LiskSignedTx, TezosSignedTx, BinanceSignTx, CardanoSignedTx, RippleSignedTx, MessageSignature, LiskMessageSignature, Success, TronAddress } from "../models/Prokey"; -import { RippleTransaction } from "../models/Responses-V6"; +import { TronCoinInfoModel } from "../models/CoinInfoModel"; +import { TronTransaction, PublicKey, RippleSignedTx, MessageSignature, Success, TronAddress } from "../models/Prokey"; import { BaseCommands } from "./BaseCommands"; import { Device } from "./Device"; import { ICoinCommands } from "./ICoinCommand"; @@ -54,15 +51,15 @@ export class TronCommands extends BaseCommands implements ICoinCommands { return await this.GetAddressesBase('TronGetAddress', 'TronAddress', device, paths); } - public async GetPublicKey(device: Device, path: string | number[], showOnProkey?: boolean): Promise { + public async GetPublicKey(device: Device, path: string | number[], showOnProkey?: boolean): Promise { return this.GetPublicKeyBase(device, path, showOnProkey); } - public async SignTransaction(device: Device, transaction: BitcoinTx | EthereumTx | RippleTransaction): Promise { + public async SignTransaction(device: Device, transaction: TronTransaction): Promise { throw new Error("Method not implemented."); } - public async SignMessage(device: Device, path: number[], message: Uint8Array, coinName?: string): Promise { + public async SignMessage(device: Device, path: number[], message: Uint8Array, coinName?: string): Promise { return await this.SignMessageBase(device, path, message, coinName || 'TRON'); } diff --git a/src/models/CoinInfoModel.ts b/src/models/CoinInfoModel.ts index eacec48..877c34e 100644 --- a/src/models/CoinInfoModel.ts +++ b/src/models/CoinInfoModel.ts @@ -126,7 +126,7 @@ export interface RippleCoinInfoModel { tx_url: string, } -export type TronCoinInfoModel { +export type TronCoinInfoModel = { name: string, shortcut: string, slip44: number, diff --git a/src/models/Prokey.ts b/src/models/Prokey.ts index f00cc9e..11b939d 100644 --- a/src/models/Prokey.ts +++ b/src/models/Prokey.ts @@ -1039,3 +1039,8 @@ export type LoadDeviceFlags = { skip_checksum?: boolean, u2f_counter?: number, } + +// Tron types +export type TronTransaction = { + +} diff --git a/src/models/Responses-V6.ts b/src/models/Responses-V6.ts deleted file mode 100644 index e2ca89d..0000000 --- a/src/models/Responses-V6.ts +++ /dev/null @@ -1,637 +0,0 @@ -/* - * This is part of PROKEY HARDWARE WALLET project - * Copyright (C) Prokey.io - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -export interface Address { - address: string; - path: Array; - serializedPath: string; -} - -export interface CipheredKeyValue { - value: string; -} - -export interface Success { - -} - -export interface Coininterface { - coin_name: string; - coin_shortcut: string; - address_interface: number; - maxfee_kb: number; - address_interface_p2sh: number; -} - -export interface Features { - vendor: string; - major_version: number; - minor_version: number; - patch_version: number; - bootloader_mode: boolean; - device_id: string; - pin_protection: boolean; - passphrase_protection: boolean; - language: string; - label: string; - coins: Coininterface[]; - initialized: boolean; - revision: string; - bootloader_hash: string; - imported: boolean; - pin_cached: boolean; - passphrase_cached: boolean; - state?: string; - needs_backup?: boolean; - firmware_present?: boolean; -} - -export interface ResetDeviceSettings { - display_random?: boolean; - strength?: number; - passphrase_protection?: boolean; - pin_protection?: boolean; - language?: string; - label?: string; - u2f_counter?: number; - skip_backup?: boolean; -} - -export interface HDPrivNode { - depth: number; - fingerprint: number; - child_num: number; - chain_code: string; - private_key: string; -} - -export interface HDPubNode { - depth: number; - fingerprint: number; - child_num: number; - chain_code: string; - public_key: string; -} - -export type HDNode = HDPubNode | HDPrivNode; - -export interface LoadDeviceSettings { - pin?: string; - passphrase_protection?: boolean; - language?: string; - label?: string; - skip_checksum?: boolean; - - mnemonic?: string; - node?: HDNode; - payload?: string; // will be converted - - u2f_counter?: number; -} - -export interface RecoverDeviceSettings { - word_count?: number; - passphrase_protection?: boolean; - pin_protection?: boolean; - language?: string; - label?: string; - enforce_wordlist?: boolean; - interface?: number; - u2f_counter?: number; -} - -export interface ApplySettings { - language?: string; - label?: string; - use_passphrase?: boolean; - homescreen?: string; -} - -export interface MessageSignature { - address: string; - signature: string; -} - -export interface MultisigRedeemScriptinterface { - pubkeys: Array<{ node: string; address_n: Array }>; - signatures: Array; - m?: number; -} - -export interface TransactionInput { - address_n?: Array; - prev_hash: string; - prev_index: number; - script_sig?: string; - sequence?: number; - script_interface?: 'SPENDADDRESS' | 'SPENDMULTISIG' | 'EXTERNAL' | 'SPENDWITNESS' | 'SPENDP2SHWITNESS'; - multisig?: MultisigRedeemScriptinterface; - amount?: number; // only with segwit - decred_tree?: number; - decred_script_version?: number; -} - -export type TransactionOutput = { - address: string; - amount: number; // in satoshis - script_interface: 'PAYTOADDRESS'; -} | { - address_n: Array; - amount: number; // in satoshis - script_interface: 'PAYTOADDRESS' | 'PAYTOP2SHWITNESS'; -} | { - op_return_data: string; - amount: 0; // fixed - script_interface: 'PAYTOOPRETURN'; -}; -// TODO: -// "multisig": MultisigRedeemScriptinterface field; where? -// "decred_script_version": number field; where? - -export interface TransactionBinOutput { - amount: number; - script_pubkey: string; -} - -export interface RefTransaction { - hash: string; - version: number; - inputs: Array; - bin_outputs: Array; - lock_time: number; - extra_data?: string; -} - -export interface TxRequestDetails { - request_index: number; - tx_hash?: string; - extra_data_len?: number; - extra_data_offset?: number; -} - -export interface TxRequestSerialized { - signature_index?: number; - signature?: string; - serialized_tx?: string; -} - -export interface TxRequest { - request_interface: 'TXINPUT' | 'TXOUTPUT' | 'TXMETA' | 'TXFINISHED' | 'TXEXTRADATA'; - details: TxRequestDetails; - serialized: TxRequestSerialized; -} - -export interface SignedTx { - signatures: Array; - serializedTx: string; - txid?: string; -} - -export interface EthereumTxRequest { - data_length?: number; - signature_v?: number; - signature_r?: string; - signature_s?: string; -} - -export interface EthereumAddress { - address: string; -} - -export interface EthereumSignedTx { - // v: number; - v: string; - r: string; - s: string; -} - -export interface Identity { - proto?: string; - user?: string; - host?: string; - port?: string; - path?: string; - index?: number; -} - -export interface SignedIdentity { - address: string; - public_key: string; - signature: string; -} - -export interface PublicKey { - node: HDPubNode; - xpub: string; -} - -// combined PublicKey and bitcoin.HDNode -export interface HDNodeResponse { - path: Array; - serializedPath: string; - childNum: number; - xpub: string; - xpubSegwit?: string; - chainCode: string; - publicKey: string; - fingerprint: number; - depth: number; -} - -// this is what Trezor asks for -export type SignTxInfoToTrezor = { - inputs: Array; -} | { - bin_outputs: Array; -} | { - outputs: Array; -} | { - extra_data: string; -} | { - version: number; - lock_time: number; - inputs_cnt: number; - outputs_cnt: number; - extra_data_len?: number; -}; - -// NEM interfaces -export interface NEMAddress { - address: string; -} - -export interface NEMSignedTx { - data: string; - signature: string; -} - -export interface NEMTransactionCommon { - address_n?: Array; - network?: number; - timestamp?: number; - fee?: number; - deadline?: number; - signer?: string; -} - -export interface NEMMosaic { - namespace?: string; - mosaic?: string; - quantity?: number; -} - -export interface NEMTransfer { - mosaics?: Array; - public_key?: string; - recipient?: string; - amount?: number; - payload?: string; -} - -export interface NEMProvisionNamespace { - namespace?: string; - sink?: string; - fee?: number; - parent?: string; -} - -export type NEMMosaicLevyinterface = { - id: 1; - name: 'MosaicLevy_Absolute'; -} | { - id: 2; - name: 'MosaicLevy_Percentile'; -}; - -export type NEMSupplyChangeinterface = { - id: 1; - name: 'SupplyChange_Increase'; -} | { - id: 2; - name: 'SupplyChange_Decrease'; -}; - -export type NEMModificationinterface = { - id: 1; - name: 'CosignatoryModification_Add'; -} | { - id: 2; - name: 'CosignatoryModification_Delete'; -}; - -export type NEMImportanceTransferMode = { - id: 1; - name: 'ImportanceTransfer_Activate'; -} | { - id: 2; - name: 'ImportanceTransfer_Deactivate'; -}; - -export interface NEMMosaicDefinition { - name?: string; - ticker?: string; - namespace?: string; - mosaic?: string; - divisibility?: number; - fee?: number; - levy?: NEMMosaicLevyinterface; - levy_address?: string; - levy_namespace?: string; - levy_mosaic?: string; - supply?: number; - mutable_supply?: boolean; - transferable?: boolean; - description?: string; - networks?: number; -} - -export interface NEMMosaicCreation { - definition?: NEMMosaicDefinition; - sink?: string; - fee?: number; -} - -export interface NEMMosaicSupplyChange { - namespace?: string; - interface?: NEMSupplyChangeinterface; - mosaic?: string; - delta?: number; -} - -export interface NEMCosignatoryModification { - interface?: NEMModificationinterface; - public_key?: string; -} - -export interface NEMAggregateModification { - modifications?: Array; - relative_change?: number; // TODO: "sint32" -} - -export interface NEMImportanceTransfer { - mode?: NEMImportanceTransferMode; - public_key?: string; -} - -export interface NEMSignTxMessage { - transaction?: NEMTransactionCommon; - cosigning?: boolean; - multisig?: NEMTransactionCommon; - transfer?: NEMTransfer; - provision_namespace?: NEMProvisionNamespace; - mosaic_creation?: NEMMosaicCreation; - supply_change?: NEMMosaicSupplyChange; - aggregate_modification?: NEMAggregateModification; - importance_transfer?: NEMImportanceTransfer; -} - -// Stellar interfaces - -export interface StellarAddress { - address: string; -} - -export interface StellarSignedTx { - public_key: string; - signature: string; -} - -export interface StellarPaymentOp { - interface: 'StellarTxOpRequest'; - message: {}; -} - -export interface StellarSignTxMessage { - address_n: Array; - source_account: string; - fee?: number; - sequence_number?: number; - network_passphrase: string; - timebounds_start?: number; - timebounds_end?: number; - memo_interface?: number; - memo_text?: string; - memo_id?: number; - memo_hash?: string; - num_operations: number; -} - -interface StellarAsset { - interface: string; - code?: string; - issuer?: string; -} - -export type StellarOperationMessage = { - interface: 'StellarCreateAccountOp'; - new_account?: string; - source_account: string; - starting_balance?: number; -} | { - interface: 'StellarPaymentOp'; - source_account?: string; - destination_account?: string; - asset?: StellarAsset; - amount?: number; -} | { - interface: 'StellarPathPaymentOp'; - source_account: string; - send_asset?: StellarAsset; - send_max?: number; - destination_account?: string; - destination_asset?: StellarAsset; - destination_amount?: number; - paths?: Array; -} | { - interface: 'StellarManageOfferOp'; - source_account: string; - offer_id: number; - amount: number; - buying_asset: StellarAsset; - selling_asset: StellarAsset; - price_n: number; - price_d: number; -} | { - interface: 'StellarCreatePassiveOfferOp'; - source_account: string; - offer_id: number; - amount: number; - buying_asset: StellarAsset; - selling_asset: StellarAsset; - price_n: number; - price_d: number; -} | { - interface: 'StellarSetOptionsOp'; - source_account: string; - signer_interface?: number; - signer_key?: string; - signer_weight?: number; - clear_flags?: number; - set_flags?: number; - master_weight?: number; - low_threshold?: number; - medium_threshold?: number; - high_threshold?: number; - home_domain?: string; - inflation_destination_account?: string; -} | { - interface: 'StellarChangeTrustOp'; - source_account: string; - asset?: StellarAsset; - limit?: number; -} | { - interface: 'StellarAllowTrustOp'; - source_account: string; - trusted_account: string; - asset_interface?: number; - asset_code?: string; - is_authorized?: number; -} | { - interface: 'StellarAccountMergeOp'; - source_account: string; - destination_account: string; -} | { - interface: 'StellarManageDataOp'; - source_account: string; - key: string; - value: string; -} | { - interface: 'StellarBumpSequenceOp'; - source_account: string; - bump_to: number; -}; - -// Cardano interfaces -export interface CardanoAddress { - address: string; - address_n?: Array; -} - -export interface CardanoPublicKey { - xpub: string; - node: HDPubNode; -} - -export interface CardanoSignedTx { - tx_hash: string; - tx_body: string; -} -export interface CardanoTxInput { - tx_hash: string; - address_n: Array; - output_index: number; - interface?: number; -} -export interface CardanoTxOutput { - address?: string; - address_n?: Array; - amount: number; -} - -export interface CardanoTxRequest { - tx_index: number; - tx_hash: string; - tx_body: string; -} - -// Lisk interfaces -export interface LiskAddress { - address: string; -} - -export interface LiskPublicKey { - public_key: string; -} - -export interface LiskMessageSignature { - public_key: string; - signature: string; -} - -export type LiskAsset = { data: string } | -{ votes: Array } | -{ delegate: { username: string } } | -{ signature: { public_key: string } } | -{ - multisignature: { - min: number; - life_time: number; - keys_group: Array; - } -}; - -export interface LiskTransaction { - interface: number; - fee: number; - amount: number; - timestamp: number; - recipient_id?: string; - sender_public_key?: string; - requester_public_key?: string; - signature?: string; - asset?: LiskAsset; -} - -export interface LiskSignedTx { - signature: string; -} - -// Ripple interfaces -export interface RippleAddress { - address: string; -} - -export interface RippleTransaction { - address_n: Array; - fee?: number; - flags?: number; - sequence?: number; - last_ledger_sequence?: number; - payment: { - amount: number; - destination: string; - destination_tag?: number; - }; -} - -export interface RippleSignedTx { - signature: string; - serialized_tx: string; -} - -// GetAccountInfo response -export interface AccountInfo { - id: number; - path: Array; - serializedPath: string; - xpub: string; - address: string; - addressIndex: number; - addressPath: Array; - addressSerializedPath: string; - balance: number; - confirmed: number; -} - -// GetAddress response -export interface Address { - address: string; - path: Array; - serializedPath: string; -} - diff --git a/src/wallet/BaseWallet.ts b/src/wallet/BaseWallet.ts index 200db0f..024fa0c 100644 --- a/src/wallet/BaseWallet.ts +++ b/src/wallet/BaseWallet.ts @@ -63,7 +63,7 @@ import * as Util from '../utils/utils'; import { BitcoinTx } from '../models/BitcoinTx'; import { EthereumTx } from '../models/EthereumTx'; import { RippleCommands } from "../device/RippleCommands"; -import { RippleSignedTx, RippleTransaction } from "../models/Responses-V6"; +import { RippleSignedTx, RippleTransaction } from "../models/Prokey"; /** * This is the base class for all implemented wallets From a5786ee52f5fa35a25443f64ef50126e6b83151a Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Wed, 21 Jul 2021 04:17:49 +0800 Subject: [PATCH 06/27] Update index.ts --- index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/index.ts b/index.ts index 4590b17..75a0209 100644 --- a/index.ts +++ b/index.ts @@ -21,6 +21,8 @@ export { Device } from './src/device/Device'; export { BitcoinCommands } from './src/device/BitcoinCommands'; export { EthereumCommands } from './src/device/EthereumCommands'; +export { TronCommands } from './src/device/TronCommands'; +export { RippleCommands } from './src/device/RippleCommands'; export { BitcoinWallet } from './src/wallet/BitcoinWallet'; export { EthereumWallet } from './src/wallet/EthereumWallet'; export { OmniWallet } from './src/wallet/OmniWallet'; From b13fd41d3c6b99ae0e392c963f3c0e456181eafa Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Wed, 21 Jul 2021 04:18:17 +0800 Subject: [PATCH 07/27] Update index.ts --- index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/index.ts b/index.ts index 75a0209..845021d 100644 --- a/index.ts +++ b/index.ts @@ -3,6 +3,7 @@ * Copyright (C) Prokey.io * * Hadi Robati, hadi@prokey.io + * Ali Akbar Mohammadi * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by From 590dd4dbf7d144e392b15f57dbfd7f87f9794f32 Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Thu, 22 Jul 2021 13:19:00 +0800 Subject: [PATCH 08/27] Add Tron block chain --- .../servers/prokey/src/ripple/RippleModel.ts | 2 + .../servers/prokey/src/tron/TronBlockchain.ts | 77 +++++++++++++++++++ .../servers/prokey/src/tron/TronModel.ts | 75 ++++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 src/blockchain/servers/prokey/src/tron/TronBlockchain.ts create mode 100644 src/blockchain/servers/prokey/src/tron/TronModel.ts diff --git a/src/blockchain/servers/prokey/src/ripple/RippleModel.ts b/src/blockchain/servers/prokey/src/ripple/RippleModel.ts index 53622d9..94d5ec4 100644 --- a/src/blockchain/servers/prokey/src/ripple/RippleModel.ts +++ b/src/blockchain/servers/prokey/src/ripple/RippleModel.ts @@ -2,6 +2,8 @@ * This is part of PROKEY HARDWARE WALLET project * Copyright (C) Prokey.io * + * Ali Akbar Mohammadi + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or diff --git a/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts b/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts new file mode 100644 index 0000000..6450a8e --- /dev/null +++ b/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts @@ -0,0 +1,77 @@ +/* + * This is part of PROKEY HARDWARE WALLET project + * Copyright (C) Prokey.io + * + * Ali Akbar Mohammadi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +import { MyConsole } from '../../../../../utils/console'; +import * as Utils from '../../../../../utils/utils'; +import { ProkeyBaseBlockChain } from '../ProkeyBaseBlockChain'; +import { TronAccountInfo, TronBlock, TronTransactionDataInfo, TronTrc20TransactionDataInfo } from './TronModel'; + +export class TronBlockchain extends ProkeyBaseBlockChain { + + _coinName: string; + + constructor(coinName: string) { + super(); + this._coinName = coinName; + } + + public async GetAccountInfo(account: string): Promise { + try { + let r = await this.GetFromServer(`address/${this._coinName}/${account}`); + if (!r.success) + { + MyConsole.Error("Tron get account info error: ", r); + return null; + } + return r.data[0]; + } catch (error) { + return null; + } + } + + public async GetAccountTransactions(account: string, limit: number = 10): Promise> { + let r = await this.GetFromServer(`address/transactions/${this._coinName}/${account}/${limit}`); + if (!r.success) + { + MyConsole.Error("Tron get account transactions error: ", r); + return []; + } + return r.data; + } + + public async GetAccountTrc20Transactions(account: string, limit: number = 10): Promise> { + let r = await this.GetFromServer(`address/trc20/transactions/${this._coinName}/${account}/${limit}`); + if (!r.success) + { + MyConsole.Error("Tron get account TRC20 transactions error: ", r); + return []; + } + return r.data; + } + + public async GetNowBlock(): Promise { + return await this.GetFromServer(`getblockcount/${this._coinName}`); + } + + public async BroadCastTransaction(data: string): Promise { + return await this.GetFromServer(`Transaction/send/${this._coinName}/${data}`); + } + +} \ No newline at end of file diff --git a/src/blockchain/servers/prokey/src/tron/TronModel.ts b/src/blockchain/servers/prokey/src/tron/TronModel.ts new file mode 100644 index 0000000..05b2dc9 --- /dev/null +++ b/src/blockchain/servers/prokey/src/tron/TronModel.ts @@ -0,0 +1,75 @@ +/* + * This is part of PROKEY HARDWARE WALLET project + * Copyright (C) Prokey.io + * + * Ali Akbar Mohammadi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +export type TronAccountInfo = { + latest_opration_time: number; + address: string; + balance: number; + create_time: number; + trc20?: Array; // TRC20 balances + latest_consume_free_time: number; +} + +export type TronTransactionDataInfo = { + signature: Array; + txID: string; + net_usage: number; + net_fee: number; + energy_usage: number; + blockNumber: number; + block_timestamp: number; + energy_fee: number; + energy_usage_total: number; +} + +export type TronTokenInfo = { + symbol: string; + address: string; + decimals: number; + name: string; +} + +export type TronTrc20TransactionDataInfo = { + transaction_id: string; + token_info: TronTokenInfo; + block_timestamp: number; + from: string; + to: string; + type: string; + value: string; +} + +export type TronBlockHeaderRawData = { + number: number; + txTrieRoot: string; + witness_address: string; + parentHash: string; + timestamp: number; +} + +export type TronBlockHeader = { + raw_data: TronBlockHeaderRawData; + witness_signature: string; +} + +export type TronBlock = { + blockID: string; + block_header: TronBlockHeader; +} \ No newline at end of file From 13292d2a9bb90ea295514e4713528b609cb73890 Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Thu, 22 Jul 2021 13:19:34 +0800 Subject: [PATCH 09/27] Update TronBlockchain.ts --- src/blockchain/servers/prokey/src/tron/TronBlockchain.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts b/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts index 6450a8e..f47da4d 100644 --- a/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts +++ b/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts @@ -19,7 +19,6 @@ */ import { MyConsole } from '../../../../../utils/console'; -import * as Utils from '../../../../../utils/utils'; import { ProkeyBaseBlockChain } from '../ProkeyBaseBlockChain'; import { TronAccountInfo, TronBlock, TronTransactionDataInfo, TronTrc20TransactionDataInfo } from './TronModel'; From 97ebdf1170072265ca8624225da15d0ebf488906 Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Thu, 22 Jul 2021 13:43:43 +0800 Subject: [PATCH 10/27] Update ProkeyCoinsInfo.json --- data/ProkeyCoinsInfo.json | 52 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/data/ProkeyCoinsInfo.json b/data/ProkeyCoinsInfo.json index 990737d..f25f781 100644 --- a/data/ProkeyCoinsInfo.json +++ b/data/ProkeyCoinsInfo.json @@ -14586,7 +14586,7 @@ "slip44": 144, "decimals": 6, "priority": 100, - "on_device": "Ripple Testnet", + "on_device": "Ripple", "test": true, "support": { "optimum": "1.10.0" @@ -14596,5 +14596,55 @@ "https://wallet.prokey.io" ] } + ], + "tron": [ + { + "name": "Tron", + "shortcut": "TRX", + "slip44": 195, + "decimals": 6, + "priority": 7, + "on_device": "Tron", + "test": false, + "support": { + "optimum": "1.10.0" + }, + "tx_url": "https://tronscan.org/#/transaction/{hash}", + "wallets": [ + "https://wallet.prokey.io" + ] + }, + { + "name": "Tron Shasta", + "shortcut": "Shasta", + "slip44": 195, + "decimals": 6, + "priority": 7, + "on_device": "Tron", + "test": true, + "support": { + "optimum": "1.10.0" + }, + "tx_url": "https://tronscan.org/#/transaction/{hash}", + "wallets": [ + "https://wallet.prokey.io" + ] + }, + { + "name": "Tron Nile", + "shortcut": "Nile", + "slip44": 195, + "decimals": 6, + "priority": 7, + "on_device": "Tron", + "test": true, + "support": { + "optimum": "1.10.0" + }, + "tx_url": "https://tronscan.org/#/transaction/{hash}", + "wallets": [ + "https://wallet.prokey.io" + ] + } ] } From 41bf172eef4de58dad310b4e5ad30b861ae6f721 Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Thu, 22 Jul 2021 14:08:02 +0800 Subject: [PATCH 11/27] Add tron to coin info --- src/coins/CoinInfo.ts | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/coins/CoinInfo.ts b/src/coins/CoinInfo.ts index 92b8a81..a548531 100644 --- a/src/coins/CoinInfo.ts +++ b/src/coins/CoinInfo.ts @@ -161,10 +161,24 @@ export class CoinInfo { Priority: element.priority, ContractAddress: '', Decimals: element.decimals, - }) + }); } }); + // Add Tron to the list + ProkeyCoinInfoModel.tron.forEach(element => { + if (compareVersions(firmwareVersion, element.support.optimum) >= 0) { + list.push({ + Name: element.name, + Shortcut: element.shortcut, + Type: CoinBaseType.Tron, + Priority: element.priority, + ContractAddress: '', + Decimals: element.decimals, + }); + } + }); + //! Sort the list by Priority list.sort((a, b) => { if (a.Priority > b.Priority) @@ -248,6 +262,18 @@ export class CoinInfo { }); }); } + else if(ct == CoinBaseType.Tron) { + ProkeyCoinInfoModel.tron.foreach(element => { + list.push({ + Name: element.name, + Shortcut: element.shortcut, + Type: CoinBaseType.Tron, + Priority: element.priority, + ContractAddress: '', + Decimals: element.decimals, + }); + }); + } //! Sort the list by Priority list.sort((a, b) => { From 1db07e54c3d441468d135d797d713096de0036d6 Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Thu, 22 Jul 2021 14:11:06 +0800 Subject: [PATCH 12/27] Update CoinInfo.ts --- src/coins/CoinInfo.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/coins/CoinInfo.ts b/src/coins/CoinInfo.ts index a548531..12c3a61 100644 --- a/src/coins/CoinInfo.ts +++ b/src/coins/CoinInfo.ts @@ -73,6 +73,9 @@ export class CoinInfo { case CoinBaseType.Ripple: c = ProkeyCoinInfoModel.ripple; break; + case CoinBaseType.Tron: + c = ProkeyCoinInfoModel.tron; + break; } let ci: any; From 86e86bd83c5bb92a0b596e012958695990506edb Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Thu, 22 Jul 2021 14:13:30 +0800 Subject: [PATCH 13/27] Add TronSignedTx type --- src/device/ICoinCommand.ts | 3 ++- src/device/TronCommands.ts | 4 ++-- src/models/Prokey.ts | 4 ++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/device/ICoinCommand.ts b/src/device/ICoinCommand.ts index fb29643..1283997 100644 --- a/src/device/ICoinCommand.ts +++ b/src/device/ICoinCommand.ts @@ -79,7 +79,8 @@ export interface ICoinCommands { ProkeyResponses.TezosSignedTx | ProkeyResponses.BinanceSignTx | ProkeyResponses.CardanoSignedTx | - ProkeyResponses.RippleSignedTx>; + ProkeyResponses.RippleSignedTx | + ProkeyResponses.TronSignedTx>; SignMessage( device: Device, diff --git a/src/device/TronCommands.ts b/src/device/TronCommands.ts index cf1a4d0..2807379 100644 --- a/src/device/TronCommands.ts +++ b/src/device/TronCommands.ts @@ -21,7 +21,7 @@ import { CoinBaseType, CoinInfo } from "../coins/CoinInfo"; import { TronCoinInfoModel } from "../models/CoinInfoModel"; -import { TronTransaction, PublicKey, RippleSignedTx, MessageSignature, Success, TronAddress } from "../models/Prokey"; +import { TronTransaction, PublicKey, RippleSignedTx, MessageSignature, Success, TronAddress, TronSignedTx } from "../models/Prokey"; import { BaseCommands } from "./BaseCommands"; import { Device } from "./Device"; import { ICoinCommands } from "./ICoinCommand"; @@ -55,7 +55,7 @@ export class TronCommands extends BaseCommands implements ICoinCommands { return this.GetPublicKeyBase(device, path, showOnProkey); } - public async SignTransaction(device: Device, transaction: TronTransaction): Promise { + public async SignTransaction(device: Device, transaction: TronTransaction): Promise { throw new Error("Method not implemented."); } diff --git a/src/models/Prokey.ts b/src/models/Prokey.ts index 11b939d..0aa2914 100644 --- a/src/models/Prokey.ts +++ b/src/models/Prokey.ts @@ -740,6 +740,10 @@ export type TronAddress = { address: string, } +export type TronSignedTx = { + serialized_tx: string, +} + // EOS types export type EosPublicKey = { wif_public_key: string, From 93ddb9cfc91c1f89efda1fe302544501416c8a46 Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Fri, 23 Jul 2021 13:58:05 +0800 Subject: [PATCH 14/27] Add Tron wallet --- src/wallet/RippleWallet.ts | 2 + src/wallet/TronWallet.ts | 138 +++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 src/wallet/TronWallet.ts diff --git a/src/wallet/RippleWallet.ts b/src/wallet/RippleWallet.ts index a4d1754..1c22ce5 100644 --- a/src/wallet/RippleWallet.ts +++ b/src/wallet/RippleWallet.ts @@ -2,6 +2,8 @@ * This is part of PROKEY HARDWARE WALLET project * Copyright (C) Prokey.io * + * Ali Akbar Mohammadi + * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or diff --git a/src/wallet/TronWallet.ts b/src/wallet/TronWallet.ts new file mode 100644 index 0000000..6726311 --- /dev/null +++ b/src/wallet/TronWallet.ts @@ -0,0 +1,138 @@ +/* + * This is part of PROKEY HARDWARE WALLET project + * Copyright (C) Prokey.io + * + * Ali Akbar Mohammadi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +import { CoinBaseType } from "../coins/CoinInfo"; +import { Device } from "../device/Device"; +import { TronCoinInfoModel } from "../models/CoinInfoModel"; +import { BaseWallet } from "./BaseWallet"; +import * as PathUtil from '../utils/pathUtils'; +import { TronAddress, TronSignedTx, TronTransaction } from "../models/Prokey"; +import { TronBlockchain } from "../blockchain/servers/prokey/src/tron/TronBlockchain"; +import { TronAccountInfo, TronBlock, TronTransactionDataInfo } from "../blockchain/servers/prokey/src/tron/TronModel"; +var WAValidator = require('multicoin-address-validator'); + +export class TronWallet extends BaseWallet { + + _block_chain : TronBlockchain; + _accounts: Array; + + constructor(device: Device, coinName: string) + { + super(device, coinName, CoinBaseType.Tron); + this._block_chain = new TronBlockchain(this.GetCoinInfo().shortcut); + this._accounts = []; + } + + public IsAddressValid(address: string): boolean { + if(WAValidator.validate(address, "trx")) { + return true; + } + + return false; + } + + public async StartDiscovery( + accountFindCallBack?: (accountInfo: TronAccountInfo) => void + ): Promise> + { + return new Promise>(async (resolve, reject) => { + let an = 0; + this._accounts = new Array(); + do + { + let account = await this.GetAccountInfo(an); + if (account == null) + { + // there is nothing here + return resolve(this._accounts); + } + this._accounts.push(account); + if (accountFindCallBack) { + accountFindCallBack(account); + } + an++; + } while(true); + }); + } + + // Get Tron account info from blockchain + private async GetAccountInfo(accountNumber: number): Promise { + let slip44 = (super.GetCoinInfo() as TronCoinInfoModel).slip44; + let path = PathUtil.GetListOfBipPath( + slip44, + accountNumber, // Tron, each address is considered as an account + 1, // We only need an address + false, // Segwit not defined so we should use 44' + false, // No change address defined in Tron + 0); + + let address = await this.GetAddress(path[0].path, false); + + return await this._block_chain.GetAccountInfo(address.address); + } + + public async GetAccountTransactions(account: string): Promise> { + return await this._block_chain.GetAccountTransactions(account); + } + + public async GetNowBlock(): Promise + { + return await this._block_chain.GetNowBlock(); + } + + public GenerateTransaction(toAccount: string, amount: number, accountNumber: number): TronTransaction + { + // Validate accountNumber + if(accountNumber >= this._accounts.length){ + throw new Error('Account number is wrong'); + } + + // Check balance + let bal = 0; + var acc = this._accounts[accountNumber]; + if (acc != null && acc.balance != null) { + bal = acc.balance; + } + + bal = bal + - amount + if (bal < 0) + throw new Error("Insufficient balance in your account."); + + let ci = super.GetCoinInfo() as TronCoinInfoModel + let slip44 = ci.slip44; + let path = PathUtil.GetListOfBipPath( + slip44, + accountNumber, // Tron, each address is considered as an account + 1, // We only need an address + false, // Segwit not defined so we should use 44' + false, // No change address defined in Tron + 0); + + let tx: TronTransaction = { + address_n: path[0].path, + }; + return tx; + } + + public async SendTransaction(tx: TronSignedTx): Promise { + return await this._block_chain.BroadCastTransaction(tx.serialized_tx); + } +} From c9c9a555a87ff318580cc62ca158048bd68946cf Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Sat, 24 Jul 2021 13:12:16 +0800 Subject: [PATCH 15/27] update tron types --- .../servers/prokey/src/tron/TronModel.ts | 32 +++++++++++++++++++ src/device/ICoinCommand.ts | 3 +- src/device/RippleCommands.ts | 4 +-- src/wallet/BaseWallet.ts | 5 +-- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/blockchain/servers/prokey/src/tron/TronModel.ts b/src/blockchain/servers/prokey/src/tron/TronModel.ts index 05b2dc9..669e218 100644 --- a/src/blockchain/servers/prokey/src/tron/TronModel.ts +++ b/src/blockchain/servers/prokey/src/tron/TronModel.ts @@ -27,9 +27,40 @@ export type TronAccountInfo = { latest_consume_free_time: number; } +export type TronContractRet = { + contractRet: string; + fee: number; +} + +export type TronContractTransfer = { + amount: number; + owner_address: string; + to_address: string; +} + +export type TronContractParameter = { + value: TronContractTransfer | any; + type: string; +} + +export type TronContract = { + parameter: TronContractParameter; + type: string; +} + +export type TronTransactionRawData = { + contract: Array; + ref_block_bytes: string; + ref_block_hash: string; + expiration: number; + timestamp: number; +} + export type TronTransactionDataInfo = { + ret: Array; signature: Array; txID: string; + raw_data_hex: string; net_usage: number; net_fee: number; energy_usage: number; @@ -37,6 +68,7 @@ export type TronTransactionDataInfo = { block_timestamp: number; energy_fee: number; energy_usage_total: number; + raw_data: TronTransactionRawData; } export type TronTokenInfo = { diff --git a/src/device/ICoinCommand.ts b/src/device/ICoinCommand.ts index 1283997..6f90f4e 100644 --- a/src/device/ICoinCommand.ts +++ b/src/device/ICoinCommand.ts @@ -71,7 +71,8 @@ export interface ICoinCommands { device: Device, transaction:BitcoinTx | EthereumTx | - RippleTransaction, + RippleTransaction | + ProkeyResponses.TronTransaction, ): Promise, showOnProkey?: boolean): Promise { - return await this.GetAddressBase('RippleGetAddress', 'RippleAddress', device, path, showOnProkey); + return await this.GetAddressBase('RippleGetAddress', 'RippleAddress', device, path, showOnProkey); } /** @@ -67,7 +67,7 @@ export class RippleCommands extends BaseCommands implements ICoinCommands { * @param paths list of paths to retrive the addresses */ public async GetAddresses(device: Device, paths: Array>): Promise> { - return await this.GetAddressesBase('RippleGetAddress', 'RippleAddress', device, paths); + return await this.GetAddressesBase('RippleGetAddress', 'RippleAddress', device, paths); } /** diff --git a/src/wallet/BaseWallet.ts b/src/wallet/BaseWallet.ts index 024fa0c..1268db4 100644 --- a/src/wallet/BaseWallet.ts +++ b/src/wallet/BaseWallet.ts @@ -50,7 +50,8 @@ import { TezosSignedTx, BinanceSignTx, CardanoSignedTx, - Success + Success, + TronTransaction } from "../models/Prokey"; import { @@ -159,7 +160,7 @@ export abstract class BaseWallet { * @param tx transaction to be signed by device */ public async SignTransaction - (tx: BitcoinTx | EthereumTx | RippleTransaction): Promise + (tx: BitcoinTx | EthereumTx | RippleTransaction | TronTransaction): Promise { return await this._commands.SignTransaction(this._device, tx) as T; } From ec3cb3c5c593acc25bb6360d37f3f8a7b03f0f8e Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Fri, 30 Jul 2021 20:47:10 +0800 Subject: [PATCH 16/27] Get tron address fixed --- src/device/BaseCommands.ts | 2 +- src/device/TronCommands.ts | 4 ++-- src/wallet/BaseWallet.ts | 12 ++++++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/device/BaseCommands.ts b/src/device/BaseCommands.ts index 80b2452..89b305a 100644 --- a/src/device/BaseCommands.ts +++ b/src/device/BaseCommands.ts @@ -88,7 +88,7 @@ export abstract class BaseCommands { lstAddress.length = paths.length; paths.forEach(async (path) => { - lstAddress.push(await this.GetAddressBase( + lstAddress.push(await this.GetAddressBase( deviceCommand, returnType, device, diff --git a/src/device/TronCommands.ts b/src/device/TronCommands.ts index 2807379..bc3c425 100644 --- a/src/device/TronCommands.ts +++ b/src/device/TronCommands.ts @@ -44,11 +44,11 @@ export class TronCommands extends BaseCommands implements ICoinCommands { } public async GetAddress(device: Device, path: Array, showOnProkey?: boolean): Promise { - return await this.GetAddressBase('TronGetAddress', 'TronAddress', device, path, showOnProkey); + return await this.GetAddressBase('TronGetAddress', 'TronAddress', device, path, showOnProkey); } public async GetAddresses(device: Device, paths: Array>): Promise { - return await this.GetAddressesBase('TronGetAddress', 'TronAddress', device, paths); + return await this.GetAddressesBase('TronGetAddress', 'TronAddress', device, paths); } public async GetPublicKey(device: Device, path: string | number[], showOnProkey?: boolean): Promise { diff --git a/src/wallet/BaseWallet.ts b/src/wallet/BaseWallet.ts index 1268db4..6a56952 100644 --- a/src/wallet/BaseWallet.ts +++ b/src/wallet/BaseWallet.ts @@ -51,7 +51,8 @@ import { BinanceSignTx, CardanoSignedTx, Success, - TronTransaction + TronTransaction, + TronSignedTx } from "../models/Prokey"; import { @@ -65,6 +66,7 @@ import { BitcoinTx } from '../models/BitcoinTx'; import { EthereumTx } from '../models/EthereumTx'; import { RippleCommands } from "../device/RippleCommands"; import { RippleSignedTx, RippleTransaction } from "../models/Prokey"; +import { TronCommands } from "../device/TronCommands"; /** * This is the base class for all implemented wallets @@ -102,6 +104,10 @@ export abstract class BaseWallet { this._commands = new RippleCommands(_coinName); break; + case CoinBaseType.Tron: + this._commands = new TronCommands(_coinName); + break; + default: throw new Error("Unknown coin type"); break; @@ -159,7 +165,9 @@ export abstract class BaseWallet { * Sign Transaction * @param tx transaction to be signed by device */ - public async SignTransaction + public async SignTransaction (tx: BitcoinTx | EthereumTx | RippleTransaction | TronTransaction): Promise { return await this._commands.SignTransaction(this._device, tx) as T; From f7d0c08e39247a1d944b644e98f4123feaa69ca0 Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Wed, 4 Aug 2021 19:39:55 +0800 Subject: [PATCH 17/27] Fix some bugs --- .../servers/prokey/src/tron/TronBlockchain.ts | 3 ++- .../servers/prokey/src/tron/TronModel.ts | 1 + src/models/Prokey.ts | 20 ++++++++++++++- src/wallet/TronWallet.ts | 25 ++++++++++++++++--- 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts b/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts index f47da4d..e80899e 100644 --- a/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts +++ b/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts @@ -52,6 +52,7 @@ export class TronBlockchain extends ProkeyBaseBlockChain { MyConsole.Error("Tron get account transactions error: ", r); return []; } + MyConsole.Info("tron transactions: ", r.data); return r.data; } @@ -66,7 +67,7 @@ export class TronBlockchain extends ProkeyBaseBlockChain { } public async GetNowBlock(): Promise { - return await this.GetFromServer(`getblockcount/${this._coinName}`); + return await this.GetFromServer(`block/getblockcount/${this._coinName}`); } public async BroadCastTransaction(data: string): Promise { diff --git a/src/blockchain/servers/prokey/src/tron/TronModel.ts b/src/blockchain/servers/prokey/src/tron/TronModel.ts index 669e218..d3a9f21 100644 --- a/src/blockchain/servers/prokey/src/tron/TronModel.ts +++ b/src/blockchain/servers/prokey/src/tron/TronModel.ts @@ -93,6 +93,7 @@ export type TronBlockHeaderRawData = { txTrieRoot: string; witness_address: string; parentHash: string; + version: number; timestamp: number; } diff --git a/src/models/Prokey.ts b/src/models/Prokey.ts index 0aa2914..9da9dd1 100644 --- a/src/models/Prokey.ts +++ b/src/models/Prokey.ts @@ -17,6 +17,8 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + +const Long = require('../protobuf/long'); export type CipheredKeyValue = { value: string, @@ -1046,5 +1048,21 @@ export type LoadDeviceFlags = { // Tron types export type TronTransaction = { - + address_n: Array; + timestamp: number; + expiration?: number; + block_header: { + timestamp: number; + tx_trie_root: string; + parent_hash: string; + number: number; + witness_address: string; + version: number; + }; + contract: { + transfer_contract?: { + to_address: string; + amount: number; + } + } } diff --git a/src/wallet/TronWallet.ts b/src/wallet/TronWallet.ts index 6726311..f7b0fba 100644 --- a/src/wallet/TronWallet.ts +++ b/src/wallet/TronWallet.ts @@ -97,7 +97,7 @@ export class TronWallet extends BaseWallet { return await this._block_chain.GetNowBlock(); } - public GenerateTransaction(toAccount: string, amount: number, accountNumber: number): TronTransaction + public async GenerateTransaction(toAccount: string, amount: number, accountNumber: number): Promise { // Validate accountNumber if(accountNumber >= this._accounts.length){ @@ -111,23 +111,40 @@ export class TronWallet extends BaseWallet { bal = acc.balance; } - bal = bal - - amount + bal = bal - amount; if (bal < 0) throw new Error("Insufficient balance in your account."); let ci = super.GetCoinInfo() as TronCoinInfoModel let slip44 = ci.slip44; let path = PathUtil.GetListOfBipPath( - slip44, + slip44, accountNumber, // Tron, each address is considered as an account 1, // We only need an address false, // Segwit not defined so we should use 44' false, // No change address defined in Tron 0); + + // get the now block + let now_block = await this._block_chain.GetNowBlock(); let tx: TronTransaction = { address_n: path[0].path, + timestamp: Date.now(), + block_header: { + number: now_block.block_header.raw_data.number, + parent_hash: now_block.block_header.raw_data.parentHash, + timestamp: now_block.block_header.raw_data.timestamp, + tx_trie_root: now_block.block_header.raw_data.txTrieRoot, + version: now_block.block_header.raw_data.version, + witness_address: now_block.block_header.witness_signature + }, + contract: { + transfer_contract: { + to_address: toAccount, + amount: amount + } + } }; return tx; } From 82a2d9e8ddc6f850518f42411cd418b55e590132 Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Fri, 6 Aug 2021 23:28:50 +0800 Subject: [PATCH 18/27] fix for tron --- data/ProkeyCoinsInfo.json | 4 ++-- .../servers/prokey/src/tron/TronBlockchain.ts | 4 ++++ src/device/Device.ts | 4 ++++ src/device/TronCommands.ts | 2 +- src/wallet/TronWallet.ts | 13 +++++++++++-- 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/data/ProkeyCoinsInfo.json b/data/ProkeyCoinsInfo.json index f25f781..368b0ee 100644 --- a/data/ProkeyCoinsInfo.json +++ b/data/ProkeyCoinsInfo.json @@ -14625,7 +14625,7 @@ "support": { "optimum": "1.10.0" }, - "tx_url": "https://tronscan.org/#/transaction/{hash}", + "tx_url": "https://shasta.tronscan.org/#/transaction/{hash}", "wallets": [ "https://wallet.prokey.io" ] @@ -14641,7 +14641,7 @@ "support": { "optimum": "1.10.0" }, - "tx_url": "https://tronscan.org/#/transaction/{hash}", + "tx_url": "https://nile.tronscan.org/#/transaction/{hash}", "wallets": [ "https://wallet.prokey.io" ] diff --git a/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts b/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts index e80899e..ca0aefe 100644 --- a/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts +++ b/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts @@ -70,6 +70,10 @@ export class TronBlockchain extends ProkeyBaseBlockChain { return await this.GetFromServer(`block/getblockcount/${this._coinName}`); } + public async GetLatestBlock(count: number): Promise { + return await this.GetFromServer(`block/GetLatest/${this._coinName}/${count}`); + } + public async BroadCastTransaction(data: string): Promise { return await this.GetFromServer(`Transaction/send/${this._coinName}/${data}`); } diff --git a/src/device/Device.ts b/src/device/Device.ts index 39c8546..9dc3502 100644 --- a/src/device/Device.ts +++ b/src/device/Device.ts @@ -393,10 +393,14 @@ export class Device { if (res.type === 'Failure') { + res.success = false; console.log("Failure", res); if(this._eventEmitters.emit('OnFailure', res.payload) == false){ MyConsole.Warning('DeviceCommands::OnReceiveDataFromBridge->OnFailure has no listener'); } + if(this._sendMessageReject) { + this._sendMessageReject(res); + } } else if (res.type === 'ButtonRequest') { diff --git a/src/device/TronCommands.ts b/src/device/TronCommands.ts index bc3c425..69d9fa5 100644 --- a/src/device/TronCommands.ts +++ b/src/device/TronCommands.ts @@ -56,7 +56,7 @@ export class TronCommands extends BaseCommands implements ICoinCommands { } public async SignTransaction(device: Device, transaction: TronTransaction): Promise { - throw new Error("Method not implemented."); + return await device.SendMessage("TronSignTx", transaction, "TronSignedTx"); } public async SignMessage(device: Device, path: number[], message: Uint8Array, coinName?: string): Promise { diff --git a/src/wallet/TronWallet.ts b/src/wallet/TronWallet.ts index f7b0fba..ff5a2a1 100644 --- a/src/wallet/TronWallet.ts +++ b/src/wallet/TronWallet.ts @@ -26,6 +26,7 @@ import * as PathUtil from '../utils/pathUtils'; import { TronAddress, TronSignedTx, TronTransaction } from "../models/Prokey"; import { TronBlockchain } from "../blockchain/servers/prokey/src/tron/TronBlockchain"; import { TronAccountInfo, TronBlock, TronTransactionDataInfo } from "../blockchain/servers/prokey/src/tron/TronModel"; +import * as Utils from '../utils/utils'; var WAValidator = require('multicoin-address-validator'); export class TronWallet extends BaseWallet { @@ -126,7 +127,8 @@ export class TronWallet extends BaseWallet { 0); // get the now block - let now_block = await this._block_chain.GetNowBlock(); + let last_block = await this._block_chain.GetLatestBlock(1); + let now_block = last_block.block[0] as TronBlock; let tx: TronTransaction = { address_n: path[0].path, @@ -137,7 +139,7 @@ export class TronWallet extends BaseWallet { timestamp: now_block.block_header.raw_data.timestamp, tx_trie_root: now_block.block_header.raw_data.txTrieRoot, version: now_block.block_header.raw_data.version, - witness_address: now_block.block_header.witness_signature + witness_address: now_block.block_header.raw_data.witness_address }, contract: { transfer_contract: { @@ -150,6 +152,13 @@ export class TronWallet extends BaseWallet { } public async SendTransaction(tx: TronSignedTx): Promise { + let data_any = tx.serialized_tx as any; + if (data_any instanceof Uint8Array) + { + return await this._block_chain.BroadCastTransaction( + Utils.ByteArrayToHexString(data_any).toUpperCase()); + } + return await this._block_chain.BroadCastTransaction(tx.serialized_tx); } } From 0262b0ed61040676ec13413566bd5bffca46ebe5 Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Wed, 11 Aug 2021 12:38:14 +0800 Subject: [PATCH 19/27] First tron tx worked --- protob/combined.proto.txt | 11 +---------- src/models/Prokey.ts | 9 +-------- src/wallet/TronWallet.ts | 10 +--------- 3 files changed, 3 insertions(+), 27 deletions(-) diff --git a/protob/combined.proto.txt b/protob/combined.proto.txt index b42186f..1d74abf 100644 --- a/protob/combined.proto.txt +++ b/protob/combined.proto.txt @@ -3070,19 +3070,10 @@ message TronSignTx { // Common part of transaction optional uint64 timestamp = 2; // UTC timestamp optional uint64 expiration = 3; // Transaction expiration - optional TronBlockHeader block_header = 4; // Now block data + optional string block_id = 4; // Now block id optional TronContract contract = 6; // Contract messages optional uint64 fee_limit = 8; // fee limit - message TronBlockHeader { - optional int64 timestamp = 1; - optional string tx_trie_root = 2; - optional string parent_hash = 3; - optional int64 number = 7; - optional string witness_address = 9; - optional int32 version = 10; - } - /*** * Tron Contracts Messages * diff --git a/src/models/Prokey.ts b/src/models/Prokey.ts index 9da9dd1..698875b 100644 --- a/src/models/Prokey.ts +++ b/src/models/Prokey.ts @@ -1051,14 +1051,7 @@ export type TronTransaction = { address_n: Array; timestamp: number; expiration?: number; - block_header: { - timestamp: number; - tx_trie_root: string; - parent_hash: string; - number: number; - witness_address: string; - version: number; - }; + block_id: string; contract: { transfer_contract?: { to_address: string; diff --git a/src/wallet/TronWallet.ts b/src/wallet/TronWallet.ts index ff5a2a1..e1bdfc3 100644 --- a/src/wallet/TronWallet.ts +++ b/src/wallet/TronWallet.ts @@ -129,18 +129,10 @@ export class TronWallet extends BaseWallet { // get the now block let last_block = await this._block_chain.GetLatestBlock(1); let now_block = last_block.block[0] as TronBlock; - let tx: TronTransaction = { address_n: path[0].path, timestamp: Date.now(), - block_header: { - number: now_block.block_header.raw_data.number, - parent_hash: now_block.block_header.raw_data.parentHash, - timestamp: now_block.block_header.raw_data.timestamp, - tx_trie_root: now_block.block_header.raw_data.txTrieRoot, - version: now_block.block_header.raw_data.version, - witness_address: now_block.block_header.raw_data.witness_address - }, + block_id: now_block.blockID, contract: { transfer_contract: { to_address: toAccount, From 53b086a0aca5cc4e66d0c763dfcbf82b45f1c709 Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Fri, 13 Aug 2021 15:09:56 +0800 Subject: [PATCH 20/27] get account resources --- package.json | 5 +- .../servers/prokey/src/tron/TronBlockchain.ts | 12 ++++- .../servers/prokey/src/tron/TronModel.ts | 14 +++++- src/transport/WebSocketTransport.ts | 1 - src/wallet/TronWallet.ts | 48 +++++++++---------- 5 files changed, 51 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index 2f03f4a..3bbe56b 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,10 @@ "license": "GPL-3.0", "main": "dist/index.js", "types": "dist/index.d.ts", - "files": ["dist/**/*", "protob/**/*"], + "files": [ + "dist/**/*", + "protob/**/*" + ], "description": "This module can be used to communicate with Prokey device", "author": "Prokey Techologies Sdn. Bhd. ", "dependencies": { diff --git a/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts b/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts index ca0aefe..13d1d2d 100644 --- a/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts +++ b/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts @@ -20,7 +20,7 @@ import { MyConsole } from '../../../../../utils/console'; import { ProkeyBaseBlockChain } from '../ProkeyBaseBlockChain'; -import { TronAccountInfo, TronBlock, TronTransactionDataInfo, TronTrc20TransactionDataInfo } from './TronModel'; +import { TronAccountInfo, TronAccountResources, TronBlock, TronTransactionDataInfo, TronTrc20TransactionDataInfo } from './TronModel'; export class TronBlockchain extends ProkeyBaseBlockChain { @@ -45,6 +45,16 @@ export class TronBlockchain extends ProkeyBaseBlockChain { } } + // Get account resources the address must be in HEX format + public async GetAccountResources(account: string): Promise { + try { + return await this.GetFromServer(`address/resources/${this._coinName}/${account}`); + } catch (error) { + MyConsole.Error("Tron get account resources error: ", error); + return null; + } + } + public async GetAccountTransactions(account: string, limit: number = 10): Promise> { let r = await this.GetFromServer(`address/transactions/${this._coinName}/${account}/${limit}`); if (!r.success) diff --git a/src/blockchain/servers/prokey/src/tron/TronModel.ts b/src/blockchain/servers/prokey/src/tron/TronModel.ts index d3a9f21..094d2c7 100644 --- a/src/blockchain/servers/prokey/src/tron/TronModel.ts +++ b/src/blockchain/servers/prokey/src/tron/TronModel.ts @@ -27,6 +27,18 @@ export type TronAccountInfo = { latest_consume_free_time: number; } +export type TronAccountResources = { + freeNetUsed: number; // Free bandwidth used + freeNetLimit: number; // Total free bandwidth + NetLimit: number; // Total bandwidth obtained by freezing + TotalNetLimit: number; // Total bandwidth can be obtained by freezing + TotalNetWeight: number; // Total TRX frozen for bandwidth + tronPowerLimit: number; // TRON Power(vote) + EnergyLimit: number; // Total energy obtained by freezing + TotalEnergyLimit: number; // Total energy can be obtained by freezing + TotalEnergyWeight: number; // Total TRX frozen for energy} +} + export type TronContractRet = { contractRet: string; fee: number; @@ -49,7 +61,7 @@ export type TronContract = { } export type TronTransactionRawData = { - contract: Array; + contract: Array; ref_block_bytes: string; ref_block_hash: string; expiration: number; diff --git a/src/transport/WebSocketTransport.ts b/src/transport/WebSocketTransport.ts index a087082..7ae233a 100644 --- a/src/transport/WebSocketTransport.ts +++ b/src/transport/WebSocketTransport.ts @@ -21,7 +21,6 @@ import { GeneralErrors, GeneralResponse } from "../models/GeneralResponse"; import { IMessagePayload, ITransport } from "./ITransport"; import { IMessageEvent, w3cwebsocket } from "websocket"; -import { MyConsole } from "../utils/console"; export class WebSocketTransport implements ITransport { onReceiveCallback!: (msgPayload: IMessagePayload) => void; diff --git a/src/wallet/TronWallet.ts b/src/wallet/TronWallet.ts index e1bdfc3..28eeef9 100644 --- a/src/wallet/TronWallet.ts +++ b/src/wallet/TronWallet.ts @@ -25,24 +25,23 @@ import { BaseWallet } from "./BaseWallet"; import * as PathUtil from '../utils/pathUtils'; import { TronAddress, TronSignedTx, TronTransaction } from "../models/Prokey"; import { TronBlockchain } from "../blockchain/servers/prokey/src/tron/TronBlockchain"; -import { TronAccountInfo, TronBlock, TronTransactionDataInfo } from "../blockchain/servers/prokey/src/tron/TronModel"; +import { TronAccountInfo, TronAccountResources, TronBlock, TronTransactionDataInfo } from "../blockchain/servers/prokey/src/tron/TronModel"; import * as Utils from '../utils/utils'; var WAValidator = require('multicoin-address-validator'); export class TronWallet extends BaseWallet { - _block_chain : TronBlockchain; + _block_chain: TronBlockchain; _accounts: Array; - constructor(device: Device, coinName: string) - { - super(device, coinName, CoinBaseType.Tron); + constructor(device: Device, coinName: string) { + super(device, coinName, CoinBaseType.Tron); this._block_chain = new TronBlockchain(this.GetCoinInfo().shortcut); this._accounts = []; } - + public IsAddressValid(address: string): boolean { - if(WAValidator.validate(address, "trx")) { + if (WAValidator.validate(address, "trx")) { return true; } @@ -51,16 +50,13 @@ export class TronWallet extends BaseWallet { public async StartDiscovery( accountFindCallBack?: (accountInfo: TronAccountInfo) => void - ): Promise> - { + ): Promise> { return new Promise>(async (resolve, reject) => { let an = 0; this._accounts = new Array(); - do - { + do { let account = await this.GetAccountInfo(an); - if (account == null) - { + if (account == null) { // there is nothing here return resolve(this._accounts); } @@ -69,7 +65,7 @@ export class TronWallet extends BaseWallet { accountFindCallBack(account); } an++; - } while(true); + } while (true); }); } @@ -77,31 +73,34 @@ export class TronWallet extends BaseWallet { private async GetAccountInfo(accountNumber: number): Promise { let slip44 = (super.GetCoinInfo() as TronCoinInfoModel).slip44; let path = PathUtil.GetListOfBipPath( - slip44, + slip44, accountNumber, // Tron, each address is considered as an account 1, // We only need an address false, // Segwit not defined so we should use 44' false, // No change address defined in Tron 0); - + let address = await this.GetAddress(path[0].path, false); return await this._block_chain.GetAccountInfo(address.address); } + // Get account resources the address must be in HEX format + public async GetAccountResources(account: string): Promise { + return await this._block_chain.GetAccountResources(account); + } + public async GetAccountTransactions(account: string): Promise> { return await this._block_chain.GetAccountTransactions(account); } - public async GetNowBlock(): Promise - { + public async GetNowBlock(): Promise { return await this._block_chain.GetNowBlock(); } - public async GenerateTransaction(toAccount: string, amount: number, accountNumber: number): Promise - { + public async GenerateTransaction(toAccount: string, amount: number, accountNumber: number): Promise { // Validate accountNumber - if(accountNumber >= this._accounts.length){ + if (accountNumber >= this._accounts.length) { throw new Error('Account number is wrong'); } @@ -119,7 +118,7 @@ export class TronWallet extends BaseWallet { let ci = super.GetCoinInfo() as TronCoinInfoModel let slip44 = ci.slip44; let path = PathUtil.GetListOfBipPath( - slip44, + slip44, accountNumber, // Tron, each address is considered as an account 1, // We only need an address false, // Segwit not defined so we should use 44' @@ -145,10 +144,9 @@ export class TronWallet extends BaseWallet { public async SendTransaction(tx: TronSignedTx): Promise { let data_any = tx.serialized_tx as any; - if (data_any instanceof Uint8Array) - { + if (data_any instanceof Uint8Array) { return await this._block_chain.BroadCastTransaction( - Utils.ByteArrayToHexString(data_any).toUpperCase()); + Utils.ByteArrayToHexString(data_any).toUpperCase()); } return await this._block_chain.BroadCastTransaction(tx.serialized_tx); From 8feb10608309e16c0036cb406f11e05f830dc2e5 Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Fri, 20 Aug 2021 12:17:24 +0800 Subject: [PATCH 21/27] Update combined.proto.txt --- protob/combined.proto.txt | 82 +++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 43 deletions(-) diff --git a/protob/combined.proto.txt b/protob/combined.proto.txt index 1d74abf..b2911ed 100644 --- a/protob/combined.proto.txt +++ b/protob/combined.proto.txt @@ -3070,7 +3070,7 @@ message TronSignTx { // Common part of transaction optional uint64 timestamp = 2; // UTC timestamp optional uint64 expiration = 3; // Transaction expiration - optional string block_id = 4; // Now block id + optional string block_id = 4; // Now block ID optional TronContract contract = 6; // Contract messages optional uint64 fee_limit = 8; // fee limit @@ -3079,19 +3079,15 @@ message TronSignTx { * */ message TronContract { - // Update account name - message TronAccountUpdateContract { - optional string account_name = 1; // Account name is not unique - } // Transfer TRX message TronTransferContract { optional string to_address = 1; // To address - optional uint64 amount = 2; // TRX amount in sun (10^-6) + optional uint64 amount = 2; // TRX amount in sun (10^-6) } // Transfer asset message TronTransferAssetContract { - optional string asset_name = 1; // Asset name - optional string to_address = 2; // To address + optional string asset_name = 1; // Asset name is token id in hex string ex: "31303030303031" + optional string to_address = 2; // To address optional uint64 amount = 3; // Amount to transfer } // Vote witness @@ -3102,14 +3098,6 @@ message TronSignTx { } repeated TronVote votes = 1; // votes } - // Upgrade account to witness - message TronWitnessCreateContract { - optional string url = 1; // Witness URL - } - // Update witness URL - message TronWitnessUpdateContract { - optional string update_url = 2; // Witness URL - } // Issue Asset message TronAssetIssueContract { message TronFrozenSupply { @@ -3133,13 +3121,21 @@ message TronSignTx { optional string asset_name = 2; // The name of target asset optional uint64 amount = 3; // TRX amount in sun } + enum TronResourceCode { + BANDWIDTH = 0x00; + ENERGY = 0x01; + } // Freeze TRX balance message TronFreezeBalanceContract { optional uint64 frozen_balance = 1; // Amount to freeze - optional uint64 frozen_duration = 2; // Freeze minimal duration in days - } + optional uint64 frozen_duration = 2; // (Optional)Freeze minimal duration in days currently 3 days is fixed on tron network + optional TronResourceCode resource = 3; // Freeze the balance to get bandwidth or energy + optional string receiver_address = 4; // (Optional)Energy or bandwidth receiver address + } // Unfreeze TRX Balance message TronUnfreezeBalanceContract { + optional TronResourceCode resource = 3; // Unfreeze the bandwidth or energy + optional string receiver_address = 4; // (Optional)Energy or bandwidth receiver address } // Unfreeze Asset Balance message TronUnfreezeAssetContract { @@ -3152,39 +3148,38 @@ message TronSignTx { optional string description = 1; // New description optional string url = 2; // New URL } - // Network proposal contract - message TronProposalCreateContract { - message TronProposalParameters { - optional uint64 key = 1; // Parameter key - optional uint64 value = 2; // Parameter value - } - repeated TronProposalParameters parameters = 1; // Parameter to be changed - } // Approval contract message TronProposalApproveContract { optional uint64 proposal_id = 1; // Proposal ID optional bool is_add_approval = 2; // Add or remove approval } - // Delete proposal - message TronProposalDeleteContract { - optional uint64 proposal_id = 1; // Proposal ID + // Trigger smart contract + message TronTriggerSmartContract { + optional string contract_address = 1; // The contract address + optional int64 call_value = 2; // The amount of TRX to send to the contract when triggers. + optional bytes data = 3; // The parameters to trigger the contract. + optional int64 call_token_value = 4; // The amount of TRC-10 token to send to the contract when triggers. + optional int64 token_id = 5; // The id of the TRC-10 token to be sent to the contract. + } + // Transger TRC20 + message TronTransferTRC20 { // This is a helper function to ease sending of TRC20 tokens + optional string contract_address = 1; // The TRC20 contract address + optional string to_address = 2; // The to address + optional bytes amount = 3; // <=256 bit unsigned big endian } optional TronTransferContract transfer_contract = 1; optional TronTransferAssetContract transfer_asset_contract = 2; - optional TronVoteWitnessContract vote_witness_contract = 4; - optional TronWitnessCreateContract witness_create_contract = 5; - optional TronAssetIssueContract asset_issue_contract = 6; - optional TronWitnessUpdateContract witness_update_contract = 8; - optional TronParticipateAssetIssueContract participate_asset_issue_contract = 9; - optional TronAccountUpdateContract account_update_contract = 10; - optional TronFreezeBalanceContract freeze_balance_contract = 11; - optional TronUnfreezeBalanceContract unfreeze_balance_contract = 12; - optional TronWithdrawBalanceContract withdraw_balance_contract = 13; - optional TronUnfreezeAssetContract unfreeze_asset_contract = 14; - optional TronUpdateAssetContract update_asset_contract = 15; - optional TronProposalCreateContract proposal_create_contract = 16; - optional TronProposalApproveContract proposal_approve_contract = 17; - optional TronProposalDeleteContract proposal_delete_contract = 18; + optional TronVoteWitnessContract vote_witness_contract = 3; + optional TronAssetIssueContract asset_issue_contract = 4; + optional TronParticipateAssetIssueContract participate_asset_issue_contract = 5; + optional TronFreezeBalanceContract freeze_balance_contract = 6; + optional TronUnfreezeBalanceContract unfreeze_balance_contract = 7; + optional TronWithdrawBalanceContract withdraw_balance_contract = 8; + optional TronUnfreezeAssetContract unfreeze_asset_contract = 9; + optional TronUpdateAssetContract update_asset_contract = 10; + optional TronProposalApproveContract proposal_approve_contract = 11; + optional TronTriggerSmartContract trigger_smart_contract = 12; + optional TronTransferTRC20 transfer_trc20 = 13; } } @@ -3194,6 +3189,7 @@ message TronSignTx { */ message TronSignedTx { optional bytes serialized_tx = 1; // Serialized transaction + optional bytes signature = 2; // transaction signature } /** From 83a2daf05682a9d344d3639f6d6529161428b2ce Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Sun, 22 Aug 2021 22:54:12 +0800 Subject: [PATCH 22/27] minor update to Tron account resources --- .../servers/prokey/src/tron/TronBlockchain.ts | 19 ++++++++++--------- .../servers/prokey/src/tron/TronModel.ts | 1 + 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts b/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts index 13d1d2d..fe06681 100644 --- a/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts +++ b/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts @@ -30,12 +30,11 @@ export class TronBlockchain extends ProkeyBaseBlockChain { super(); this._coinName = coinName; } - + public async GetAccountInfo(account: string): Promise { try { - let r = await this.GetFromServer(`address/${this._coinName}/${account}`); - if (!r.success) - { + let r = await this.GetFromServer(`address/${this._coinName}/${account}`); + if (!r.success) { MyConsole.Error("Tron get account info error: ", r); return null; } @@ -48,7 +47,11 @@ export class TronBlockchain extends ProkeyBaseBlockChain { // Get account resources the address must be in HEX format public async GetAccountResources(account: string): Promise { try { - return await this.GetFromServer(`address/resources/${this._coinName}/${account}`); + let r = await this.GetFromServer(`address/resources/${this._coinName}/${account}`); + if (r.freeNetUsed == undefined) { + r.freeNetUsed = 0; + } + return r; } catch (error) { MyConsole.Error("Tron get account resources error: ", error); return null; @@ -57,8 +60,7 @@ export class TronBlockchain extends ProkeyBaseBlockChain { public async GetAccountTransactions(account: string, limit: number = 10): Promise> { let r = await this.GetFromServer(`address/transactions/${this._coinName}/${account}/${limit}`); - if (!r.success) - { + if (!r.success) { MyConsole.Error("Tron get account transactions error: ", r); return []; } @@ -68,8 +70,7 @@ export class TronBlockchain extends ProkeyBaseBlockChain { public async GetAccountTrc20Transactions(account: string, limit: number = 10): Promise> { let r = await this.GetFromServer(`address/trc20/transactions/${this._coinName}/${account}/${limit}`); - if (!r.success) - { + if (!r.success) { MyConsole.Error("Tron get account TRC20 transactions error: ", r); return []; } diff --git a/src/blockchain/servers/prokey/src/tron/TronModel.ts b/src/blockchain/servers/prokey/src/tron/TronModel.ts index 094d2c7..a8f6c87 100644 --- a/src/blockchain/servers/prokey/src/tron/TronModel.ts +++ b/src/blockchain/servers/prokey/src/tron/TronModel.ts @@ -33,6 +33,7 @@ export type TronAccountResources = { NetLimit: number; // Total bandwidth obtained by freezing TotalNetLimit: number; // Total bandwidth can be obtained by freezing TotalNetWeight: number; // Total TRX frozen for bandwidth + tronPowerUsed: number; // TRON power used tronPowerLimit: number; // TRON Power(vote) EnergyLimit: number; // Total energy obtained by freezing TotalEnergyLimit: number; // Total energy can be obtained by freezing From bf90d878a422e26d352b6819dba7f04b71897d6f Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Wed, 25 Aug 2021 14:59:04 +0800 Subject: [PATCH 23/27] Add tron freeze --- .../servers/prokey/src/tron/TronBlockchain.ts | 13 +++++++++ .../servers/prokey/src/tron/TronModel.ts | 1 + src/models/Prokey.ts | 28 +++++++++++++++---- src/wallet/TronWallet.ts | 10 ++++++- 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts b/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts index fe06681..cbf310a 100644 --- a/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts +++ b/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts @@ -48,9 +48,22 @@ export class TronBlockchain extends ProkeyBaseBlockChain { public async GetAccountResources(account: string): Promise { try { let r = await this.GetFromServer(`address/resources/${this._coinName}/${account}`); + MyConsole.Info("Tron account resources: ", r); if (r.freeNetUsed == undefined) { r.freeNetUsed = 0; } + if (r.EnergyLimit == undefined) { + r.EnergyLimit = 0; + } + if (r.EnergyUsed == undefined) { + r.EnergyUsed = 0; + } + if (r.tronPowerLimit == undefined) { + r.tronPowerLimit = 0; + } + if (r.tronPowerUsed == undefined) { + r.tronPowerUsed = 0; + } return r; } catch (error) { MyConsole.Error("Tron get account resources error: ", error); diff --git a/src/blockchain/servers/prokey/src/tron/TronModel.ts b/src/blockchain/servers/prokey/src/tron/TronModel.ts index a8f6c87..78ac464 100644 --- a/src/blockchain/servers/prokey/src/tron/TronModel.ts +++ b/src/blockchain/servers/prokey/src/tron/TronModel.ts @@ -36,6 +36,7 @@ export type TronAccountResources = { tronPowerUsed: number; // TRON power used tronPowerLimit: number; // TRON Power(vote) EnergyLimit: number; // Total energy obtained by freezing + EnergyUsed: number; // Total energy obtained by freezing TotalEnergyLimit: number; // Total energy can be obtained by freezing TotalEnergyWeight: number; // Total TRX frozen for energy} } diff --git a/src/models/Prokey.ts b/src/models/Prokey.ts index 698875b..5c0aab3 100644 --- a/src/models/Prokey.ts +++ b/src/models/Prokey.ts @@ -1047,15 +1047,31 @@ export type LoadDeviceFlags = { } // Tron types +export enum TronResourceCode { + BANDWIDTH = 0x00, + ENERGY = 0x01 +} + +export type TronFreezeBalance = { + frozen_balance: number; // Amount to freeze + frozen_duration?: number; // (Optional)Freeze minimal duration in days currently 3 days is fixed on tron network + resource: TronResourceCode; // Freeze the balance to get bandwidth or energy + receiver_address?: string; // (Optional)Energy or bandwidth receiver address +} + export type TronTransaction = { address_n: Array; - timestamp: number; - expiration?: number; - block_id: string; + timestamp: number; // UTC timestamp + expiration?: number; // Transaction expiration + block_id: string; // Now block ID + fee_limit?: number; // Max fee in TRX when calling contract address contract: { + // Transfer TRX transfer_contract?: { - to_address: string; - amount: number; - } + to_address: string; // To address + amount: number; // TRX amount in sun (10^-6) + }; + // Freeze TRX balance + freeze_balance_contract?: TronFreezeBalance; } } diff --git a/src/wallet/TronWallet.ts b/src/wallet/TronWallet.ts index 28eeef9..a9e3244 100644 --- a/src/wallet/TronWallet.ts +++ b/src/wallet/TronWallet.ts @@ -23,7 +23,7 @@ import { Device } from "../device/Device"; import { TronCoinInfoModel } from "../models/CoinInfoModel"; import { BaseWallet } from "./BaseWallet"; import * as PathUtil from '../utils/pathUtils'; -import { TronAddress, TronSignedTx, TronTransaction } from "../models/Prokey"; +import { TronAddress, TronFreezeBalance, TronSignedTx, TronTransaction } from "../models/Prokey"; import { TronBlockchain } from "../blockchain/servers/prokey/src/tron/TronBlockchain"; import { TronAccountInfo, TronAccountResources, TronBlock, TronTransactionDataInfo } from "../blockchain/servers/prokey/src/tron/TronModel"; import * as Utils from '../utils/utils'; @@ -142,6 +142,14 @@ export class TronWallet extends BaseWallet { return tx; } + public async GenerateFreezeBalanceTransaction(data: TronFreezeBalance, accountNumber: number): Promise { + let tx = await this.GenerateTransaction("test", data.frozen_balance, accountNumber); + tx.contract.transfer_contract = undefined; + tx.contract.freeze_balance_contract = data; + data.frozen_balance = Math.floor(data.frozen_balance) * 1000000; + return tx; + } + public async SendTransaction(tx: TronSignedTx): Promise { let data_any = tx.serialized_tx as any; if (data_any instanceof Uint8Array) { From d2abab9bf3aca5ca61ae9a4d5a365b0666cdf4fc Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Wed, 1 Sep 2021 15:14:37 +0800 Subject: [PATCH 24/27] update from main and fix errors --- src/device/ICoinCommand.ts | 5 +++-- src/wallet/BaseWallet.ts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/device/ICoinCommand.ts b/src/device/ICoinCommand.ts index 6f90f4e..e48590c 100644 --- a/src/device/ICoinCommand.ts +++ b/src/device/ICoinCommand.ts @@ -26,11 +26,12 @@ import { BitcoinBaseCoinInfoModel, EthereumBaseCoinInfoModel, OmniCoinInfoModel, - RippleCoinInfoModel } from '../models/CoinInfoModel'; + RippleCoinInfoModel, + TronCoinInfoModel} from '../models/CoinInfoModel'; import { RippleTransaction } from '../models/Prokey'; export interface ICoinCommands { - GetCoinInfo() : BitcoinBaseCoinInfoModel | EthereumBaseCoinInfoModel | OmniCoinInfoModel | RippleCoinInfoModel | null; + GetCoinInfo() : BitcoinBaseCoinInfoModel | EthereumBaseCoinInfoModel | OmniCoinInfoModel | RippleCoinInfoModel | TronCoinInfoModel | null; GetAddress( device: Device, diff --git a/src/wallet/BaseWallet.ts b/src/wallet/BaseWallet.ts index 6397cc3..bd56e88 100644 --- a/src/wallet/BaseWallet.ts +++ b/src/wallet/BaseWallet.ts @@ -105,7 +105,7 @@ export abstract class BaseWallet { break; case CoinBaseType.Tron: - this._commands = new TronCommands(_coinName); + this._commands = new TronCommands(coinName); break; default: From 9345cac96107fc81e94d64ea603eecdd0c7be59a Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Wed, 1 Sep 2021 20:09:59 +0800 Subject: [PATCH 25/27] fix coin info for tron --- src/coins/CoinInfo.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/coins/CoinInfo.ts b/src/coins/CoinInfo.ts index 44a854f..7422bca 100644 --- a/src/coins/CoinInfo.ts +++ b/src/coins/CoinInfo.ts @@ -133,6 +133,10 @@ export class CoinInfo { ci.id = `ripple_${ci.shortcut}`; break; + case CoinBaseType.Tron: + ci = c.find(obj => obj.name.toLowerCase() == f || obj.shortcut.toLowerCase() == f); + ci.id = `tron_${ci.shortcut}`; + break; default: ci = c.find(obj => obj.name.toLowerCase() == f || obj.shortcut.toLowerCase() == f); @@ -334,6 +338,18 @@ export class CoinInfo { } }); + //! For all Tron base coins + ProkeyCoinInfoModel.tron.forEach(tron => { + //! Check the version + if(compareVersions(firmwareVersion, tron.support.optimum) >= 0) { + list.push({ + ...tron, + coinBaseType: CoinBaseType.Tron, + id: `tron${tron.shortcut}`, + }) + } + }); + //! Sort the list by Priority list.sort((a, b) => { if (a.priority > b.priority) From 86906a2495b1b34446d6d5ef0c96e616ab8ea4ce Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Tue, 23 Nov 2021 22:50:57 +0800 Subject: [PATCH 26/27] Add tron unfreeze --- .../servers/prokey/src/tron/TronBlockchain.ts | 6 ++++++ src/blockchain/servers/prokey/src/tron/TronModel.ts | 13 +++++++++++++ src/models/CoinInfoModel.ts | 2 +- src/models/Prokey.ts | 11 +++++++++-- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts b/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts index cbf310a..67c011b 100644 --- a/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts +++ b/src/blockchain/servers/prokey/src/tron/TronBlockchain.ts @@ -64,6 +64,12 @@ export class TronBlockchain extends ProkeyBaseBlockChain { if (r.tronPowerUsed == undefined) { r.tronPowerUsed = 0; } + if (r.NetLimit == undefined) { + r.NetLimit = 0; + } + if (r.NetUsed == undefined) { + r.NetUsed = 0; + } return r; } catch (error) { MyConsole.Error("Tron get account resources error: ", error); diff --git a/src/blockchain/servers/prokey/src/tron/TronModel.ts b/src/blockchain/servers/prokey/src/tron/TronModel.ts index 78ac464..1bce012 100644 --- a/src/blockchain/servers/prokey/src/tron/TronModel.ts +++ b/src/blockchain/servers/prokey/src/tron/TronModel.ts @@ -20,17 +20,30 @@ export type TronAccountInfo = { latest_opration_time: number; + account_resource?: { + frozen_balance_for_energy?: { + frozen_balance: number, + expire_time: number + }; + delegated_frozen_balance_for_energy?: number; + }; address: string; balance: number; create_time: number; trc20?: Array; // TRC20 balances latest_consume_free_time: number; + frozen?: Array<{ + frozen_balance: number, + expire_time: number + }>; + delegated_frozen_balance_for_bandwidth?: number; } export type TronAccountResources = { freeNetUsed: number; // Free bandwidth used freeNetLimit: number; // Total free bandwidth NetLimit: number; // Total bandwidth obtained by freezing + NetUsed: number; // Total bandwidth used TotalNetLimit: number; // Total bandwidth can be obtained by freezing TotalNetWeight: number; // Total TRX frozen for bandwidth tronPowerUsed: number; // TRON power used diff --git a/src/models/CoinInfoModel.ts b/src/models/CoinInfoModel.ts index 105c7d7..b8d816c 100644 --- a/src/models/CoinInfoModel.ts +++ b/src/models/CoinInfoModel.ts @@ -128,7 +128,7 @@ export interface RippleCoinInfoModel extends BaseCoinInfoModel { priority: number, } -export type TronCoinInfoModel = { +export interface TronCoinInfoModel extends BaseCoinInfoModel { name: string, shortcut: string, slip44: number, diff --git a/src/models/Prokey.ts b/src/models/Prokey.ts index 5c0aab3..f0ddde2 100644 --- a/src/models/Prokey.ts +++ b/src/models/Prokey.ts @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + const Long = require('../protobuf/long'); export type CipheredKeyValue = { @@ -307,7 +307,7 @@ export type SignTxInfo = { inputs_cnt: number, outputs_cnt: number, extra_data_len?: number, - timestamp:number, + timestamp: number, version_group_id: number, }; @@ -1059,6 +1059,13 @@ export type TronFreezeBalance = { receiver_address?: string; // (Optional)Energy or bandwidth receiver address } +// Unfreeze TRX Balance +export type TronUnfreezeBalance = { + resource: TronResourceCode; // Unfreeze the bandwidth or energy + receiver_address: string; // (Optional)Energy or bandwidth receiver address +} + + export type TronTransaction = { address_n: Array; timestamp: number; // UTC timestamp From ad6448d2edad0aa4df2611d2c8f6dd7db2eb5314 Mon Sep 17 00:00:00 2001 From: Ali Akbar Mohammadi Date: Mon, 6 Dec 2021 16:27:34 +0800 Subject: [PATCH 27/27] Update CoinInfoModel.ts --- src/models/CoinInfoModel.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/models/CoinInfoModel.ts b/src/models/CoinInfoModel.ts index d533187..2387683 100644 --- a/src/models/CoinInfoModel.ts +++ b/src/models/CoinInfoModel.ts @@ -27,6 +27,7 @@ export type GeneralCoinInfoModel = BitcoinBaseCoinInfoModel | Erc20BaseCoinInfoModel | RippleCoinInfoModel | OmniCoinInfoModel | + TronCoinInfoModel | MiscCoinInfoModel; export interface BaseCoinInfoModel {