-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
1,441 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
syntax = "proto2"; | ||
package hw.trezor.messages.benfen; | ||
|
||
// Sugar for easier handling in Java | ||
option java_package = "com.satoshilabs.trezor.lib.protobuf"; | ||
option java_outer_classname = "TrezorMessageSui"; | ||
|
||
/** | ||
* Request: Address at the specified index | ||
* @start | ||
* @next BenfenAddress | ||
*/ | ||
message BenfenGetAddress { | ||
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: Address for the given index | ||
* @end | ||
*/ | ||
message BenfenAddress { | ||
optional string address = 1; // Benfen address as hex-encoded string | ||
} | ||
|
||
/** | ||
* Request: ask device to sign Sui transaction | ||
* @start | ||
* @next BenfenSignedTx/SuiTxRequest | ||
*/ | ||
message BenfenSignTx { | ||
repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node | ||
required bytes raw_tx = 2; // serialized raw transaction | ||
optional bytes data_initial_chunk = 3 [default='']; // The initial data chunk (<= 1024 bytes) | ||
optional bytes coin_type = 4; | ||
optional uint32 data_length = 5; // Length of transaction payload | ||
} | ||
|
||
|
||
/** | ||
* Response: signature for transaction | ||
* @end | ||
*/ | ||
message BenfenSignedTx { | ||
required bytes public_key = 1; // public key for the private key used to sign tx | ||
required bytes signature = 2; // the signature of the raw transaction | ||
} | ||
|
||
/** | ||
* Response: Device asks for more data from transaction payload, or returns the signature. | ||
* If data_length is set, device awaits that many more bytes of payload. | ||
* Otherwise, the signature fields contain the computed transaction signature. All three fields will be present. | ||
* @end | ||
* @next SuiTxAck | ||
*/ | ||
message BenfenTxRequest { | ||
optional uint32 data_length = 1; // Number of bytes being requested (<= 1024) | ||
optional bytes public_key = 2; // public key for the private key used to sign tx | ||
optional bytes signature = 3; // the signature of the raw transaction | ||
} | ||
|
||
/** | ||
* Request: Transaction payload data. | ||
* @next BenfenTxRequest | ||
*/ | ||
message BenfenTxAck { | ||
required bytes data_chunk = 1; // Bytes from transaction payload (<= 1024 bytes) | ||
} | ||
|
||
/** | ||
* Request: Ask device to sign message | ||
* @next SuiMessageSignature | ||
* @next Failure | ||
*/ | ||
message BenfenSignMessage { | ||
repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node | ||
required bytes message = 2; // message to be signed | ||
} | ||
|
||
/** | ||
* Response: Signed message | ||
* @end | ||
*/ | ||
message BenfenMessageSignature { | ||
required bytes signature = 1; // signature of the message | ||
required string address = 2; // address used to sign the message | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
from apps.common.paths import PATTERN_BIP44_ED25519 | ||
|
||
CURVE = "ed25519" | ||
SLIP44_ID = 728 | ||
|
||
PATTERN = PATTERN_BIP44_ED25519 | ||
PRIMARY_COLOR = 0xCD4937 | ||
ICON = "A:/res/chain-benfen.png" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
from typing import TYPE_CHECKING | ||
|
||
from trezor.lvglui.scrs import lv | ||
from trezor.messages import BenfenAddress | ||
from trezor.ui.layouts import show_address | ||
|
||
from apps.common import paths, seed | ||
from apps.common.keychain import auto_keychain | ||
|
||
from . import ICON, PRIMARY_COLOR | ||
from .helper import benfen_address_from_pubkey, try_convert_to_bfc_address | ||
|
||
if TYPE_CHECKING: | ||
from trezor.messages import BenfenGetAddress | ||
from trezor.wire import Context | ||
from apps.common.keychain import Keychain | ||
|
||
|
||
@auto_keychain(__name__) | ||
async def get_address( | ||
ctx: Context, msg: BenfenGetAddress, keychain: Keychain | ||
) -> BenfenAddress: | ||
await paths.validate_path(ctx, keychain, msg.address_n) | ||
ctx.primary_color, ctx.icon_path = lv.color_hex(PRIMARY_COLOR), ICON | ||
node = keychain.derive(msg.address_n) | ||
pub_key_bytes = seed.remove_ed25519_prefix(node.public_key()) | ||
address = benfen_address_from_pubkey(pub_key_bytes) | ||
|
||
bfc_address = try_convert_to_bfc_address(address) | ||
if bfc_address: | ||
address = bfc_address | ||
|
||
if msg.show_display: | ||
path = paths.address_n_to_str(msg.address_n) | ||
await show_address( | ||
ctx, | ||
address=address, | ||
address_n=path, | ||
network="BENFEN", | ||
) | ||
return BenfenAddress(address=address) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
from ubinascii import hexlify | ||
|
||
from trezor.crypto.hashlib import blake2b, sha256 | ||
from trezor.strings import format_amount | ||
|
||
INTENT_BYTES = b"\x00\x00\x00" | ||
PERSONALMESSAGE_INTENT_BYTES = b"\x03\x00\x00" | ||
|
||
|
||
def benfen_address_from_pubkey(pub_key_bytes: bytes) -> str: | ||
payloads = b"\x00" + pub_key_bytes | ||
h = blake2b(data=payloads, outlen=32).digest() | ||
return f"0x{hexlify(h).decode()}" | ||
|
||
|
||
def try_convert_to_bfc_address(sui_addr: str) -> str | None: | ||
|
||
if len(sui_addr) < 3 or not (sui_addr[0] == "0" and (sui_addr[1] in "xX")): | ||
return None | ||
|
||
hex_part = sui_addr[2:] | ||
if len(hex_part) == 0 or len(hex_part) > 64: | ||
return None | ||
|
||
for c in hex_part: | ||
if not (c.isdigit() or c in "abcdefABCDEF"): | ||
return None | ||
|
||
padding = 64 - len(hex_part) | ||
if padding > 0: | ||
hex_part = "0" * padding + hex_part | ||
|
||
h = sha256() | ||
h.update(hex_part.encode("utf-8")) | ||
digest = h.digest() | ||
|
||
checksum = "".join([f"{b:02x}" for b in digest[:2]]) | ||
|
||
return "BFC" + hex_part + checksum | ||
|
||
|
||
def uleb_encode(num: int) -> bytes: | ||
arr = bytearray() | ||
while num > 0: | ||
val = num & 127 | ||
num = num >> 7 | ||
if num != 0: | ||
val |= 128 | ||
arr.append(val) | ||
return arr | ||
|
||
|
||
def format_benfen_amount(amount: int, currency_symbol: str = "BFC") -> str: | ||
|
||
decimals = 9 | ||
formatted = format_amount(amount, decimals) | ||
return f"{formatted} {currency_symbol}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
from trezor.enums import ButtonRequestType | ||
from trezor.lvglui.i18n import gettext as _, keys as i18n_keys | ||
from trezor.ui.layouts import should_show_details | ||
from trezor.wire import Context | ||
|
||
from .helper import format_benfen_amount | ||
|
||
|
||
async def require_show_overview( | ||
ctx: Context, | ||
to_addr: str, | ||
value: int, | ||
currency_symbol: str = "BFC", | ||
) -> bool: | ||
from trezor.strings import strip_amount | ||
|
||
return await should_show_details( | ||
ctx, | ||
title=_(i18n_keys.TITLE__SEND_MULTILINE).format( | ||
strip_amount(format_benfen_amount(value, currency_symbol))[0] | ||
), | ||
address=to_addr, | ||
br_code=ButtonRequestType.SignTx, | ||
) | ||
|
||
|
||
async def require_confirm_fee( | ||
ctx: Context, | ||
from_address: str, | ||
to_address: str, | ||
value: int, | ||
gas_price: int, | ||
gas_budget: int, | ||
currency_symbol: str = "BFC", | ||
) -> None: | ||
from trezor.ui.layouts.lvgl.altcoin import confirm_total_ethereum | ||
|
||
total_amount = ( | ||
format_benfen_amount(value + gas_price, currency_symbol) | ||
if currency_symbol == "BFC" | ||
else None | ||
) | ||
fee_currency = currency_symbol if currency_symbol == "BFC" else "BFC" | ||
|
||
await confirm_total_ethereum( | ||
ctx=ctx, | ||
amount=format_benfen_amount(value, currency_symbol), | ||
gas_price=None, | ||
fee_max=format_benfen_amount(gas_price, fee_currency), | ||
from_address=from_address, | ||
to_address=to_address, | ||
total_amount=total_amount, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from trezor import wire | ||
from trezor.crypto.curve import ed25519 | ||
from trezor.crypto.hashlib import blake2b | ||
from trezor.lvglui.scrs import lv | ||
from trezor.messages import BenfenMessageSignature, BenfenSignMessage | ||
|
||
from apps.common import paths, seed | ||
from apps.common.keychain import Keychain, auto_keychain | ||
from apps.common.signverify import decode_message | ||
|
||
from . import ICON, PRIMARY_COLOR | ||
from .helper import ( | ||
PERSONALMESSAGE_INTENT_BYTES, | ||
benfen_address_from_pubkey, | ||
try_convert_to_bfc_address, | ||
uleb_encode, | ||
) | ||
|
||
|
||
@auto_keychain(__name__) | ||
async def sign_message( | ||
ctx: wire.Context, msg: BenfenSignMessage, keychain: Keychain | ||
) -> BenfenMessageSignature: | ||
|
||
await paths.validate_path(ctx, keychain, msg.address_n) | ||
|
||
node = keychain.derive(msg.address_n) | ||
pub_key_bytes = seed.remove_ed25519_prefix(node.public_key()) | ||
address = benfen_address_from_pubkey(pub_key_bytes) | ||
bfc_address = try_convert_to_bfc_address(address) | ||
if bfc_address is None: | ||
raise wire.DataError("bfc_address is none") | ||
|
||
len_bytes = uleb_encode(len(msg.message)) | ||
intentMessage = PERSONALMESSAGE_INTENT_BYTES + len_bytes + msg.message | ||
|
||
from trezor.ui.layouts import confirm_signverify | ||
|
||
ctx.primary_color, ctx.icon_path = lv.color_hex(PRIMARY_COLOR), ICON | ||
await confirm_signverify( | ||
ctx, "Benfen", decode_message(msg.message), bfc_address, False | ||
) | ||
|
||
signature = ed25519.sign( | ||
node.private_key(), blake2b(data=intentMessage, outlen=32).digest() | ||
) | ||
return BenfenMessageSignature(signature=signature, address=bfc_address) |
Oops, something went wrong.