Skip to content

Commit 38275a5

Browse files
committed
fix
1 parent 442c8a9 commit 38275a5

File tree

11 files changed

+311
-186
lines changed

11 files changed

+311
-186
lines changed

packages/core-mobile/app/services/earn/EarnService.ts

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import AnalyticsService from 'services/analytics/AnalyticsService'
2929
import { TokenUnit } from '@avalabs/core-utils-sdk'
3030
import { Avalanche } from '@avalabs/core-wallets-sdk'
3131
import { AvaxXP } from 'types/AvaxXP'
32-
import { NetworkVMType } from '@avalabs/core-chains-sdk'
3332
import {
3433
getTransformedTransactions,
3534
maxGetAtomicUTXOsRetries,
@@ -366,35 +365,47 @@ class EarnService {
366365
| undefined
367366
> => {
368367
try {
369-
const currentNetworkAddresses = await WalletService.getXPAddresses({
370-
accounts,
371-
walletId,
372-
walletType,
373-
isTestnet,
374-
networkType: NetworkVMType.PVM,
375-
onlyWithActivity: true
376-
})
368+
const currentNetworkAddressesPromises = accounts.map(account =>
369+
WalletService.getXPExternalAddresses({
370+
account,
371+
walletId,
372+
walletType,
373+
isTestnet
374+
})
375+
)
376+
const currentNetworkAddresses = await Promise.all(
377+
currentNetworkAddressesPromises
378+
)
379+
const currentNetworkAddressesArray = currentNetworkAddresses
380+
.flat()
381+
.map(address => address.address)
377382
const currentNetworkTransactions =
378-
currentNetworkAddresses.length > 0
383+
currentNetworkAddressesArray.length > 0
379384
? await getTransformedTransactions(
380-
currentNetworkAddresses,
385+
currentNetworkAddressesArray,
381386
isTestnet,
382387
startTimestamp
383388
)
384389
: []
385390

386-
const oppositeNetworkAddresses = await WalletService.getXPAddresses({
387-
accounts,
388-
walletId,
389-
walletType,
390-
isTestnet: !isTestnet,
391-
networkType: NetworkVMType.PVM,
392-
onlyWithActivity: true
393-
})
391+
const oppositeNetworkAddressesPromises = accounts.map(account =>
392+
WalletService.getXPExternalAddresses({
393+
account,
394+
walletId,
395+
walletType,
396+
isTestnet: !isTestnet
397+
})
398+
)
399+
const oppositeNetworkAddresses = await Promise.all(
400+
oppositeNetworkAddressesPromises
401+
)
402+
const oppositeNetworkAddressesArray = oppositeNetworkAddresses
403+
.flat()
404+
.map(address => address.address)
394405
const oppositeNetworkTransactions =
395-
oppositeNetworkAddresses.length > 0
406+
oppositeNetworkAddressesArray.length > 0
396407
? await getTransformedTransactions(
397-
oppositeNetworkAddresses,
408+
oppositeNetworkAddressesArray,
398409
!isTestnet,
399410
startTimestamp
400411
)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { NetworkVMType } from '@avalabs/vm-module-types'
2+
import Config from 'react-native-config'
3+
import { NetworkAddresses } from 'services/wallet/types'
4+
import fetchWithAppCheck from 'utils/httpClient'
5+
import Logger from 'utils/Logger'
6+
7+
if (!Config.CORE_PROFILE_URL) {
8+
Logger.warn(
9+
'CORE_PROFILE_URL is missing. Profile service may not work properly.'
10+
)
11+
}
12+
13+
class ProfileService {
14+
public async fetchXPAddresses({
15+
xpubXP,
16+
networkType,
17+
isTestnet = false,
18+
onlyWithActivity
19+
}: {
20+
xpubXP: string
21+
networkType: NetworkVMType.AVM | NetworkVMType.PVM
22+
isTestnet: boolean
23+
onlyWithActivity: boolean
24+
}): Promise<NetworkAddresses> {
25+
try {
26+
const res = await fetchWithAppCheck(
27+
`${Config.CORE_PROFILE_URL}/v1/get-addresses`,
28+
JSON.stringify({
29+
networkType: networkType,
30+
extendedPublicKey: xpubXP,
31+
isTestnet,
32+
onlyWithActivity
33+
})
34+
)
35+
36+
if (!res.ok) {
37+
throw new Error(`${res.status}:${res.statusText}`)
38+
}
39+
40+
return res.json()
41+
} catch (err) {
42+
Logger.error(`[ProfileService][fetchXPAddresses]${err}`)
43+
throw err
44+
}
45+
}
46+
}
47+
48+
export default new ProfileService()

packages/core-mobile/app/services/wallet/WalletService.tsx

Lines changed: 28 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import Config from 'react-native-config'
21
import {
32
Avalanche,
43
BitcoinProvider,
@@ -12,7 +11,6 @@ import {
1211
CreateImportCTxParams,
1312
CreateImportPTxParams,
1413
CreateSendPTxParams,
15-
NetworkAddresses,
1614
PubKeyType,
1715
SignTransactionRequest,
1816
Wallet,
@@ -37,15 +35,21 @@ import {
3735
import { UTCDate } from '@date-fns/utc'
3836
import { nanoToWei } from 'utils/units/converter'
3937
import { SpanName } from 'services/sentry/types'
40-
import { AVALANCHE_DERIVATION_PATH_PREFIX, Curve } from 'utils/publicKeys'
41-
import fetchWithAppCheck from 'utils/httpClient'
38+
import {
39+
AVALANCHE_DERIVATION_PATH_PREFIX,
40+
Curve,
41+
getXPAddressIndexFromDerivationPath
42+
} from 'utils/publicKeys'
4243
import {
4344
AVALANCHE_MAINNET_NETWORK,
4445
AVALANCHE_TESTNET_NETWORK
4546
} from 'services/network/consts'
4647
import ModuleManager from 'vmModule/ModuleManager'
4748
import { Network as VmNetwork } from '@avalabs/vm-module-types'
4849
import { SeedlessPubKeysStorage } from 'seedless/services/storage/SeedlessPubKeysStorage'
50+
import { getAddressesFromXpubXP } from 'utils/getAddressesFromXpubXP'
51+
import { xpAddressWithoutPrefix } from 'common/utils/xpAddressWIthoutPrefix'
52+
import { AddressIndex } from '@avalabs/types'
4953
import {
5054
getAddressDerivationPath,
5155
getAssetId,
@@ -280,49 +284,6 @@ class WalletService {
280284
return wallet.getRawXpubXP(accountIndex)
281285
}
282286

283-
public async getAddressesFromXpubXP({
284-
walletId,
285-
walletType,
286-
accountIndex,
287-
networkType,
288-
isTestnet = false,
289-
onlyWithActivity
290-
}: {
291-
walletId: string
292-
walletType: WalletType
293-
accountIndex: number
294-
networkType: NetworkVMType.AVM | NetworkVMType.PVM
295-
isTestnet: boolean
296-
onlyWithActivity: boolean
297-
}): Promise<NetworkAddresses> {
298-
const xpubXP = await this.getRawXpubXP({
299-
walletId,
300-
walletType,
301-
accountIndex
302-
})
303-
304-
try {
305-
const res = await fetchWithAppCheck(
306-
`${Config.CORE_PROFILE_URL}/v1/get-addresses`,
307-
JSON.stringify({
308-
networkType: networkType,
309-
extendedPublicKey: xpubXP,
310-
isTestnet,
311-
onlyWithActivity
312-
})
313-
)
314-
315-
if (!res.ok) {
316-
throw new Error(`${res.status}:${res.statusText}`)
317-
}
318-
319-
return res.json()
320-
} catch (err) {
321-
Logger.error(`[WalletService.ts][getAddressesFromXpubXP]${err}`)
322-
throw err
323-
}
324-
}
325-
326287
/**
327288
* Get atomic transactions that are in VM memory.
328289
*/
@@ -968,58 +929,39 @@ class WalletService {
968929
* - **Seedless wallets**: Retrieves addresses from stored public keys
969930
* - **Other wallet types**: Returns an empty array
970931
*
971-
* @param accounts - Array of accounts to get addresses for
932+
* @param account - account to get addresses for
972933
* @param walletId - Unique identifier of the wallet
973934
* @param walletType - Type of wallet (Mnemonic, Keystone, Ledger, Seedless, etc.)
974935
* @param isTestnet - Whether to use testnet or mainnet
975-
* @param networkType - Chain type: NetworkVMType.AVM for X-Chain or NetworkVMType.PVM for P-Chain
976-
* @param onlyWithActivity - If true, only return addresses that have been used (xpub wallets only)
977936
*
978937
* @returns Promise resolving to an array of addresses (e.g., ["avax1...", "avax2..."])
979938
*/
980-
async getXPAddresses({
981-
accounts,
939+
async getXPExternalAddresses({
982940
walletId,
983941
walletType,
984-
isTestnet,
985-
networkType,
986-
onlyWithActivity
942+
account,
943+
isTestnet
987944
}: {
988-
accounts: Account[]
945+
account: Account
989946
walletId: string
990947
walletType: WalletType
991948
isTestnet: boolean
992-
networkType: NetworkVMType.AVM | NetworkVMType.PVM
993-
onlyWithActivity: boolean
994-
}): Promise<string[]> {
949+
}): Promise<AddressIndex[]> {
995950
if (this.hasXpub(walletType)) {
996-
const promises = accounts
997-
.map(account => account.index)
998-
.map(accountIndex =>
999-
this.getAddressesFromXpubXP({
1000-
walletId,
1001-
walletType,
1002-
networkType,
1003-
isTestnet,
1004-
accountIndex,
1005-
onlyWithActivity
1006-
})
1007-
)
1008-
1009-
const networkAddresses = await Promise.all(promises)
1010-
return networkAddresses
1011-
.map(address => address.externalAddresses)
1012-
.flat()
1013-
.map(address => address.address)
951+
const networkAddresses = await getAddressesFromXpubXP({
952+
isTestnet,
953+
walletId,
954+
walletType,
955+
accountIndex: account.index
956+
})
957+
return networkAddresses.externalAddresses
1014958
}
1015959

1016960
if (walletType === WalletType.SEEDLESS) {
1017961
const storedPubKeys = await SeedlessPubKeysStorage.retrieve()
1018962
const publicKeys = storedPubKeys.filter(publicKey =>
1019-
accounts.some(account =>
1020-
publicKey.derivationPath.startsWith(
1021-
AVALANCHE_DERIVATION_PATH_PREFIX + account.index
1022-
)
963+
publicKey.derivationPath.startsWith(
964+
AVALANCHE_DERIVATION_PATH_PREFIX + account.index
1023965
)
1024966
)
1025967

@@ -1028,10 +970,11 @@ class WalletService {
1028970
} as VmNetwork)
1029971
return publicKeys.map(publicKey => {
1030972
const publicKeyXP = Buffer.from(publicKey.key, 'hex')
1031-
return provider.getAddress(
1032-
publicKeyXP,
1033-
networkType === NetworkVMType.AVM ? 'X' : 'P'
1034-
)
973+
const address = provider.getAddress(publicKeyXP, 'P')
974+
return {
975+
address: xpAddressWithoutPrefix(address),
976+
index: getXPAddressIndexFromDerivationPath(publicKey.derivationPath)
977+
}
1035978
})
1036979
}
1037980

packages/core-mobile/app/services/wallet/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
} from '@avalabs/vm-module-types'
1717
import { SolanaProvider } from '@avalabs/core-wallets-sdk'
1818
import { Curve } from 'utils/publicKeys'
19+
import { AddressIndex } from '@avalabs/types'
1920

2021
export type SignTransactionRequest =
2122
| TransactionRequest
@@ -268,3 +269,8 @@ export interface NetworkAddresses {
268269
externalAddresses: { address: string; index: number; hasActivity: boolean }[]
269270
internalAddresses: { address: string; index: number; hasActivity: boolean }[]
270271
}
272+
273+
export type NormalizedXPAddresses = {
274+
externalAddresses: AddressIndex[]
275+
internalAddresses: AddressIndex[]
276+
}

packages/core-mobile/app/store/rpc/handlers/account/avalanche_getAccounts/avalanche_getAccounts.test.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ jest.mock('store/account/slice', () => {
1212
}
1313
})
1414

15+
jest.mock('store/settings/advanced', () => {
16+
const actual = jest.requireActual('store/settings/advanced')
17+
return {
18+
...actual,
19+
selectIsDeveloperMode: () => true
20+
}
21+
})
22+
1523
jest.mock('store/wallet/slice', () => ({
1624
selectWalletById: () => () => ({
1725
id: 'wallet-1',
@@ -27,7 +35,8 @@ jest.mock('services/wallet/WalletService', () => ({
2735
.fn()
2836
.mockResolvedValue(
2937
'xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5'
30-
)
38+
),
39+
getXPExternalAddresses: jest.fn().mockResolvedValue([])
3140
}
3241
}))
3342

@@ -89,7 +98,8 @@ describe('avalanche_getAccounts handler', () => {
8998
walletType: 'MNEMONIC',
9099
walletName: 'Test Wallet',
91100
xpubXP:
92-
'xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5'
101+
'xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5',
102+
xpAddresses: []
93103
},
94104
{
95105
id: '1',
@@ -107,7 +117,8 @@ describe('avalanche_getAccounts handler', () => {
107117
walletType: 'MNEMONIC',
108118
walletName: 'Test Wallet',
109119
xpubXP:
110-
'xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5'
120+
'xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5',
121+
xpAddresses: []
111122
}
112123
]
113124
})
@@ -132,6 +143,7 @@ describe('avalanche_getAccounts handler', () => {
132143

133144
expect(result.success).toBe(true)
134145
if (result.success) {
146+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
135147
const accounts = result.value as any[]
136148
expect(accounts).toHaveLength(2)
137149
expect(accounts[0].xpubXP).toBeUndefined()

0 commit comments

Comments
 (0)