@@ -17,6 +17,7 @@ import {
17
17
BtcAccountType ,
18
18
BtcMethod ,
19
19
EthAccountType ,
20
+ SolScope ,
20
21
} from '@metamask/keyring-api' ;
21
22
import { Messenger } from '@metamask/base-controller' ;
22
23
import { LoggingController , LogType } from '@metamask/logging-controller' ;
@@ -36,6 +37,7 @@ import {
36
37
Caip25EndowmentPermissionName ,
37
38
} from '@metamask/chain-agnostic-permission' ;
38
39
import { PermissionDoesNotExistError } from '@metamask/permission-controller' ;
40
+ import { KeyringInternalSnapClient } from '@metamask/keyring-internal-snap-client' ;
39
41
import { createTestProviderTools } from '../../test/stub/provider' ;
40
42
import {
41
43
HardwareDeviceNames ,
@@ -3957,7 +3959,7 @@ describe('MetaMaskController', () => {
3957
3959
const newlyAddedKeyringId =
3958
3960
metamaskController . keyringController . state . keyringsMetadata [
3959
3961
metamaskController . keyringController . state . keyringsMetadata . length -
3960
- 1
3962
+ 2 // -1 for the snap keyring, -1 for the newly added keyring
3961
3963
] . id ;
3962
3964
3963
3965
const newSRP = Buffer . from (
@@ -3967,7 +3969,10 @@ describe('MetaMaskController', () => {
3967
3969
expect (
3968
3970
currentKeyrings . filter ( ( kr ) => kr . type === 'HD Key Tree' ) ,
3969
3971
) . toHaveLength ( 2 ) ;
3970
- expect ( currentKeyrings ) . toHaveLength ( previousKeyrings . length + 1 ) ;
3972
+ expect (
3973
+ currentKeyrings . filter ( ( kr ) => kr . type === 'Snap Keyring' ) ,
3974
+ ) . toHaveLength ( 1 ) ;
3975
+ expect ( currentKeyrings ) . toHaveLength ( previousKeyrings . length + 2 ) ;
3971
3976
expect ( newSRP ) . toStrictEqual ( TEST_SEED_ALT ) ;
3972
3977
} ) ;
3973
3978
@@ -3982,6 +3987,77 @@ describe('MetaMaskController', () => {
3982
3987
'This Secret Recovery Phrase has already been imported.' ,
3983
3988
) ;
3984
3989
} ) ;
3990
+
3991
+ ///: BEGIN:ONLY_INCLUDE_IF(multi-srp)
3992
+ it ( 'discovers and creates Solana accounts through KeyringInternalSnapClient when importing a mnemonic' , async ( ) => {
3993
+ const password = 'what-what-what' ;
3994
+ jest . spyOn ( metamaskController , 'getBalance' ) . mockResolvedValue ( '0x0' ) ;
3995
+
3996
+ const mockDiscoverAccounts = jest
3997
+ . fn ( )
3998
+ . mockResolvedValueOnce ( [ { derivationPath : "m/44'/501'/0'/0'" } ] )
3999
+ . mockResolvedValueOnce ( [ { derivationPath : "m/44'/501'/1'/0'" } ] )
4000
+ . mockResolvedValueOnce ( [ ] ) ; // Return empty array on third call to stop the discovery loop
4001
+
4002
+ jest
4003
+ . spyOn ( KeyringInternalSnapClient . prototype , 'discoverAccounts' )
4004
+ . mockImplementation ( mockDiscoverAccounts ) ;
4005
+
4006
+ const mockCreateAccount = jest . fn ( ) . mockResolvedValue ( undefined ) ;
4007
+ const mockSnapKeyring = { createAccount : mockCreateAccount } ;
4008
+ jest
4009
+ . spyOn ( metamaskController , 'getSnapKeyring' )
4010
+ . mockResolvedValue ( mockSnapKeyring ) ;
4011
+
4012
+ await metamaskController . createNewVaultAndRestore ( password , TEST_SEED ) ;
4013
+ await metamaskController . importMnemonicToVault ( TEST_SEED_ALT ) ;
4014
+
4015
+ // Assert that discoverAccounts was called correctly
4016
+ // Should be called 3 times (twice with discovered accounts, once with empty array)
4017
+ expect ( mockDiscoverAccounts ) . toHaveBeenCalledTimes ( 3 ) ;
4018
+
4019
+ // All calls should include the solana scopes
4020
+ expect ( mockDiscoverAccounts . mock . calls [ 0 ] [ 0 ] ) . toStrictEqual (
4021
+ expect . arrayContaining ( [
4022
+ SolScope . Mainnet ,
4023
+ SolScope . Testnet ,
4024
+ SolScope . Devnet ,
4025
+ ] ) ,
4026
+ ) ;
4027
+
4028
+ // First call should be for index 0
4029
+ expect ( mockDiscoverAccounts . mock . calls [ 0 ] [ 2 ] ) . toBe ( 0 ) ;
4030
+ // Second call should be for index 1
4031
+ expect ( mockDiscoverAccounts . mock . calls [ 1 ] [ 2 ] ) . toBe ( 1 ) ;
4032
+ // Third call should be for index 2
4033
+ expect ( mockDiscoverAccounts . mock . calls [ 2 ] [ 2 ] ) . toBe ( 2 ) ;
4034
+
4035
+ // Assert that createAccount was called correctly for each discovered account
4036
+ expect ( mockCreateAccount ) . toHaveBeenCalledTimes ( 2 ) ;
4037
+
4038
+ // All calls should use the solana snap ID
4039
+ expect ( mockCreateAccount . mock . calls [ 0 ] [ 0 ] ) . toStrictEqual (
4040
+ expect . stringContaining ( 'solana-wallet' ) ,
4041
+ ) ;
4042
+ // First call should use derivation path on index 0
4043
+ expect ( mockCreateAccount . mock . calls [ 0 ] [ 1 ] ) . toStrictEqual ( {
4044
+ derivationPath : "m/44'/501'/0'/0'" ,
4045
+ entropySource : expect . any ( String ) ,
4046
+ } ) ;
4047
+ // All calls should use the same internal options
4048
+ expect ( mockCreateAccount . mock . calls [ 0 ] [ 2 ] ) . toStrictEqual ( {
4049
+ displayConfirmation : false ,
4050
+ displayAccountNameSuggestion : false ,
4051
+ setSelectedAccount : false ,
4052
+ } ) ;
4053
+
4054
+ // Second call should use derivation path on index 1
4055
+ expect ( mockCreateAccount . mock . calls [ 1 ] [ 1 ] ) . toStrictEqual ( {
4056
+ derivationPath : "m/44'/501'/1'/0'" ,
4057
+ entropySource : expect . any ( String ) ,
4058
+ } ) ;
4059
+ } ) ;
4060
+ ///: END:ONLY_INCLUDE_IF
3985
4061
} ) ;
3986
4062
} ) ;
3987
4063
0 commit comments