Skip to content

Commit dba011b

Browse files
authored
Merge pull request #2302 from AmbireTech/release/v2.92
Release / v2.92.0, v2.92.1 and v2.92.2
2 parents 0b0c120 + 67b120a commit dba011b

7 files changed

Lines changed: 71 additions & 11 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "2.91.3",
2+
"version": "2.92.2",
33
"name": "ambire-common",
44
"description": "Common ground for the Ambire apps",
55
"scripts": {

src/consts/derivation.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,20 @@ export const BIP44_LEDGER_DERIVATION_TEMPLATE = "m/44'/60'/<account>'/0/0"
1919
*/
2020
export const LEGACY_POPULAR_DERIVATION_TEMPLATE = "m/44'/60'/0'/<account>"
2121

22+
/**
23+
* BIP44 for Ethereum test networks (Sepolia, Holesky) as implemented by Trezor.
24+
* Same structure as the standard BIP44 path, but uses the testnet coin_type (1')
25+
* instead of Ethereum mainnet (60'):
26+
* m / purpose' / coin_type' / account' / change / address_index
27+
*/
28+
export const BIP44_STANDARD_TESTNET_DERIVATION_TEMPLATE = "m/44'/1'/0'/0/<account>"
29+
2230
// eslint-disable-next-line @typescript-eslint/naming-convention
2331
export type HD_PATH_TEMPLATE_TYPE =
2432
| typeof BIP44_STANDARD_DERIVATION_TEMPLATE
2533
| typeof BIP44_LEDGER_DERIVATION_TEMPLATE
2634
| typeof LEGACY_POPULAR_DERIVATION_TEMPLATE
35+
| typeof BIP44_STANDARD_TESTNET_DERIVATION_TEMPLATE
2736

2837
export interface DerivationOption {
2938
label: string
@@ -46,6 +55,12 @@ export const DERIVATION_OPTIONS: DerivationOption[] = [
4655
label: 'Ledger Legacy',
4756
value: LEGACY_POPULAR_DERIVATION_TEMPLATE,
4857
description: 'Ledger Legacy: HD path used by MEW / MyCrypto.'
58+
},
59+
{
60+
label: 'Trezor Testnets',
61+
value: BIP44_STANDARD_TESTNET_DERIVATION_TEMPLATE,
62+
description:
63+
"Trezor Testnets: BIP44 path using testnet coin type (1') for Ethereum test networks."
4964
}
5065
]
5166

src/controllers/accountPicker/accountPicker.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -518,8 +518,15 @@ export class AccountPickerController extends EventEmitter implements IAccountPic
518518
this.emitUpdate()
519519
}
520520

521-
async setHDPathTemplate({ hdPathTemplate }: { hdPathTemplate: HD_PATH_TEMPLATE_TYPE }) {
522-
if (this.hdPathTemplate === hdPathTemplate) return
521+
async setHDPathTemplateAndPage({
522+
hdPathTemplate,
523+
page = this.page
524+
}: {
525+
hdPathTemplate: HD_PATH_TEMPLATE_TYPE
526+
page: number
527+
}) {
528+
const arePropsUnchanged = this.hdPathTemplate === hdPathTemplate && page === this.page
529+
if (arePropsUnchanged) return
523530

524531
this.hdPathTemplate = hdPathTemplate
525532
// Reset the currently selected accounts, because for the keys of these
@@ -531,10 +538,10 @@ export class AccountPickerController extends EventEmitter implements IAccountPic
531538
this.emitUpdate()
532539

533540
await this.setPage({
534-
page: DEFAULT_PAGE,
541+
page,
535542
shouldGetAccountsUsedOnNetworks: DEFAULT_SHOULD_GET_ACCOUNTS_USED_ON_NETWORKS,
536543
shouldSearchForLinkedAccounts: DEFAULT_SHOULD_SEARCH_FOR_LINKED_ACCOUNTS
537-
}) // takes the user back on the first page
544+
})
538545
}
539546

540547
#getAccountKeys(account: Account, accountsOnPageWithThisAcc: AccountOnPage[]) {

src/controllers/requests/requests.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1823,7 +1823,11 @@ export class RequestsController extends EventEmitter implements IRequestsControl
18231823
this.sendNewRequestMessage(existingUserRequest, 'queued')
18241824
currentUserRequest = this.currentUserRequest || this.visibleUserRequests[0] || null
18251825
}
1826-
await this.#setCurrentUserRequest(currentUserRequest)
1826+
1827+
// Otherwise we will reset the currentUserRequest when a new request is added to the batch
1828+
if (executionType !== 'queue') {
1829+
await this.#setCurrentUserRequest(currentUserRequest)
1830+
}
18271831
} else {
18281832
const account = this.#accounts.accounts.find((x) => x.addr === meta.accountAddr)!
18291833
const accountStateBefore =

src/controllers/signAccountOp/signAccountOp.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -912,7 +912,7 @@ export class SignAccountOpController extends EventEmitter implements ISignAccoun
912912
if (isV1) {
913913
errors.push({
914914
title:
915-
'Broadcasting Ambire v1 transactions is possible only by using an ЕОА. Import or create one to broadcast your transactions.'
915+
'Broadcasting Ambire v1 transactions is possible only by using an EOA. Import or create one to broadcast your transactions.'
916916
})
917917
} else {
918918
let skippedTokensCount = 0

src/controllers/swapAndBridge/swapAndBridge.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { formatUnits, getAddress, isAddress, parseUnits, ZeroAddress } from 'ethers'
22

3+
/* eslint-disable no-await-in-loop */
4+
import { getAccountNetworks } from '@/libs/networks/networks'
5+
36
import EmittableError from '../../classes/EmittableError'
47
import { RecurringTimeout } from '../../classes/recurringTimeout/recurringTimeout'
58
import SwapAndBridgeError from '../../classes/SwapAndBridgeError'
@@ -16,10 +19,8 @@ import { IPhishingController } from '../../interfaces/phishing'
1619
import { IPortfolioController } from '../../interfaces/portfolio'
1720
import { IProvidersController } from '../../interfaces/provider'
1821
import { ISelectedAccountController } from '../../interfaces/selectedAccount'
19-
/* eslint-disable no-await-in-loop */
2022
import { ISignAccountOpController, SignAccountOpError } from '../../interfaces/signAccountOp'
2123
import { IStorageController } from '../../interfaces/storage'
22-
import { IUiController, View } from '../../interfaces/ui'
2324
import {
2425
CachedSupportedChains,
2526
CachedTokenListKey,
@@ -33,6 +34,7 @@ import {
3334
SwapAndBridgeToToken,
3435
SwapProvider
3536
} from '../../interfaces/swapAndBridge'
37+
import { IUiController, View } from '../../interfaces/ui'
3638
import { CallsUserRequest, UserRequest } from '../../interfaces/userRequest'
3739
import { getBaseAccount } from '../../libs/account/getBaseAccount'
3840
import { AccountOp } from '../../libs/accountOp/accountOp'
@@ -1077,13 +1079,21 @@ export class SwapAndBridgeController extends EventEmitter implements ISwapAndBri
10771079
!isSelectedTokenFalsyBeforeListUpdate &&
10781080
shouldUpdateFromSelectedToken
10791081
) {
1082+
// get the networks that account is supported on and select
1083+
// one from that list, not only the providers lists of networks
1084+
const accNetworks = getAccountNetworks(
1085+
this.#networks.networks,
1086+
this.#accounts.accountStates,
1087+
this.#selectedAccount.account
1088+
).map((n) => n.chainId)
10801089
const nextFromSelectedToken =
10811090
fromSelectedTokenInNextPortfolio ||
10821091
// Select the first token in the portfolio that is not the same as the "to" token
10831092
this.portfolioTokenList.find(
10841093
(t) =>
10851094
t.address !== this.toSelectedToken?.address &&
1086-
this.supportedChainIds.includes(t.chainId)
1095+
this.supportedChainIds.includes(t.chainId) &&
1096+
accNetworks.includes(t.chainId)
10871097
) ||
10881098
null
10891099

src/libs/trezor/trezor.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,27 @@
33
* human-readable messages. Although there is a message incoming from Trezor,
44
* it's not self-explanatory and can be difficult for the end users to understand.
55
*/
6-
export const getMessageFromTrezorErrorCode = (errorCode?: string, errorMsg?: string): string => {
6+
export const getMessageFromTrezorErrorCode = (
7+
errorCode?: string,
8+
errorMsg?: string,
9+
context?: {
10+
isLedgerLiveSmartAccountForbiddenPath?: boolean
11+
isHyperEvmForbiddenPath?: boolean
12+
}
13+
): string => {
714
if (!errorCode && !errorMsg) return 'Could not connect to your Trezor device. Please try again.'
815

16+
if (context?.isHyperEvmForbiddenPath && errorMsg?.toLowerCase()?.includes('forbidden key path')) {
17+
return 'Please set "Safety checks" to "Prompt" in Trezor Suite (Settings - Device) to use your Trezor on HyperEVM chain. This is flagged as non-standard and blocked otherwise.'
18+
}
19+
20+
if (
21+
context?.isLedgerLiveSmartAccountForbiddenPath &&
22+
errorMsg?.toLowerCase()?.includes('forbidden key path')
23+
) {
24+
return 'Please set "Safety checks" to "Prompt" in Trezor Suite (Settings - Device) to use your Trezor (with Ledger Live HD paths) as a key for your Ambire smart account. This is flagged as non-standard and blocked otherwise.'
25+
}
26+
927
if (errorCode === 'Method_Interrupted')
1028
return 'Closing the Trezor popup interrupted the connection.'
1129

@@ -37,3 +55,9 @@ export const normalizeTrezorMessage = (error?: string): string => {
3755

3856
return error
3957
}
58+
59+
// Temporarily, until Trezor makes their error types consistent
60+
export const getTrezorErrorMessageFromPayload = (trezorUnsuccessfulPayload: any): string => {
61+
// Trezor SDK TS promises "error", but Trezor Suite the message comes as "message"
62+
return trezorUnsuccessfulPayload?.error || trezorUnsuccessfulPayload?.message
63+
}

0 commit comments

Comments
 (0)