@@ -299,6 +299,17 @@ pub async fn process(request: &Transaction<'_>) -> Result<Response, Error> {
299
299
}
300
300
super :: keypath:: warn_unusual_keypath ( & params, params. name , request. keypath ( ) ) . await ?;
301
301
302
+ // Show chain confirmation only for known non-mainnet networks
303
+ if super :: params:: is_known_non_mainnet ( params. chain_id ) {
304
+ confirm:: confirm ( & confirm:: Params {
305
+ title : "Confirm Chain" ,
306
+ body : & format ! ( "Sign transaction on\n {}" , params. name) ,
307
+ accept_is_nextarrow : true ,
308
+ ..Default :: default ( )
309
+ } )
310
+ . await ?;
311
+ }
312
+
302
313
// Size limits.
303
314
if request. nonce ( ) . len ( ) > 16
304
315
|| request. gas_limit ( ) . len ( ) > 16
@@ -647,6 +658,11 @@ mod tests {
647
658
assert_eq ! ( params. body, "Warning: unusual keypath m/44'/60'/0'/0/0. Proceed only if you know what you are doing." ) ;
648
659
true
649
660
}
661
+ 2 => {
662
+ assert_eq ! ( params. title, "Confirm Chain" ) ;
663
+ assert_eq ! ( params. body, "Sign transaction on\n Sepolia" ) ;
664
+ true
665
+ }
650
666
_ => panic ! ( "too many user confirmations" ) ,
651
667
}
652
668
} ) ) ,
@@ -681,7 +697,7 @@ mod tests {
681
697
address_case : pb:: EthAddressCase :: Mixed as _ ,
682
698
} ) ) )
683
699
. unwrap ( ) ;
684
- assert_eq ! ( unsafe { CONFIRM_COUNTER } , 1 ) ;
700
+ assert_eq ! ( unsafe { CONFIRM_COUNTER } , 2 ) ;
685
701
}
686
702
687
703
/// Standard ETH transaction with an unknown data field.
@@ -1175,4 +1191,171 @@ mod tests {
1175
1191
) ;
1176
1192
assert_eq ! ( unsafe { CONFIRM_COUNTER } , 4 ) ;
1177
1193
}
1194
+
1195
+ /// Test that the chain confirmation screen appears for known non-mainnet networks.
1196
+ #[ test]
1197
+ pub fn test_chain_confirmation_for_l2_networks ( ) {
1198
+ const KEYPATH : & [ u32 ] = & [ 44 + HARDENED , 60 + HARDENED , 0 + HARDENED , 0 , 0 ] ;
1199
+ static mut CONFIRM_COUNTER : u32 = 0 ;
1200
+ // Test with Arbitrum (chain_id 42161)
1201
+ mock ( Data {
1202
+ ui_confirm_create : Some ( Box :: new ( |params| {
1203
+ unsafe {
1204
+ if CONFIRM_COUNTER == 0 {
1205
+ assert_eq ! ( params. title, "Confirm Chain" ) ;
1206
+ assert_eq ! ( params. body, "Sign transaction on\n Arbitrum One" ) ;
1207
+ CONFIRM_COUNTER += 1 ;
1208
+ }
1209
+ }
1210
+ true
1211
+ } ) ) ,
1212
+ // Skip checking these details
1213
+ ui_transaction_address_create : Some ( Box :: new ( |_, _| true ) ) ,
1214
+ ui_transaction_fee_create : Some ( Box :: new ( |_, _, _| true ) ) ,
1215
+ ..Default :: default ( )
1216
+ } ) ;
1217
+ mock_unlocked ( ) ;
1218
+
1219
+ block_on ( process ( & Transaction :: Legacy ( & pb:: EthSignRequest {
1220
+ coin : pb:: EthCoin :: Eth as _ ,
1221
+ keypath : KEYPATH . to_vec ( ) ,
1222
+ nonce : b"\x1f \xdc " . to_vec ( ) ,
1223
+ gas_price : b"\x01 \x65 \xa0 \xbc \x00 " . to_vec ( ) ,
1224
+ gas_limit : b"\x52 \x08 " . to_vec ( ) ,
1225
+ recipient :
1226
+ b"\x04 \xf2 \x64 \xcf \x34 \x44 \x03 \x13 \xb4 \xa0 \x19 \x2a \x35 \x28 \x14 \xfb \xe9 \x27 \xb8 \x85 "
1227
+ . to_vec ( ) ,
1228
+ value : b"\x07 \x5c \xf1 \x25 \x9e \x9c \x40 \x00 " . to_vec ( ) ,
1229
+ data : b"" . to_vec ( ) ,
1230
+ host_nonce_commitment : None ,
1231
+ chain_id : 42161 ,
1232
+ address_case : pb:: EthAddressCase :: Mixed as _ ,
1233
+ } ) ) )
1234
+ . unwrap ( ) ;
1235
+ assert_eq ! ( unsafe { CONFIRM_COUNTER } , 1 ) ;
1236
+ }
1237
+
1238
+ /// Test that EIP-1559 transactions also get the chain confirmation screen for L2 networks
1239
+ #[ test]
1240
+ pub fn test_chain_confirmation_for_eip1559 ( ) {
1241
+ const KEYPATH : & [ u32 ] = & [ 44 + HARDENED , 60 + HARDENED , 0 + HARDENED , 0 , 0 ] ;
1242
+ static mut CONFIRM_COUNTER : u32 = 0 ;
1243
+
1244
+ // Test with Polygon network (chain_id 137)
1245
+ mock ( Data {
1246
+ ui_confirm_create : Some ( Box :: new ( |params| {
1247
+ unsafe {
1248
+ if CONFIRM_COUNTER == 0 {
1249
+ assert_eq ! ( params. title, "Confirm Chain" ) ;
1250
+ assert_eq ! ( params. body, "Sign transaction on\n Polygon" ) ;
1251
+ CONFIRM_COUNTER += 1 ;
1252
+ }
1253
+ }
1254
+ true
1255
+ } ) ) ,
1256
+ ui_transaction_address_create : Some ( Box :: new ( |_, _| true ) ) ,
1257
+ ui_transaction_fee_create : Some ( Box :: new ( |_, _, _| true ) ) ,
1258
+ ..Default :: default ( )
1259
+ } ) ;
1260
+ mock_unlocked ( ) ;
1261
+
1262
+ block_on ( process ( & Transaction :: Eip1559 ( & pb:: EthSignEip1559Request {
1263
+ keypath : KEYPATH . to_vec ( ) ,
1264
+ nonce : b"\x1f \xdc " . to_vec ( ) ,
1265
+ max_priority_fee_per_gas : b"\x3b \x9a \xca \x00 " . to_vec ( ) ,
1266
+ max_fee_per_gas : b"\x01 \x65 \xa0 \xbc \x00 " . to_vec ( ) ,
1267
+ gas_limit : b"\x52 \x08 " . to_vec ( ) ,
1268
+ recipient :
1269
+ b"\x04 \xf2 \x64 \xcf \x34 \x44 \x03 \x13 \xb4 \xa0 \x19 \x2a \x35 \x28 \x14 \xfb \xe9 \x27 \xb8 \x85 "
1270
+ . to_vec ( ) ,
1271
+ value : b"\x07 \x5c \xf1 \x25 \x9e \x9c \x40 \x00 " . to_vec ( ) ,
1272
+ data : b"" . to_vec ( ) ,
1273
+ host_nonce_commitment : None ,
1274
+ chain_id : 137 ,
1275
+ address_case : pb:: EthAddressCase :: Mixed as _ ,
1276
+ } ) ) )
1277
+ . unwrap ( ) ;
1278
+ assert_eq ! ( unsafe { CONFIRM_COUNTER } , 1 ) ;
1279
+ }
1280
+
1281
+ /// Test that unknown networks and mainnet do NOT get the chain confirmation screen
1282
+ #[ test]
1283
+ pub fn test_no_chain_confirmation_for_unknown_networks ( ) {
1284
+ const KEYPATH : & [ u32 ] = & [ 44 + HARDENED , 60 + HARDENED , 0 + HARDENED , 0 , 0 ] ;
1285
+ static mut CONFIRM_COUNTER : u32 = 0 ;
1286
+
1287
+ // Test with an unknown network (chain_id 999999)
1288
+ mock ( Data {
1289
+ ui_confirm_create : Some ( Box :: new ( |params| {
1290
+ unsafe {
1291
+ // Only the warning confirmations should appear, not chain confirmation
1292
+ if params. title == "Confirm Chain" {
1293
+ CONFIRM_COUNTER += 1 ;
1294
+ }
1295
+ }
1296
+ true
1297
+ } ) ) ,
1298
+ ui_transaction_address_create : Some ( Box :: new ( |_, _| true ) ) ,
1299
+ ui_transaction_fee_create : Some ( Box :: new ( |_, _, _| true ) ) ,
1300
+ ..Default :: default ( )
1301
+ } ) ;
1302
+ mock_unlocked ( ) ;
1303
+
1304
+ block_on ( process ( & Transaction :: Legacy ( & pb:: EthSignRequest {
1305
+ coin : pb:: EthCoin :: Eth as _ ,
1306
+ keypath : KEYPATH . to_vec ( ) ,
1307
+ nonce : b"\x1f \xdc " . to_vec ( ) ,
1308
+ gas_price : b"\x01 \x65 \xa0 \xbc \x00 " . to_vec ( ) ,
1309
+ gas_limit : b"\x52 \x08 " . to_vec ( ) ,
1310
+ recipient :
1311
+ b"\x04 \xf2 \x64 \xcf \x34 \x44 \x03 \x13 \xb4 \xa0 \x19 \x2a \x35 \x28 \x14 \xfb \xe9 \x27 \xb8 \x85 "
1312
+ . to_vec ( ) ,
1313
+ value : b"\x07 \x5c \xf1 \x25 \x9e \x9c \x40 \x00 " . to_vec ( ) ,
1314
+ data : b"" . to_vec ( ) ,
1315
+ host_nonce_commitment : None ,
1316
+ chain_id : 999999 ,
1317
+ address_case : pb:: EthAddressCase :: Mixed as _ ,
1318
+ } ) ) )
1319
+ . unwrap ( ) ;
1320
+
1321
+ assert_eq ! ( unsafe { CONFIRM_COUNTER } , 0 ) ;
1322
+
1323
+ // Reset counter for mainnet test
1324
+ unsafe { CONFIRM_COUNTER = 0 } ;
1325
+
1326
+ // Test with Ethereum mainnet (chain_id 1)
1327
+ mock ( Data {
1328
+ ui_confirm_create : Some ( Box :: new ( |params| {
1329
+ unsafe {
1330
+ if params. title == "Confirm Chain" {
1331
+ CONFIRM_COUNTER += 1 ;
1332
+ }
1333
+ }
1334
+ true
1335
+ } ) ) ,
1336
+ ui_transaction_address_create : Some ( Box :: new ( |_, _| true ) ) ,
1337
+ ui_transaction_fee_create : Some ( Box :: new ( |_, _, _| true ) ) ,
1338
+ ..Default :: default ( )
1339
+ } ) ;
1340
+ mock_unlocked ( ) ;
1341
+
1342
+ block_on ( process ( & Transaction :: Legacy ( & pb:: EthSignRequest {
1343
+ coin : pb:: EthCoin :: Eth as _ ,
1344
+ keypath : KEYPATH . to_vec ( ) ,
1345
+ nonce : b"\x1f \xdc " . to_vec ( ) ,
1346
+ gas_price : b"\x01 \x65 \xa0 \xbc \x00 " . to_vec ( ) ,
1347
+ gas_limit : b"\x52 \x08 " . to_vec ( ) ,
1348
+ recipient :
1349
+ b"\x04 \xf2 \x64 \xcf \x34 \x44 \x03 \x13 \xb4 \xa0 \x19 \x2a \x35 \x28 \x14 \xfb \xe9 \x27 \xb8 \x85 "
1350
+ . to_vec ( ) ,
1351
+ value : b"\x07 \x5c \xf1 \x25 \x9e \x9c \x40 \x00 " . to_vec ( ) ,
1352
+ data : b"" . to_vec ( ) ,
1353
+ host_nonce_commitment : None ,
1354
+ chain_id : 1 ,
1355
+ address_case : pb:: EthAddressCase :: Mixed as _ ,
1356
+ } ) ) )
1357
+ . unwrap ( ) ;
1358
+
1359
+ assert_eq ! ( unsafe { CONFIRM_COUNTER } , 0 ) ;
1360
+ }
1178
1361
}
0 commit comments