Skip to content

Commit d58f686

Browse files
authored
fix(core): adaptation related to Polkadot updates (#403)
* fix(core): Bitcoin-only firmware adaptation * fix(core): adaptation related to Polkadot updates * feat(core): add independent switch for USB and BLE * chore: bump version to 4.18.0
1 parent e01716b commit d58f686

File tree

25 files changed

+660
-297
lines changed

25 files changed

+660
-297
lines changed

.github/workflows/build-pro.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ jobs:
2727
bitcoin_only: 1
2828
secret_key_1_name: "SECRET_KEY_1"
2929
secret_key_2_name: "SECRET_KEY_2"
30-
output_dir: prod-bc-only
31-
artifact_suffix: "prod-bc-only"
30+
output_dir: prod-btc-only
31+
artifact_suffix: "prod-btc-only"
3232
- production: 0
3333
bitcoin_only: 0
3434
secret_key_1_name: "SECRET_QA_KEY_1"
@@ -39,8 +39,8 @@ jobs:
3939
bitcoin_only: 1
4040
secret_key_1_name: "SECRET_QA_KEY_1"
4141
secret_key_2_name: "SECRET_QA_KEY_2"
42-
output_dir: qa-bc-only
43-
artifact_suffix: "qa-bc-only"
42+
output_dir: qa-btc-only
43+
artifact_suffix: "qa-btc-only"
4444

4545
steps:
4646
- name: "Checkout"

common/protob/messages-polkadot.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ message PolkadotSignTx {
3636
repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
3737
required bytes raw_tx = 2; // serialized raw transaction
3838
required string network = 3; // Network name
39+
optional uint32 prefix = 4; // SS58 address-type
3940
}
4041

4142
/**

core/embed/firmware/version.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
#define FIX_VERSION_BUILD VERSION_BUILD
1010

1111
#define ONEKEY_VERSION_MAJOR 4
12-
#define ONEKEY_VERSION_MINOR 17
13-
#define ONEKEY_VERSION_PATCH 1
12+
#define ONEKEY_VERSION_MINOR 18
13+
#define ONEKEY_VERSION_PATCH 0
1414
#define ONEKEY_VERSION_BUILD 0
1515

1616
// Minimum SE version required for firmware upgrade

core/src/apps/polkadot/__init__.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,21 @@
33
CURVE = "ed25519-ledger"
44
SLIP44_ID = 354
55
PATTERN = PATTERN_BIP44
6-
PRIMARY_COLOR = 0xE6007A
7-
PRIMARY_COLOR_KSM = 0xFFFFFF
6+
PRIMARY_COLOR = 0x00FF33
7+
PRIMARY_COLOR_KSM = 0x00FF33
88
PRIMARY_COLOR_WESTEND = 0x969696
99
PRIMARY_COLOR_ASTAR = 0x04E2FE
1010
PRIMARY_COLOR_JOY = 0x4038FF
1111
PRIMARY_COLOR_MAMTA = 0x26C8BF
12+
PRIMARY_COLOR_HYDRATION = 0x00FF33
13+
PRIMARY_COLOR_BIFROST = 0x00FF33
14+
PRIMARY_COLOR_BIFROST_KSMC = 0x00FF33
1215
ICON = "A:/res/chain-dot.png"
1316
ICON_KSM = "A:/res/chain-kusama.png"
1417
ICON_WESTEND = "A:/res/chain-westend.png"
1518
ICON_ASTAR = "A:/res/chain-astar.png"
1619
ICON_JOY = "A:/res/chain-joystream.png"
1720
ICON_MANTA = "A:/res/chain-manta.png"
21+
ICON_HYDRATION = "A:/res/chain-hydration.png"
22+
ICON_BIFROST = "A:/res/chain-bifrost.png"
23+
ICON_BIFROST_KSM = "A:/res/chain-bifrost-ksm.png"

core/src/apps/polkadot/helper.py

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,18 @@
77
from . import (
88
ICON,
99
ICON_ASTAR,
10+
ICON_BIFROST,
11+
ICON_BIFROST_KSM,
12+
ICON_HYDRATION,
1013
ICON_JOY,
1114
ICON_KSM,
1215
ICON_MANTA,
1316
ICON_WESTEND,
1417
PRIMARY_COLOR,
1518
PRIMARY_COLOR_ASTAR,
19+
PRIMARY_COLOR_BIFROST,
20+
PRIMARY_COLOR_BIFROST_KSMC,
21+
PRIMARY_COLOR_HYDRATION,
1622
PRIMARY_COLOR_JOY,
1723
PRIMARY_COLOR_KSM,
1824
PRIMARY_COLOR_MAMTA,
@@ -30,6 +36,9 @@
3036
["astar", 5],
3137
["joystream", 126],
3238
["manta", 77],
39+
["hydration", 0],
40+
["bifrost", 0],
41+
["bifrost-ksm", 0],
3342
]
3443

3544
COIN_AMOUNT_DECIMAL_PLACES = 10
@@ -41,6 +50,8 @@
4150
ASTAR_COIN_TICKER = "ASTR"
4251
JOY_COIN_TICKER = "JOY"
4352
MANTA_COIN_TICKER = "MANTA"
53+
HYDRATION_COIN_TICKER = "HDX"
54+
BIFROST_COIN_TICKER = "BNC"
4455

4556

4657
def ss58_encode(address: bytes, ss58_format: int = 42) -> str:
@@ -118,6 +129,30 @@ def retrieval_chain_res(ctx: Context, network: str) -> tuple[str, str, int]:
118129
chain_name = "Manta"
119130
symbol = MANTA_COIN_TICKER
120131
decimal = COIN_AMOUNT_DECIMAL_PLACES_18
132+
elif network == "hydration":
133+
ctx.primary_color, ctx.icon_path = (
134+
lv.color_hex(PRIMARY_COLOR_HYDRATION),
135+
ICON_HYDRATION,
136+
)
137+
chain_name = "Hydration"
138+
symbol = HYDRATION_COIN_TICKER
139+
decimal = COIN_AMOUNT_DECIMAL_PLACES_12
140+
elif network == "bifrost":
141+
ctx.primary_color, ctx.icon_path = (
142+
lv.color_hex(PRIMARY_COLOR_BIFROST),
143+
ICON_BIFROST,
144+
)
145+
chain_name = "Bifrost"
146+
symbol = BIFROST_COIN_TICKER
147+
decimal = COIN_AMOUNT_DECIMAL_PLACES_12
148+
elif network == "bifrost-ksm":
149+
ctx.primary_color, ctx.icon_path = (
150+
lv.color_hex(PRIMARY_COLOR_BIFROST_KSMC),
151+
ICON_BIFROST_KSM,
152+
)
153+
chain_name = "Bifrost-KSM"
154+
symbol = BIFROST_COIN_TICKER
155+
decimal = COIN_AMOUNT_DECIMAL_PLACES_12
121156
else:
122157
ctx.primary_color, ctx.icon_path = lv.color_hex(PRIMARY_COLOR), ICON
123158
chain_name = "UNKN Chain"
@@ -126,10 +161,10 @@ def retrieval_chain_res(ctx: Context, network: str) -> tuple[str, str, int]:
126161
return chain_name, symbol, decimal
127162

128163

129-
def get_address_type(network: str) -> int:
130-
address_type = 42
164+
def get_address_type(network: str, preset_prefix: int | None = None) -> int:
165+
address_type = preset_prefix if preset_prefix is not None else 42
131166
for element in POLKADOT_ADDRESS_TYPES:
132167
if network == element[0]:
133168
address_type = element[1]
134-
169+
break
135170
return address_type

core/src/apps/polkadot/sign_tx.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ async def sign_tx(
1919
public_key = node.public_key()[1:]
2020
else:
2121
public_key = ed25519.publickey(node.private_key())
22-
address_type = helper.get_address_type(msg.network)
22+
address_type = helper.get_address_type(msg.network, msg.prefix)
2323
address = helper.ss58_encode(public_key, address_type)
2424
chain_name, symbol, decimal = helper.retrieval_chain_res(ctx, msg.network)
2525
tx = transaction.Transaction.deserialize(msg.raw_tx, msg.network)

core/src/apps/polkadot/transaction.py

Lines changed: 95 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,26 @@ async def layout(
2323
return None
2424

2525
@staticmethod
26-
def _readAccountIdLookupOfT_V15(rawtx: codec.base.ScaleBytes, address_type) -> str:
27-
value = rawtx.get_next_bytes(1)[0]
28-
if value == 0: # Id
26+
def _readAccountIdLookupOfT_V15(
27+
rawtx: codec.base.ScaleBytes, address_type, skip_type_lookup: bool = False
28+
) -> str:
29+
if not skip_type_lookup:
30+
value = rawtx.get_next_bytes(1)[0]
31+
else:
32+
value = 0
33+
if value == 0:
2934
accountid = helper.ss58_encode(rawtx.get_next_bytes(32), address_type)
30-
elif value == 1: # Index
35+
elif value == 1:
3136
obj = codec.types.Compact(rawtx)
3237
accountid = str(obj.decode(check_remaining=False))
33-
elif value == 2: # Raw
38+
elif value == 2:
3439
obj = codec.types.Compact(rawtx)
3540
value = obj.decode(check_remaining=False)
3641
clen = int(0 if value is None else value)
3742
accountid = hexlify(rawtx.get_next_bytes(clen)).decode()
38-
elif value == 3: # Address32
43+
elif value == 3:
3944
accountid = hexlify(rawtx.get_next_bytes(32)).decode()
40-
elif value == 4: # Address20
45+
elif value == 4:
4146
accountid = hexlify(rawtx.get_next_bytes(20)).decode()
4247
else:
4348
raise Exception("Unexpected value")
@@ -49,23 +54,23 @@ def deserialize_polkadot(
4954
rawtx: codec.base.ScaleBytes, callPrivIdx: int
5055
) -> "Transaction":
5156
tx = TransactionUnknown(rawtx)
52-
if callPrivIdx in (1287, 1280):
57+
if callPrivIdx in (1287, 1280, 2560):
5358
desc = Transaction._readAccountIdLookupOfT_V15(rawtx, 0)
5459
obj = codec.types.Compact(rawtx)
5560
balance = obj.decode(check_remaining=False)
5661
tx = BalancesTransfer(desc, balance)
57-
elif callPrivIdx == 1282:
62+
elif callPrivIdx in (1282, 2562):
5863
source = Transaction._readAccountIdLookupOfT_V15(rawtx, 0)
5964
dest = Transaction._readAccountIdLookupOfT_V15(rawtx, 0)
6065
obj = codec.types.Compact(rawtx)
6166
balance = obj.decode(check_remaining=False)
6267
tx = BalancesForceTransfer(source, dest, balance)
63-
elif callPrivIdx == 1283:
68+
elif callPrivIdx in (1283, 2563):
6469
desc = Transaction._readAccountIdLookupOfT_V15(rawtx, 0)
6570
obj = codec.types.Compact(rawtx)
6671
balance = obj.decode(check_remaining=False)
6772
tx = BalancesTransferKeepAlive(desc, balance)
68-
elif callPrivIdx == 1284:
73+
elif callPrivIdx in (1284, 2564):
6974
desc = Transaction._readAccountIdLookupOfT_V15(rawtx, 0)
7075
keep_alive = rawtx.get_next_bytes(1)[0]
7176
tx = BalancesTransferAll(desc, keep_alive)
@@ -77,23 +82,23 @@ def deserialize_kusama(
7782
rawtx: codec.base.ScaleBytes, callPrivIdx: int
7883
) -> "Transaction":
7984
tx = TransactionUnknown(rawtx)
80-
if callPrivIdx in (1031, 1024):
85+
if callPrivIdx in (1031, 1024, 2560):
8186
desc = Transaction._readAccountIdLookupOfT_V15(rawtx, 2)
8287
obj = codec.types.Compact(rawtx)
8388
balance = obj.decode(check_remaining=False)
8489
tx = BalancesTransfer(desc, balance)
85-
elif callPrivIdx == 1026:
90+
elif callPrivIdx in (1026, 2562):
8691
source = Transaction._readAccountIdLookupOfT_V15(rawtx, 2)
8792
dest = Transaction._readAccountIdLookupOfT_V15(rawtx, 2)
8893
obj = codec.types.Compact(rawtx)
8994
balance = obj.decode(check_remaining=False)
9095
tx = BalancesForceTransfer(source, dest, balance)
91-
elif callPrivIdx == 1027:
96+
elif callPrivIdx in (1027, 2563):
9297
desc = Transaction._readAccountIdLookupOfT_V15(rawtx, 2)
9398
obj = codec.types.Compact(rawtx)
9499
balance = obj.decode(check_remaining=False)
95100
tx = BalancesTransferKeepAlive(desc, balance)
96-
elif callPrivIdx == 1028:
101+
elif callPrivIdx in (1028, 2564):
97102
desc = Transaction._readAccountIdLookupOfT_V15(rawtx, 2)
98103
keep_alive = rawtx.get_next_bytes(1)[0]
99104
tx = BalancesTransferAll(desc, keep_alive)
@@ -162,47 +167,101 @@ def deserialize_joy(
162167
) -> "Transaction":
163168
tx = TransactionUnknown(rawtx)
164169
if callPrivIdx == 1280:
165-
dest = helper.ss58_encode(rawtx.get_next_bytes(32), 126)
170+
dest = Transaction._readAccountIdLookupOfT_V15(
171+
rawtx, 126, skip_type_lookup=True
172+
)
166173
obj = codec.types.Compact(rawtx)
167174
balance = obj.decode(check_remaining=False)
168175
tx = BalancesTransfer(dest, balance)
176+
elif callPrivIdx == 1282:
177+
source = Transaction._readAccountIdLookupOfT_V15(
178+
rawtx, 126, skip_type_lookup=True
179+
)
180+
dest = Transaction._readAccountIdLookupOfT_V15(
181+
rawtx, 126, skip_type_lookup=True
182+
)
183+
obj = codec.types.Compact(rawtx)
184+
balance = obj.decode(check_remaining=False)
185+
tx = BalancesForceTransfer(source, dest, balance)
169186
elif callPrivIdx == 1283:
170-
dest = helper.ss58_encode(rawtx.get_next_bytes(32), 126)
187+
dest = Transaction._readAccountIdLookupOfT_V15(
188+
rawtx, 126, skip_type_lookup=True
189+
)
171190
obj = codec.types.Compact(rawtx)
172191
balance = obj.decode(check_remaining=False)
173192
tx = BalancesTransferKeepAlive(dest, balance)
174193
elif callPrivIdx == 1284:
175-
dest = helper.ss58_encode(rawtx.get_next_bytes(32), 126)
194+
dest = Transaction._readAccountIdLookupOfT_V15(
195+
rawtx, 126, skip_type_lookup=True
196+
)
176197
keep_alive = rawtx.get_next_bytes(1)[0]
177198
tx = BalancesTransferAll(dest, keep_alive)
178199

179200
return tx
180201

181202
@staticmethod
182203
def deserialize_manta(
183-
rawtx: codec.base.ScaleBytes, callPrivIdx: int
204+
rawtx: codec.base.ScaleBytes, callPrivIdx: int, address_type: int
184205
) -> "Transaction":
185206
tx = TransactionUnknown(rawtx)
186207
if callPrivIdx == 2560:
187-
desc = Transaction._readAccountIdLookupOfT_V15(rawtx, 77)
208+
desc = Transaction._readAccountIdLookupOfT_V15(rawtx, address_type)
188209
obj = codec.types.Compact(rawtx)
189210
balance = obj.decode(check_remaining=False)
190211
tx = BalancesTransfer(desc, balance)
212+
elif callPrivIdx == 2562:
213+
source = Transaction._readAccountIdLookupOfT_V15(rawtx, address_type)
214+
dest = Transaction._readAccountIdLookupOfT_V15(rawtx, address_type)
215+
obj = codec.types.Compact(rawtx)
216+
balance = obj.decode(check_remaining=False)
217+
tx = BalancesForceTransfer(source, dest, balance)
191218
elif callPrivIdx == 2563:
192-
desc = Transaction._readAccountIdLookupOfT_V15(rawtx, 77)
219+
desc = Transaction._readAccountIdLookupOfT_V15(rawtx, address_type)
193220
obj = codec.types.Compact(rawtx)
194221
balance = obj.decode(check_remaining=False)
195222
tx = BalancesTransferKeepAlive(desc, balance)
196223
elif callPrivIdx == 2564:
197-
desc = Transaction._readAccountIdLookupOfT_V15(rawtx, 77)
224+
desc = Transaction._readAccountIdLookupOfT_V15(rawtx, address_type)
198225
keep_alive = rawtx.get_next_bytes(1)[0]
199226
tx = BalancesTransferAll(desc, keep_alive)
200-
elif callPrivIdx == 2562:
201-
source = Transaction._readAccountIdLookupOfT_V15(rawtx, 77)
202-
dest = Transaction._readAccountIdLookupOfT_V15(rawtx, 77)
227+
228+
return tx
229+
230+
@staticmethod
231+
def deserialize_hydration(
232+
rawtx: codec.base.ScaleBytes, callPrivIdx: int
233+
) -> "Transaction":
234+
tx = TransactionUnknown(rawtx)
235+
if callPrivIdx == 1792:
236+
desc = Transaction._readAccountIdLookupOfT_V15(
237+
rawtx, 0, skip_type_lookup=True
238+
)
239+
obj = codec.types.Compact(rawtx)
240+
balance = obj.decode(check_remaining=False)
241+
tx = BalancesTransfer(desc, balance)
242+
elif callPrivIdx == 1794:
243+
source = Transaction._readAccountIdLookupOfT_V15(
244+
rawtx, 0, skip_type_lookup=True
245+
)
246+
dest = Transaction._readAccountIdLookupOfT_V15(
247+
rawtx, 0, skip_type_lookup=True
248+
)
203249
obj = codec.types.Compact(rawtx)
204250
balance = obj.decode(check_remaining=False)
205251
tx = BalancesForceTransfer(source, dest, balance)
252+
elif callPrivIdx == 1795:
253+
desc = Transaction._readAccountIdLookupOfT_V15(
254+
rawtx, 0, skip_type_lookup=True
255+
)
256+
obj = codec.types.Compact(rawtx)
257+
balance = obj.decode(check_remaining=False)
258+
tx = BalancesTransferKeepAlive(desc, balance)
259+
elif callPrivIdx == 1796:
260+
desc = Transaction._readAccountIdLookupOfT_V15(
261+
rawtx, 0, skip_type_lookup=True
262+
)
263+
keep_alive = rawtx.get_next_bytes(1)[0]
264+
tx = BalancesTransferAll(desc, keep_alive)
206265

207266
return tx
208267

@@ -224,8 +283,14 @@ def deserialize(raw_tx: bytes, network: str) -> "Transaction":
224283
tx = Transaction.deserialize_astar(rawtx, callPrivIdx)
225284
elif network == "joystream":
226285
tx = Transaction.deserialize_joy(rawtx, callPrivIdx)
227-
elif network == "manta":
228-
tx = Transaction.deserialize_manta(rawtx, callPrivIdx)
286+
elif network in ("manta", "bifrost", "bifrost-ksm"):
287+
if network == "manta":
288+
address_type = 77
289+
else:
290+
address_type = 0
291+
tx = Transaction.deserialize_manta(rawtx, callPrivIdx, address_type)
292+
elif network == "hydration":
293+
tx = Transaction.deserialize_hydration(rawtx, callPrivIdx)
229294
else:
230295
tx = TransactionUnknown(rawtx)
231296

@@ -248,6 +313,9 @@ def deserialize(raw_tx: bytes, network: str) -> "Transaction":
248313
tip = obj.decode(check_remaining=False)
249314
tx.tip = tip if tip is not None else 0
250315

316+
# optional: assetId(asset location if assetId is not equal to 0)
317+
# optional: mode
318+
251319
return tx
252320

253321

0 commit comments

Comments
 (0)