@metamask/multichain-account-service 8.0.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/CHANGELOG.md +45 -12
  2. package/dist/MultichainAccountGroup.cjs.map +1 -1
  3. package/dist/MultichainAccountGroup.d.cts.map +1 -1
  4. package/dist/MultichainAccountGroup.d.mts.map +1 -1
  5. package/dist/MultichainAccountGroup.mjs.map +1 -1
  6. package/dist/MultichainAccountService-method-action-types.cjs.map +1 -1
  7. package/dist/MultichainAccountService-method-action-types.d.cts +9 -1
  8. package/dist/MultichainAccountService-method-action-types.d.cts.map +1 -1
  9. package/dist/MultichainAccountService-method-action-types.d.mts +9 -1
  10. package/dist/MultichainAccountService-method-action-types.d.mts.map +1 -1
  11. package/dist/MultichainAccountService-method-action-types.mjs.map +1 -1
  12. package/dist/MultichainAccountService.cjs +1 -0
  13. package/dist/MultichainAccountService.cjs.map +1 -1
  14. package/dist/MultichainAccountService.d.cts.map +1 -1
  15. package/dist/MultichainAccountService.d.mts.map +1 -1
  16. package/dist/MultichainAccountService.mjs +1 -0
  17. package/dist/MultichainAccountService.mjs.map +1 -1
  18. package/dist/MultichainAccountWallet.cjs.map +1 -1
  19. package/dist/MultichainAccountWallet.d.cts.map +1 -1
  20. package/dist/MultichainAccountWallet.d.mts.map +1 -1
  21. package/dist/MultichainAccountWallet.mjs.map +1 -1
  22. package/dist/analytics/perf.cjs +1 -1
  23. package/dist/analytics/perf.cjs.map +1 -1
  24. package/dist/analytics/perf.mjs +1 -1
  25. package/dist/analytics/perf.mjs.map +1 -1
  26. package/dist/errors.cjs +1 -1
  27. package/dist/errors.cjs.map +1 -1
  28. package/dist/errors.d.cts.map +1 -1
  29. package/dist/errors.d.mts.map +1 -1
  30. package/dist/errors.mjs +2 -2
  31. package/dist/errors.mjs.map +1 -1
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +1 -1
  34. package/dist/index.d.cts.map +1 -1
  35. package/dist/index.d.mts +1 -1
  36. package/dist/index.d.mts.map +1 -1
  37. package/dist/index.mjs.map +1 -1
  38. package/dist/providers/AccountProviderWrapper.cjs.map +1 -1
  39. package/dist/providers/AccountProviderWrapper.d.cts +3 -2
  40. package/dist/providers/AccountProviderWrapper.d.cts.map +1 -1
  41. package/dist/providers/AccountProviderWrapper.d.mts +3 -2
  42. package/dist/providers/AccountProviderWrapper.d.mts.map +1 -1
  43. package/dist/providers/AccountProviderWrapper.mjs.map +1 -1
  44. package/dist/providers/BaseBip44AccountProvider.cjs +29 -0
  45. package/dist/providers/BaseBip44AccountProvider.cjs.map +1 -1
  46. package/dist/providers/BaseBip44AccountProvider.d.cts +29 -2
  47. package/dist/providers/BaseBip44AccountProvider.d.cts.map +1 -1
  48. package/dist/providers/BaseBip44AccountProvider.d.mts +29 -2
  49. package/dist/providers/BaseBip44AccountProvider.d.mts.map +1 -1
  50. package/dist/providers/BaseBip44AccountProvider.mjs +29 -0
  51. package/dist/providers/BaseBip44AccountProvider.mjs.map +1 -1
  52. package/dist/providers/BtcAccountProvider.cjs +2 -2
  53. package/dist/providers/BtcAccountProvider.cjs.map +1 -1
  54. package/dist/providers/BtcAccountProvider.d.cts +3 -2
  55. package/dist/providers/BtcAccountProvider.d.cts.map +1 -1
  56. package/dist/providers/BtcAccountProvider.d.mts +3 -2
  57. package/dist/providers/BtcAccountProvider.d.mts.map +1 -1
  58. package/dist/providers/BtcAccountProvider.mjs +2 -2
  59. package/dist/providers/BtcAccountProvider.mjs.map +1 -1
  60. package/dist/providers/EvmAccountProvider.cjs +63 -46
  61. package/dist/providers/EvmAccountProvider.cjs.map +1 -1
  62. package/dist/providers/EvmAccountProvider.d.cts +3 -2
  63. package/dist/providers/EvmAccountProvider.d.cts.map +1 -1
  64. package/dist/providers/EvmAccountProvider.d.mts +3 -2
  65. package/dist/providers/EvmAccountProvider.d.mts.map +1 -1
  66. package/dist/providers/EvmAccountProvider.mjs +63 -46
  67. package/dist/providers/EvmAccountProvider.mjs.map +1 -1
  68. package/dist/providers/SnapAccountProvider.cjs +2 -2
  69. package/dist/providers/SnapAccountProvider.cjs.map +1 -1
  70. package/dist/providers/SnapAccountProvider.d.cts +1 -1
  71. package/dist/providers/SnapAccountProvider.d.cts.map +1 -1
  72. package/dist/providers/SnapAccountProvider.d.mts +1 -1
  73. package/dist/providers/SnapAccountProvider.d.mts.map +1 -1
  74. package/dist/providers/SnapAccountProvider.mjs +2 -2
  75. package/dist/providers/SnapAccountProvider.mjs.map +1 -1
  76. package/dist/providers/SolAccountProvider.cjs +2 -2
  77. package/dist/providers/SolAccountProvider.cjs.map +1 -1
  78. package/dist/providers/SolAccountProvider.d.cts +3 -2
  79. package/dist/providers/SolAccountProvider.d.cts.map +1 -1
  80. package/dist/providers/SolAccountProvider.d.mts +3 -2
  81. package/dist/providers/SolAccountProvider.d.mts.map +1 -1
  82. package/dist/providers/SolAccountProvider.mjs +2 -2
  83. package/dist/providers/SolAccountProvider.mjs.map +1 -1
  84. package/dist/providers/TrxAccountProvider.cjs +2 -2
  85. package/dist/providers/TrxAccountProvider.cjs.map +1 -1
  86. package/dist/providers/TrxAccountProvider.d.cts +3 -2
  87. package/dist/providers/TrxAccountProvider.d.cts.map +1 -1
  88. package/dist/providers/TrxAccountProvider.d.mts +3 -2
  89. package/dist/providers/TrxAccountProvider.d.mts.map +1 -1
  90. package/dist/providers/TrxAccountProvider.mjs +2 -2
  91. package/dist/providers/TrxAccountProvider.mjs.map +1 -1
  92. package/dist/providers/utils.cjs +13 -1
  93. package/dist/providers/utils.cjs.map +1 -1
  94. package/dist/providers/utils.d.cts +7 -0
  95. package/dist/providers/utils.d.cts.map +1 -1
  96. package/dist/providers/utils.d.mts +7 -0
  97. package/dist/providers/utils.d.mts.map +1 -1
  98. package/dist/providers/utils.mjs +11 -0
  99. package/dist/providers/utils.mjs.map +1 -1
  100. package/dist/tests/accounts.cjs +4 -6
  101. package/dist/tests/accounts.cjs.map +1 -1
  102. package/dist/tests/accounts.d.cts +8 -21
  103. package/dist/tests/accounts.d.cts.map +1 -1
  104. package/dist/tests/accounts.d.mts +8 -21
  105. package/dist/tests/accounts.d.mts.map +1 -1
  106. package/dist/tests/accounts.mjs +4 -6
  107. package/dist/tests/accounts.mjs.map +1 -1
  108. package/dist/tests/messenger.cjs +1 -0
  109. package/dist/tests/messenger.cjs.map +1 -1
  110. package/dist/tests/messenger.d.cts.map +1 -1
  111. package/dist/tests/messenger.d.mts.map +1 -1
  112. package/dist/tests/messenger.mjs +1 -0
  113. package/dist/tests/messenger.mjs.map +1 -1
  114. package/dist/tests/providers.cjs.map +1 -1
  115. package/dist/tests/providers.d.cts +2 -1
  116. package/dist/tests/providers.d.cts.map +1 -1
  117. package/dist/tests/providers.d.mts +2 -1
  118. package/dist/tests/providers.d.mts.map +1 -1
  119. package/dist/tests/providers.mjs.map +1 -1
  120. package/dist/types.cjs.map +1 -1
  121. package/dist/types.d.cts +4 -4
  122. package/dist/types.d.cts.map +1 -1
  123. package/dist/types.d.mts +4 -4
  124. package/dist/types.d.mts.map +1 -1
  125. package/dist/types.mjs.map +1 -1
  126. package/package.json +32 -31
@@ -1 +1 @@
1
- {"version":3,"file":"BtcAccountProvider.d.mts","sourceRoot":"","sources":["../../src/providers/BtcAccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,mCAAmC;AAChE,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,mBAAmB,EACpB,8BAA8B;AAM/B,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AACtE,OAAO,KAAK,EAAE,MAAM,EAAE,4BAA4B;AAElD,OAAO,EAAE,mBAAmB,EAAE,kCAA8B;AAC5D,OAAO,KAAK,EACV,qBAAqB,EACrB,yBAAyB,EAC1B,kCAA8B;AAI/B,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAElE,MAAM,MAAM,wBAAwB,GAAG,yBAAyB,CAAC;AAEjE,eAAO,MAAM,yBAAyB,YAAY,CAAC;AAEnD,eAAO,MAAM,mCAAmC,EAAE,wBAejD,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,mBAAmB;IACzD,MAAM,CAAC,IAAI,SAA6B;IAExC,MAAM,CAAC,WAAW,SAAiD;IAEnE,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAMxC;gBAGA,SAAS,EAAE,iCAAiC,EAC5C,MAAM,GAAE,wBAA8D,EACtE,KAAK,GAAE,aAA6B;IAKtC,OAAO,IAAI,MAAM;IAIjB,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC,GAAG,OAAO;cAOjD,eAAe,CAChC,OAAO,EAAE,qBAAqB,EAC9B,EACE,aAAa,EACb,UAAU,GACX,EAAE;QAAE,aAAa,EAAE,eAAe,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GACxD,OAAO,CAAC,cAAc,CAAC;IASpB,gBAAgB,CAAC,EACrB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;CA+C5C"}
1
+ {"version":3,"file":"BtcAccountProvider.d.mts","sourceRoot":"","sources":["../../src/providers/BtcAccountProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,mCAAmC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,8BAA8B;AAM7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,iCAAiC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AACtE,OAAO,KAAK,EAAE,MAAM,EAAE,4BAA4B;AAIlD,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAClE,OAAO,EAAE,mBAAmB,EAAE,kCAA8B;AAC5D,OAAO,KAAK,EACV,qBAAqB,EACrB,yBAAyB,EAC1B,kCAA8B;AAG/B,MAAM,MAAM,wBAAwB,GAAG,yBAAyB,CAAC;AAEjE,eAAO,MAAM,yBAAyB,YAAY,CAAC;AAEnD,eAAO,MAAM,mCAAmC,EAAE,wBAejD,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,mBAAmB;IACzD,MAAM,CAAC,IAAI,SAA6B;IAExC,MAAM,CAAC,WAAW,SAAiD;IAEnE,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAMxC;gBAGA,SAAS,EAAE,iCAAiC,EAC5C,MAAM,GAAE,wBAA8D,EACtE,KAAK,GAAE,aAA6B;IAKtC,OAAO,IAAI,MAAM;IAIjB,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC,GAAG,OAAO;cAOjD,eAAe,CAChC,OAAO,EAAE,qBAAqB,EAC9B,EACE,aAAa,EACb,UAAU,GACX,EAAE;QAAE,aAAa,EAAE,eAAe,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GACxD,OAAO,CAAC,cAAc,CAAC;IASpB,gBAAgB,CAAC,EACrB,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;CA+C5C"}
@@ -1,8 +1,8 @@
1
1
  import { AccountCreationType, BtcAccountType, BtcScope } from "@metamask/keyring-api";
2
- import { SnapAccountProvider } from "./SnapAccountProvider.mjs";
3
- import { withRetry, withTimeout } from "./utils.mjs";
4
2
  import { traceFallback } from "../analytics/index.mjs";
5
3
  import { TraceName } from "../analytics/traces.mjs";
4
+ import { SnapAccountProvider } from "./SnapAccountProvider.mjs";
5
+ import { withRetry, withTimeout } from "./utils.mjs";
6
6
  export const BTC_ACCOUNT_PROVIDER_NAME = 'Bitcoin';
7
7
  export const BTC_ACCOUNT_PROVIDER_DEFAULT_CONFIG = {
8
8
  maxConcurrency: 3,
@@ -1 +1 @@
1
- {"version":3,"file":"BtcAccountProvider.mjs","sourceRoot":"","sources":["../../src/providers/BtcAccountProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Bip44Account } from '@metamask/account-api';\nimport type { TraceCallback } from '@metamask/controller-utils';\nimport type {\n EntropySourceId,\n KeyringAccount,\n KeyringCapabilities,\n} from '@metamask/keyring-api';\nimport {\n AccountCreationType,\n BtcAccountType,\n BtcScope,\n} from '@metamask/keyring-api';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { SnapId } from '@metamask/snaps-sdk';\n\nimport { SnapAccountProvider } from './SnapAccountProvider';\nimport type {\n RestrictedSnapKeyring,\n SnapAccountProviderConfig,\n} from './SnapAccountProvider';\nimport { withRetry, withTimeout } from './utils';\nimport { traceFallback } from '../analytics';\nimport { TraceName } from '../analytics/traces';\nimport type { MultichainAccountServiceMessenger } from '../types';\n\nexport type BtcAccountProviderConfig = SnapAccountProviderConfig;\n\nexport const BTC_ACCOUNT_PROVIDER_NAME = 'Bitcoin';\n\nexport const BTC_ACCOUNT_PROVIDER_DEFAULT_CONFIG: BtcAccountProviderConfig = {\n maxConcurrency: 3,\n createAccounts: {\n batched: false, // For now, the Snap is not fully v2 compliant.\n timeoutMs: 3000,\n },\n discovery: {\n enabled: true,\n timeoutMs: 2000,\n maxAttempts: 3,\n backOffMs: 1000,\n },\n resyncAccounts: {\n autoRemoveExtraSnapAccounts: true,\n },\n};\n\nexport class BtcAccountProvider extends SnapAccountProvider {\n static NAME = BTC_ACCOUNT_PROVIDER_NAME;\n\n static BTC_SNAP_ID = 'npm:@metamask/bitcoin-wallet-snap' as SnapId;\n\n readonly capabilities: KeyringCapabilities = {\n scopes: [BtcScope.Mainnet, BtcScope.Testnet],\n bip44: {\n deriveIndex: true,\n deriveIndexRange: true,\n },\n };\n\n constructor(\n messenger: MultichainAccountServiceMessenger,\n config: BtcAccountProviderConfig = BTC_ACCOUNT_PROVIDER_DEFAULT_CONFIG,\n trace: TraceCallback = traceFallback,\n ) {\n super(BtcAccountProvider.BTC_SNAP_ID, messenger, config, trace);\n }\n\n getName(): string {\n return BtcAccountProvider.NAME;\n }\n\n isAccountCompatible(account: Bip44Account<InternalAccount>): boolean {\n return (\n account.type === BtcAccountType.P2wpkh &&\n Object.values<string>(BtcAccountType).includes(account.type)\n );\n }\n\n protected override createAccountV1(\n keyring: RestrictedSnapKeyring,\n {\n entropySource,\n groupIndex,\n }: { entropySource: EntropySourceId; groupIndex: number },\n ): Promise<KeyringAccount> {\n return keyring.createAccount({\n entropySource,\n index: groupIndex,\n addressType: BtcAccountType.P2wpkh,\n scope: BtcScope.Mainnet,\n });\n }\n\n async discoverAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n return this.withSnap(async ({ client, keyring }) => {\n return await super.trace(\n {\n name: TraceName.SnapDiscoverAccounts,\n data: {\n provider: this.getName(),\n },\n },\n async () => {\n if (!this.config.discovery.enabled) {\n return [];\n }\n\n const discoveredAccounts = await withRetry(\n () =>\n withTimeout(\n () =>\n client.discoverAccounts(\n [BtcScope.Mainnet],\n entropySource,\n groupIndex,\n ),\n this.config.discovery.timeoutMs,\n ),\n {\n maxAttempts: this.config.discovery.maxAttempts,\n backOffMs: this.config.discovery.backOffMs,\n },\n );\n\n if (\n !Array.isArray(discoveredAccounts) ||\n discoveredAccounts.length === 0\n ) {\n return [];\n }\n\n return await this.createBip44Accounts(keyring, {\n type: AccountCreationType.Bip44DeriveIndex,\n entropySource,\n groupIndex,\n });\n },\n );\n });\n }\n}\n"]}
1
+ {"version":3,"file":"BtcAccountProvider.mjs","sourceRoot":"","sources":["../../src/providers/BtcAccountProvider.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,QAAQ,EACT,8BAA8B;AAK/B,OAAO,EAAE,aAAa,EAAE,+BAAqB;AAC7C,OAAO,EAAE,SAAS,EAAE,gCAA4B;AAEhD,OAAO,EAAE,mBAAmB,EAAE,kCAA8B;AAK5D,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,oBAAgB;AAIjD,MAAM,CAAC,MAAM,yBAAyB,GAAG,SAAS,CAAC;AAEnD,MAAM,CAAC,MAAM,mCAAmC,GAA6B;IAC3E,cAAc,EAAE,CAAC;IACjB,cAAc,EAAE;QACd,OAAO,EAAE,KAAK,EAAE,+CAA+C;QAC/D,SAAS,EAAE,IAAI;KAChB;IACD,SAAS,EAAE;QACT,OAAO,EAAE,IAAI;QACb,SAAS,EAAE,IAAI;QACf,WAAW,EAAE,CAAC;QACd,SAAS,EAAE,IAAI;KAChB;IACD,cAAc,EAAE;QACd,2BAA2B,EAAE,IAAI;KAClC;CACF,CAAC;AAEF,MAAM,OAAO,kBAAmB,SAAQ,mBAAmB;IAazD,YACE,SAA4C,EAC5C,SAAmC,mCAAmC,EACtE,QAAuB,aAAa;QAEpC,KAAK,CAAC,kBAAkB,CAAC,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QAbzD,iBAAY,GAAwB;YAC3C,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC;YAC5C,KAAK,EAAE;gBACL,WAAW,EAAE,IAAI;gBACjB,gBAAgB,EAAE,IAAI;aACvB;SACF,CAAC;IAQF,CAAC;IAED,OAAO;QACL,OAAO,kBAAkB,CAAC,IAAI,CAAC;IACjC,CAAC;IAED,mBAAmB,CAAC,OAAsC;QACxD,OAAO,CACL,OAAO,CAAC,IAAI,KAAK,cAAc,CAAC,MAAM;YACtC,MAAM,CAAC,MAAM,CAAS,cAAc,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAC7D,CAAC;IACJ,CAAC;IAEkB,eAAe,CAChC,OAA8B,EAC9B,EACE,aAAa,EACb,UAAU,GAC6C;QAEzD,OAAO,OAAO,CAAC,aAAa,CAAC;YAC3B,aAAa;YACb,KAAK,EAAE,UAAU;YACjB,WAAW,EAAE,cAAc,CAAC,MAAM;YAClC,KAAK,EAAE,QAAQ,CAAC,OAAO;SACxB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,EACrB,aAAa,EACb,UAAU,GAIX;QACC,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;YACjD,OAAO,MAAM,KAAK,CAAC,KAAK,CACtB;gBACE,IAAI,EAAE,SAAS,CAAC,oBAAoB;gBACpC,IAAI,EAAE;oBACJ,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE;iBACzB;aACF,EACD,KAAK,IAAI,EAAE;gBACT,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;oBACnC,OAAO,EAAE,CAAC;gBACZ,CAAC;gBAED,MAAM,kBAAkB,GAAG,MAAM,SAAS,CACxC,GAAG,EAAE,CACH,WAAW,CACT,GAAG,EAAE,CACH,MAAM,CAAC,gBAAgB,CACrB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAClB,aAAa,EACb,UAAU,CACX,EACH,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAChC,EACH;oBACE,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW;oBAC9C,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS;iBAC3C,CACF,CAAC;gBAEF,IACE,CAAC,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC;oBAClC,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAC/B,CAAC;oBACD,OAAO,EAAE,CAAC;gBACZ,CAAC;gBAED,OAAO,MAAM,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE;oBAC7C,IAAI,EAAE,mBAAmB,CAAC,gBAAgB;oBAC1C,aAAa;oBACb,UAAU;iBACX,CAAC,CAAC;YACL,CAAC,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;;AAlGM,uBAAI,GAAG,yBAAyB,AAA5B,CAA6B;AAEjC,8BAAW,GAAG,mCAA6C,AAAhD,CAAiD","sourcesContent":["import type { Bip44Account } from '@metamask/account-api';\nimport type { TraceCallback } from '@metamask/controller-utils';\nimport type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api';\nimport {\n AccountCreationType,\n BtcAccountType,\n BtcScope,\n} from '@metamask/keyring-api';\nimport type { KeyringCapabilities } from '@metamask/keyring-api/v2';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { SnapId } from '@metamask/snaps-sdk';\n\nimport { traceFallback } from '../analytics';\nimport { TraceName } from '../analytics/traces';\nimport type { MultichainAccountServiceMessenger } from '../types';\nimport { SnapAccountProvider } from './SnapAccountProvider';\nimport type {\n RestrictedSnapKeyring,\n SnapAccountProviderConfig,\n} from './SnapAccountProvider';\nimport { withRetry, withTimeout } from './utils';\n\nexport type BtcAccountProviderConfig = SnapAccountProviderConfig;\n\nexport const BTC_ACCOUNT_PROVIDER_NAME = 'Bitcoin';\n\nexport const BTC_ACCOUNT_PROVIDER_DEFAULT_CONFIG: BtcAccountProviderConfig = {\n maxConcurrency: 3,\n createAccounts: {\n batched: false, // For now, the Snap is not fully v2 compliant.\n timeoutMs: 3000,\n },\n discovery: {\n enabled: true,\n timeoutMs: 2000,\n maxAttempts: 3,\n backOffMs: 1000,\n },\n resyncAccounts: {\n autoRemoveExtraSnapAccounts: true,\n },\n};\n\nexport class BtcAccountProvider extends SnapAccountProvider {\n static NAME = BTC_ACCOUNT_PROVIDER_NAME;\n\n static BTC_SNAP_ID = 'npm:@metamask/bitcoin-wallet-snap' as SnapId;\n\n readonly capabilities: KeyringCapabilities = {\n scopes: [BtcScope.Mainnet, BtcScope.Testnet],\n bip44: {\n deriveIndex: true,\n deriveIndexRange: true,\n },\n };\n\n constructor(\n messenger: MultichainAccountServiceMessenger,\n config: BtcAccountProviderConfig = BTC_ACCOUNT_PROVIDER_DEFAULT_CONFIG,\n trace: TraceCallback = traceFallback,\n ) {\n super(BtcAccountProvider.BTC_SNAP_ID, messenger, config, trace);\n }\n\n getName(): string {\n return BtcAccountProvider.NAME;\n }\n\n isAccountCompatible(account: Bip44Account<InternalAccount>): boolean {\n return (\n account.type === BtcAccountType.P2wpkh &&\n Object.values<string>(BtcAccountType).includes(account.type)\n );\n }\n\n protected override createAccountV1(\n keyring: RestrictedSnapKeyring,\n {\n entropySource,\n groupIndex,\n }: { entropySource: EntropySourceId; groupIndex: number },\n ): Promise<KeyringAccount> {\n return keyring.createAccount({\n entropySource,\n index: groupIndex,\n addressType: BtcAccountType.P2wpkh,\n scope: BtcScope.Mainnet,\n });\n }\n\n async discoverAccounts({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n return this.withSnap(async ({ client, keyring }) => {\n return await super.trace(\n {\n name: TraceName.SnapDiscoverAccounts,\n data: {\n provider: this.getName(),\n },\n },\n async () => {\n if (!this.config.discovery.enabled) {\n return [];\n }\n\n const discoveredAccounts = await withRetry(\n () =>\n withTimeout(\n () =>\n client.discoverAccounts(\n [BtcScope.Mainnet],\n entropySource,\n groupIndex,\n ),\n this.config.discovery.timeoutMs,\n ),\n {\n maxAttempts: this.config.discovery.maxAttempts,\n backOffMs: this.config.discovery.backOffMs,\n },\n );\n\n if (\n !Array.isArray(discoveredAccounts) ||\n discoveredAccounts.length === 0\n ) {\n return [];\n }\n\n return await this.createBip44Accounts(keyring, {\n type: AccountCreationType.Bip44DeriveIndex,\n entropySource,\n groupIndex,\n });\n },\n );\n });\n }\n}\n"]}
@@ -10,19 +10,18 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _EvmAccountProvider_instances, _EvmAccountProvider_config, _EvmAccountProvider_trace, _EvmAccountProvider_getAccountId, _EvmAccountProvider_createAccount, _EvmAccountProvider_getTransactionCount, _EvmAccountProvider_getAddressFromGroupIndex;
13
+ var _EvmAccountProvider_instances, _EvmAccountProvider_config, _EvmAccountProvider_trace, _EvmAccountProvider_createAccount, _EvmAccountProvider_getAddressFromGroupIndex, _EvmAccountProvider_getTransactionCount;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.EvmAccountProvider = exports.EVM_ACCOUNT_PROVIDER_DEFAULT_CONFIG = exports.EVM_ACCOUNT_PROVIDER_NAME = void 0;
16
16
  const util_1 = require("@ethereumjs/util");
17
- const accounts_controller_1 = require("@metamask/accounts-controller");
18
17
  const keyring_api_1 = require("@metamask/keyring-api");
19
18
  const keyring_controller_1 = require("@metamask/keyring-controller");
20
19
  const utils_1 = require("@metamask/utils");
21
- const BaseBip44AccountProvider_1 = require("./BaseBip44AccountProvider.cjs");
22
- const utils_2 = require("./utils.cjs");
23
20
  const analytics_1 = require("../analytics/index.cjs");
24
21
  const traces_1 = require("../analytics/traces.cjs");
25
22
  const logger_1 = require("../logger.cjs");
23
+ const BaseBip44AccountProvider_1 = require("./BaseBip44AccountProvider.cjs");
24
+ const utils_2 = require("./utils.cjs");
26
25
  const ETH_MAINNET_CHAIN_ID = '0x1';
27
26
  /**
28
27
  * Asserts an internal account exists.
@@ -97,7 +96,7 @@ class EvmAccountProvider extends BaseBip44AccountProvider_1.BaseBip44AccountProv
97
96
  if (options.type === keyring_api_1.AccountCreationType.Bip44DeriveIndexRange) {
98
97
  const { range } = options;
99
98
  // Use a single withKeyring call for the entire range.
100
- const accountIds = await this.withKeyring({ id: entropySource }, async ({ keyring }) => {
99
+ const accountIds = await this.withKeyringV2({ id: entropySource }, async ({ keyring }) => {
101
100
  const existing = await keyring.getAccounts();
102
101
  // Validate no gaps: we can only create accounts starting from existing.length.
103
102
  if (range.from > existing.length) {
@@ -108,17 +107,19 @@ class EvmAccountProvider extends BaseBip44AccountProvider_1.BaseBip44AccountProv
108
107
  for (let groupIndex = range.from; groupIndex <= range.to; groupIndex++) {
109
108
  if (groupIndex < existing.length) {
110
109
  // Account already exists.
111
- result.push(__classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_getAccountId).call(this, existing[groupIndex]));
110
+ result.push(existing[groupIndex].id);
112
111
  }
113
112
  }
114
- // Determine if we need to create new accounts.
115
- const from = Math.max(range.from, existing.length);
116
- if (from <= range.to) {
117
- // Calculate how many new accounts to create.
118
- const accountsToCreate = range.to - existing.length + 1;
119
- // Create all new accounts in one call.
120
- const newAccounts = await keyring.addAccounts(accountsToCreate);
121
- result.push(...newAccounts.map((address) => __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_getAccountId).call(this, address)));
113
+ // Create new accounts one-by-one since HdKeyringV2 only supports
114
+ // bip44:derive-index (not bip44:derive-index-range).
115
+ for (let groupIndex = Math.max(range.from, existing.length); groupIndex <= range.to; groupIndex++) {
116
+ const [created] = await keyring.createAccounts({
117
+ type: keyring_api_1.AccountCreationType.Bip44DeriveIndex,
118
+ entropySource,
119
+ groupIndex,
120
+ });
121
+ (0, utils_1.assert)(created, 'Account creation failed');
122
+ result.push(created.id);
122
123
  }
123
124
  return result;
124
125
  });
@@ -133,13 +134,13 @@ class EvmAccountProvider extends BaseBip44AccountProvider_1.BaseBip44AccountProv
133
134
  }
134
135
  // Handle Bip44DeriveIndex (single account creation).
135
136
  const { groupIndex } = options;
136
- const [address] = await __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_createAccount).call(this, {
137
+ const [created] = await __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_createAccount).call(this, {
137
138
  entropySource,
138
139
  groupIndex,
139
140
  throwOnGap: true,
140
141
  });
141
- const accountId = __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_getAccountId).call(this, address);
142
- const account = this.messenger.call('AccountsController:getAccount', accountId);
142
+ (0, utils_1.assert)(created, 'Account creation failed');
143
+ const account = this.messenger.call('AccountsController:getAccount', created.id);
143
144
  // We MUST have the associated internal account.
144
145
  assertInternalAccountExists(account);
145
146
  const accountsArray = [account];
@@ -176,13 +177,14 @@ class EvmAccountProvider extends BaseBip44AccountProvider_1.BaseBip44AccountProv
176
177
  return [];
177
178
  }
178
179
  // We have some activity on this address, we try to create the account.
179
- const [address] = await __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_createAccount).call(this, {
180
+ const [created] = await __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_createAccount).call(this, {
180
181
  entropySource,
181
182
  groupIndex,
183
+ throwOnGap: false,
182
184
  });
183
- (0, utils_1.assert)(addressFromGroupIndex === address, 'Created account does not match address from group index.');
184
- const accoundId = __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_getAccountId).call(this, address);
185
- const account = this.messenger.call('AccountsController:getAccount', accoundId);
185
+ (0, utils_1.assert)(created, 'Account creation failed');
186
+ (0, utils_1.assert)(addressFromGroupIndex === created.address, 'Created account does not match address from group index.');
187
+ const account = this.messenger.call('AccountsController:getAccount', created.id);
186
188
  assertInternalAccountExists(account);
187
189
  (0, BaseBip44AccountProvider_1.assertIsBip44Account)(account);
188
190
  this.accounts.add(account.id);
@@ -195,9 +197,7 @@ class EvmAccountProvider extends BaseBip44AccountProvider_1.BaseBip44AccountProv
195
197
  }
196
198
  }
197
199
  exports.EvmAccountProvider = EvmAccountProvider;
198
- _EvmAccountProvider_config = new WeakMap(), _EvmAccountProvider_trace = new WeakMap(), _EvmAccountProvider_instances = new WeakSet(), _EvmAccountProvider_getAccountId = function _EvmAccountProvider_getAccountId(address) {
199
- return (0, accounts_controller_1.getUUIDFromAddressOfNormalAccount)(address);
200
- }, _EvmAccountProvider_createAccount =
200
+ _EvmAccountProvider_config = new WeakMap(), _EvmAccountProvider_trace = new WeakMap(), _EvmAccountProvider_instances = new WeakSet(), _EvmAccountProvider_createAccount =
201
201
  /**
202
202
  * Create an EVM account.
203
203
  *
@@ -205,22 +205,54 @@ _EvmAccountProvider_config = new WeakMap(), _EvmAccountProvider_trace = new Weak
205
205
  * @param opts.entropySource - The entropy source to use for the creation of the account.
206
206
  * @param opts.groupIndex - The index of the group to create the account for.
207
207
  * @param opts.throwOnGap - Whether to throw an error if the account index is not contiguous.
208
- * @returns The account ID and a boolean indicating if the account was created.
208
+ * @returns The created or existing keyring account(s) at the requested group
209
+ * index. Returns an empty array if the keyring did not create an account.
209
210
  */
210
- async function _EvmAccountProvider_createAccount({ entropySource, groupIndex, throwOnGap = false, }) {
211
- const result = await this.withKeyring({ id: entropySource }, async ({ keyring }) => {
211
+ async function _EvmAccountProvider_createAccount({ entropySource, groupIndex, throwOnGap, }) {
212
+ return await this.withKeyringV2({ id: entropySource }, async ({ keyring }) => {
212
213
  const existing = await keyring.getAccounts();
213
214
  if (groupIndex < existing.length) {
214
- return [existing[groupIndex], false];
215
+ return [existing[groupIndex]];
215
216
  }
216
217
  // If the throwOnGap flag is set, we throw an error to prevent index gaps.
217
218
  if (throwOnGap && groupIndex !== existing.length) {
218
219
  throw new Error('Trying to create too many accounts');
219
220
  }
220
- const [added] = await keyring.addAccounts(1);
221
- return [added, true];
221
+ return await keyring.createAccounts({
222
+ type: keyring_api_1.AccountCreationType.Bip44DeriveIndex,
223
+ entropySource,
224
+ groupIndex,
225
+ });
226
+ });
227
+ }, _EvmAccountProvider_getAddressFromGroupIndex =
228
+ /**
229
+ * Get the address that would be derived for a given group index without
230
+ * persisting an account in the keyring.
231
+ *
232
+ * Peeks at the next address via the HD `root` so discovery can short-circuit
233
+ * (and skip the vault write + `stateChange` event) when there is no on-chain
234
+ * activity at this index.
235
+ *
236
+ * @param opts - The options for the address derivation.
237
+ * @param opts.entropySource - The entropy source to derive from.
238
+ * @param opts.groupIndex - The group index to derive at.
239
+ * @returns The derived address for the given group index.
240
+ */
241
+ async function _EvmAccountProvider_getAddressFromGroupIndex({ entropySource, groupIndex, }) {
242
+ // NOTE: To avoid exposing this function at keyring level, we just re-use its internal state
243
+ // and compute the derivation here.
244
+ return await this.withKeyringV2({ id: entropySource }, async ({ keyring }) => {
245
+ // If the account already exist, do not re-derive and just re-use that account.
246
+ const existing = await keyring.getAccounts();
247
+ if (groupIndex < existing.length) {
248
+ return existing[groupIndex].address;
249
+ }
250
+ // If not, then we just "peek" the next address to avoid creating the account.
251
+ (0, utils_1.assert)(keyring.root, 'Expected HD keyring.root to be set');
252
+ const hdKey = keyring.root.deriveChild(groupIndex);
253
+ (0, utils_1.assert)(hdKey.publicKey, 'Expected public key to be set');
254
+ return (0, utils_1.add0x)((0, utils_1.bytesToHex)((0, util_1.publicToAddress)(hdKey.publicKey, true)).toLowerCase());
222
255
  });
223
- return result;
224
256
  }, _EvmAccountProvider_getTransactionCount =
225
257
  /**
226
258
  * Get the transaction count for an EVM account.
@@ -247,21 +279,6 @@ async function _EvmAccountProvider_getTransactionCount(provider, address) {
247
279
  return 0;
248
280
  }
249
281
  return parseInt(response, 16);
250
- }, _EvmAccountProvider_getAddressFromGroupIndex = async function _EvmAccountProvider_getAddressFromGroupIndex({ entropySource, groupIndex, }) {
251
- // NOTE: To avoid exposing this function at keyring level, we just re-use its internal state
252
- // and compute the derivation here.
253
- return await this.withKeyring({ id: entropySource }, async ({ keyring }) => {
254
- // If the account already exist, do not re-derive and just re-use that account.
255
- const existing = await keyring.getAccounts();
256
- if (groupIndex < existing.length) {
257
- return existing[groupIndex];
258
- }
259
- // If not, then we just "peek" the next address to avoid creating the account.
260
- (0, utils_1.assert)(keyring.root, 'Expected HD keyring.root to be set');
261
- const hdKey = keyring.root.deriveChild(groupIndex);
262
- (0, utils_1.assert)(hdKey.publicKey, 'Expected public key to be set');
263
- return (0, utils_1.add0x)((0, utils_1.bytesToHex)((0, util_1.publicToAddress)(hdKey.publicKey, true)).toLowerCase());
264
- });
265
282
  };
266
283
  EvmAccountProvider.NAME = exports.EVM_ACCOUNT_PROVIDER_NAME;
267
284
  //# sourceMappingURL=EvmAccountProvider.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"EvmAccountProvider.cjs","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import { publicToAddress } from '@ethereumjs/util';\nimport type { Bip44Account } from '@metamask/account-api';\nimport { getUUIDFromAddressOfNormalAccount } from '@metamask/accounts-controller';\nimport type { TraceCallback } from '@metamask/controller-utils';\nimport type { HdKeyring } from '@metamask/eth-hd-keyring';\nimport type {\n CreateAccountOptions,\n EntropySourceId,\n KeyringAccount,\n KeyringCapabilities,\n} from '@metamask/keyring-api';\nimport {\n AccountCreationType,\n assertCreateAccountOptionIsSupported,\n EthAccountType,\n EthScope,\n} from '@metamask/keyring-api';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type {\n EthKeyring,\n InternalAccount,\n} from '@metamask/keyring-internal-api';\nimport { AccountId } from '@metamask/keyring-utils';\nimport type { Provider } from '@metamask/network-controller';\nimport { add0x, assert, bytesToHex, isStrictHexString } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\n\nimport {\n assertAreBip44Accounts,\n assertIsBip44Account,\n BaseBip44AccountProvider,\n} from './BaseBip44AccountProvider';\nimport { withRetry, withTimeout } from './utils';\nimport { traceFallback } from '../analytics';\nimport { TraceName } from '../analytics/traces';\nimport { projectLogger as log, WARNING_PREFIX } from '../logger';\nimport type { MultichainAccountServiceMessenger } from '../types';\n\nconst ETH_MAINNET_CHAIN_ID = '0x1';\n\n/**\n * Asserts an internal account exists.\n *\n * @param account - The internal account to check.\n * @throws An error if the internal account does not exist.\n */\nfunction assertInternalAccountExists(\n account: InternalAccount | undefined,\n): asserts account is InternalAccount {\n if (!account) {\n throw new Error('Internal account does not exist');\n }\n}\n\nexport type EvmAccountProviderConfig = {\n discovery: {\n enabled?: boolean;\n maxAttempts: number;\n timeoutMs: number;\n backOffMs: number;\n };\n};\n\nexport const EVM_ACCOUNT_PROVIDER_NAME = 'EVM';\n\nexport const EVM_ACCOUNT_PROVIDER_DEFAULT_CONFIG = {\n discovery: {\n maxAttempts: 3,\n timeoutMs: 500,\n backOffMs: 500,\n },\n};\n\nexport class EvmAccountProvider extends BaseBip44AccountProvider {\n static NAME = EVM_ACCOUNT_PROVIDER_NAME;\n\n readonly #config: EvmAccountProviderConfig;\n\n readonly #trace: TraceCallback;\n\n readonly capabilities: KeyringCapabilities = {\n scopes: [EthScope.Eoa],\n bip44: {\n deriveIndex: true,\n deriveIndexRange: true,\n },\n };\n\n constructor(\n messenger: MultichainAccountServiceMessenger,\n config: EvmAccountProviderConfig = EVM_ACCOUNT_PROVIDER_DEFAULT_CONFIG,\n trace?: TraceCallback,\n ) {\n super(messenger);\n this.#config = {\n ...config,\n discovery: {\n ...config.discovery,\n enabled: config.discovery.enabled ?? true,\n },\n };\n this.#trace = trace ?? traceFallback;\n }\n\n isAccountCompatible(account: Bip44Account<InternalAccount>): boolean {\n return (\n account.type === EthAccountType.Eoa &&\n account.metadata.keyring.type === (KeyringTypes.hd as string)\n );\n }\n\n getName(): string {\n return EvmAccountProvider.NAME;\n }\n\n /**\n * Get the EVM provider.\n *\n * @returns The EVM provider.\n */\n getEvmProvider(): Provider {\n const networkClientId = this.messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n ETH_MAINNET_CHAIN_ID,\n );\n const { provider } = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return provider;\n }\n\n /**\n * Get the account ID for an EVM account.\n *\n * Note: Since the account ID is deterministic at the AccountsController level,\n * we can use this method to get the account ID from the address.\n *\n * @param address - The address of the account.\n * @returns The account ID.\n */\n #getAccountId(address: Hex): string {\n return getUUIDFromAddressOfNormalAccount(address);\n }\n\n /**\n * Create an EVM account.\n *\n * @param opts - The options for the creation of the account.\n * @param opts.entropySource - The entropy source to use for the creation of the account.\n * @param opts.groupIndex - The index of the group to create the account for.\n * @param opts.throwOnGap - Whether to throw an error if the account index is not contiguous.\n * @returns The account ID and a boolean indicating if the account was created.\n */\n async #createAccount({\n entropySource,\n groupIndex,\n throwOnGap = false,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n throwOnGap?: boolean;\n }): Promise<[Hex, boolean]> {\n const result = await this.withKeyring<EthKeyring, [Hex, boolean]>(\n { id: entropySource },\n async ({ keyring }) => {\n const existing = await keyring.getAccounts();\n if (groupIndex < existing.length) {\n return [existing[groupIndex], false];\n }\n\n // If the throwOnGap flag is set, we throw an error to prevent index gaps.\n if (throwOnGap && groupIndex !== existing.length) {\n throw new Error('Trying to create too many accounts');\n }\n\n const [added] = await keyring.addAccounts(1);\n return [added, true];\n },\n );\n\n return result;\n }\n\n /**\n * Create accounts for the EVM provider.\n *\n * @param options - The options for the creation of the accounts.\n * @returns The accounts for the EVM provider.\n */\n async createAccounts(\n options: CreateAccountOptions,\n ): Promise<Bip44Account<KeyringAccount>[]> {\n assertCreateAccountOptionIsSupported(options, [\n `${AccountCreationType.Bip44DeriveIndex}`,\n `${AccountCreationType.Bip44DeriveIndexRange}`,\n ]);\n\n const { entropySource } = options;\n\n if (options.type === AccountCreationType.Bip44DeriveIndexRange) {\n const { range } = options;\n\n // Use a single withKeyring call for the entire range.\n const accountIds = await this.withKeyring<EthKeyring, AccountId[]>(\n { id: entropySource },\n async ({ keyring }) => {\n const existing = await keyring.getAccounts();\n\n // Validate no gaps: we can only create accounts starting from existing.length.\n if (range.from > existing.length) {\n throw new Error(\n `Bad account creation request, group index range would create gaps (${range.from} (from) > ${existing.length} (next available index))`,\n );\n }\n\n const result: AccountId[] = [];\n\n // Collect existing accounts within the range.\n for (\n let groupIndex = range.from;\n groupIndex <= range.to;\n groupIndex++\n ) {\n if (groupIndex < existing.length) {\n // Account already exists.\n result.push(this.#getAccountId(existing[groupIndex]));\n }\n }\n\n // Determine if we need to create new accounts.\n const from = Math.max(range.from, existing.length);\n if (from <= range.to) {\n // Calculate how many new accounts to create.\n const accountsToCreate = range.to - existing.length + 1;\n\n // Create all new accounts in one call.\n const newAccounts = await keyring.addAccounts(accountsToCreate);\n result.push(\n ...newAccounts.map((address) => this.#getAccountId(address)),\n );\n }\n\n return result;\n },\n );\n\n const accounts: InternalAccount[] = [];\n for (const account of this.messenger.call(\n 'AccountsController:getAccounts',\n accountIds,\n )) {\n assertInternalAccountExists(account);\n this.accounts.add(account.id);\n accounts.push(account);\n }\n\n assertAreBip44Accounts(accounts);\n return accounts;\n }\n\n // Handle Bip44DeriveIndex (single account creation).\n const { groupIndex } = options;\n\n const [address] = await this.#createAccount({\n entropySource,\n groupIndex,\n throwOnGap: true,\n });\n\n const accountId = this.#getAccountId(address);\n\n const account = this.messenger.call(\n 'AccountsController:getAccount',\n accountId,\n );\n\n // We MUST have the associated internal account.\n assertInternalAccountExists(account);\n\n const accountsArray = [account];\n assertAreBip44Accounts(accountsArray);\n\n this.accounts.add(account.id);\n return accountsArray;\n }\n\n /**\n * Get the transaction count for an EVM account.\n * This method uses a retry and timeout mechanism to handle transient failures.\n *\n * @param provider - The provider to use for the transaction count.\n * @param address - The address of the account.\n * @returns The transaction count.\n */\n async #getTransactionCount(\n provider: Provider,\n address: Hex,\n ): Promise<number> {\n const method = 'eth_getTransactionCount';\n\n const response = await withRetry(\n () =>\n withTimeout(\n () =>\n provider.request({\n method,\n params: [address, 'latest'],\n }),\n this.#config.discovery.timeoutMs,\n ),\n {\n maxAttempts: this.#config.discovery.maxAttempts,\n backOffMs: this.#config.discovery.backOffMs,\n },\n );\n\n // Make sure we got the right response format, if not, we fallback to \"0x0\", to avoid having to deal with `NaN`.\n if (!isStrictHexString(response)) {\n const message = `Received invalid hex response from \"${method}\" request: ${JSON.stringify(response)}`;\n\n log(`${WARNING_PREFIX} ${message}`);\n console.warn(message);\n\n return 0;\n }\n\n return parseInt(response, 16);\n }\n\n async #getAddressFromGroupIndex({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Hex> {\n // NOTE: To avoid exposing this function at keyring level, we just re-use its internal state\n // and compute the derivation here.\n return await this.withKeyring<HdKeyring, Hex>(\n { id: entropySource },\n async ({ keyring }) => {\n // If the account already exist, do not re-derive and just re-use that account.\n const existing = await keyring.getAccounts();\n if (groupIndex < existing.length) {\n return existing[groupIndex];\n }\n\n // If not, then we just \"peek\" the next address to avoid creating the account.\n assert(keyring.root, 'Expected HD keyring.root to be set');\n const hdKey = keyring.root.deriveChild(groupIndex);\n assert(hdKey.publicKey, 'Expected public key to be set');\n\n return add0x(\n bytesToHex(publicToAddress(hdKey.publicKey, true)).toLowerCase(),\n );\n },\n );\n }\n\n /**\n * Discover and create accounts for the EVM provider.\n *\n * @param opts - The options for the discovery and creation of accounts.\n * @param opts.entropySource - The entropy source to use for the discovery and creation of accounts.\n * @param opts.groupIndex - The index of the group to create the accounts for.\n * @returns The accounts for the EVM provider.\n */\n async discoverAccounts(opts: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n return this.#trace(\n {\n name: TraceName.EvmDiscoverAccounts,\n data: {\n provider: this.getName(),\n },\n },\n async () => {\n if (!this.#config.discovery.enabled) {\n return [];\n }\n\n const provider = this.getEvmProvider();\n const { entropySource, groupIndex } = opts;\n\n const addressFromGroupIndex = await this.#getAddressFromGroupIndex({\n entropySource,\n groupIndex,\n });\n\n const count = await this.#getTransactionCount(\n provider,\n addressFromGroupIndex,\n );\n if (count === 0) {\n return [];\n }\n\n // We have some activity on this address, we try to create the account.\n const [address] = await this.#createAccount({\n entropySource,\n groupIndex,\n });\n assert(\n addressFromGroupIndex === address,\n 'Created account does not match address from group index.',\n );\n\n const accoundId = this.#getAccountId(address);\n\n const account = this.messenger.call(\n 'AccountsController:getAccount',\n accoundId,\n );\n assertInternalAccountExists(account);\n assertIsBip44Account(account);\n this.accounts.add(account.id);\n return [account];\n },\n );\n }\n\n async resyncAccounts(): Promise<void> {\n // No-op for the EVM account provider, since keyring accounts are already on\n // the MetaMask side.\n }\n}\n"]}
1
+ {"version":3,"file":"EvmAccountProvider.cjs","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAmD;AASnD,uDAK+B;AAE/B,qEAA4D;AAI5D,2CAA+E;AAG/E,sDAA6C;AAC7C,oDAAgD;AAChD,0CAAiE;AAEjE,6EAIoC;AACpC,uCAAiD;AAEjD,MAAM,oBAAoB,GAAG,KAAK,CAAC;AAEnC;;;;;GAKG;AACH,SAAS,2BAA2B,CAClC,OAAoC;IAEpC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAWY,QAAA,yBAAyB,GAAG,KAAK,CAAC;AAElC,QAAA,mCAAmC,GAAG;IACjD,SAAS,EAAE;QACT,WAAW,EAAE,CAAC;QACd,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,GAAG;KACf;CACF,CAAC;AAEF,MAAa,kBAAmB,SAAQ,mDAAwB;IAe9D,YACE,SAA4C,EAC5C,SAAmC,2CAAmC,EACtE,KAAqB;QAErB,KAAK,CAAC,SAAS,CAAC,CAAC;;QAjBV,6CAAkC;QAElC,4CAAsB;QAEtB,iBAAY,GAAwB;YAC3C,MAAM,EAAE,CAAC,sBAAQ,CAAC,GAAG,CAAC;YACtB,KAAK,EAAE;gBACL,WAAW,EAAE,IAAI;gBACjB,gBAAgB,EAAE,IAAI;aACvB;SACF,CAAC;QAQA,uBAAA,IAAI,8BAAW;YACb,GAAG,MAAM;YACT,SAAS,EAAE;gBACT,GAAG,MAAM,CAAC,SAAS;gBACnB,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,OAAO,IAAI,IAAI;aAC1C;SACF,MAAA,CAAC;QACF,uBAAA,IAAI,6BAAU,KAAK,IAAI,yBAAa,MAAA,CAAC;IACvC,CAAC;IAED,mBAAmB,CAAC,OAAsC;QACxD,OAAO,CACL,OAAO,CAAC,IAAI,KAAK,4BAAc,CAAC,GAAG;YACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAM,iCAAY,CAAC,EAAa,CAC9D,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,kBAAkB,CAAC,IAAI,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,cAAc;QACZ,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CACzC,gDAAgD,EAChD,oBAAoB,CACrB,CAAC;QACF,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CACtC,wCAAwC,EACxC,eAAe,CAChB,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;IA2CD;;;;;OAKG;IACH,KAAK,CAAC,cAAc,CAClB,OAA6B;QAE7B,IAAA,kDAAoC,EAAC,OAAO,EAAE;YAC5C,GAAG,iCAAmB,CAAC,gBAAgB,EAAE;YACzC,GAAG,iCAAmB,CAAC,qBAAqB,EAAE;SAC/C,CAAC,CAAC;QAEH,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;QAElC,IAAI,OAAO,CAAC,IAAI,KAAK,iCAAmB,CAAC,qBAAqB,EAAE,CAAC;YAC/D,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;YAE1B,sDAAsD;YACtD,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,aAAa,CACzC,EAAE,EAAE,EAAE,aAAa,EAAE,EACrB,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBACpB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;gBAE7C,+EAA+E;gBAC/E,IAAI,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;oBACjC,MAAM,IAAI,KAAK,CACb,sEAAsE,KAAK,CAAC,IAAI,aAAa,QAAQ,CAAC,MAAM,0BAA0B,CACvI,CAAC;gBACJ,CAAC;gBAED,MAAM,MAAM,GAAgB,EAAE,CAAC;gBAE/B,8CAA8C;gBAC9C,KACE,IAAI,UAAU,GAAG,KAAK,CAAC,IAAI,EAC3B,UAAU,IAAI,KAAK,CAAC,EAAE,EACtB,UAAU,EAAE,EACZ,CAAC;oBACD,IAAI,UAAU,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;wBACjC,0BAA0B;wBAC1B,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC;oBACvC,CAAC;gBACH,CAAC;gBAED,iEAAiE;gBACjE,qDAAqD;gBACrD,KACE,IAAI,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,EACtD,UAAU,IAAI,KAAK,CAAC,EAAE,EACtB,UAAU,EAAE,EACZ,CAAC;oBACD,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC;wBAC7C,IAAI,EAAE,iCAAmB,CAAC,gBAAgB;wBAC1C,aAAa;wBACb,UAAU;qBACX,CAAC,CAAC;oBACH,IAAA,cAAM,EAAC,OAAO,EAAE,yBAAyB,CAAC,CAAC;oBAC3C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBAC1B,CAAC;gBAED,OAAO,MAAM,CAAC;YAChB,CAAC,CACF,CAAC;YAEF,MAAM,QAAQ,GAAsB,EAAE,CAAC;YACvC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CACvC,gCAAgC,EAChC,UAAU,CACX,EAAE,CAAC;gBACF,2BAA2B,CAAC,OAAO,CAAC,CAAC;gBACrC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBAC9B,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,CAAC;YAED,IAAA,iDAAsB,EAAC,QAAQ,CAAC,CAAC;YACjC,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,qDAAqD;QACrD,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;QAE/B,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,uBAAA,IAAI,wEAAe,MAAnB,IAAI,EAAgB;YAC1C,aAAa;YACb,UAAU;YACV,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;QAEH,IAAA,cAAM,EAAC,OAAO,EAAE,yBAAyB,CAAC,CAAC;QAE3C,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CACjC,+BAA+B,EAC/B,OAAO,CAAC,EAAE,CACX,CAAC;QAEF,gDAAgD;QAChD,2BAA2B,CAAC,OAAO,CAAC,CAAC;QAErC,MAAM,aAAa,GAAG,CAAC,OAAO,CAAC,CAAC;QAChC,IAAA,iDAAsB,EAAC,aAAa,CAAC,CAAC;QAEtC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC9B,OAAO,aAAa,CAAC;IACvB,CAAC;IAwFD;;;;;;;OAOG;IACH,KAAK,CAAC,gBAAgB,CAAC,IAGtB;QACC,OAAO,uBAAA,IAAI,iCAAO,MAAX,IAAI,EACT;YACE,IAAI,EAAE,kBAAS,CAAC,mBAAmB;YACnC,IAAI,EAAE;gBACJ,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE;aACzB;SACF,EACD,KAAK,IAAI,EAAE;YACT,IAAI,CAAC,uBAAA,IAAI,kCAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;gBACpC,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACvC,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;YAE3C,MAAM,qBAAqB,GAAG,MAAM,uBAAA,IAAI,mFAA0B,MAA9B,IAAI,EAA2B;gBACjE,aAAa;gBACb,UAAU;aACX,CAAC,CAAC;YAEH,MAAM,KAAK,GAAG,MAAM,uBAAA,IAAI,8EAAqB,MAAzB,IAAI,EACtB,QAAQ,EACR,qBAAqB,CACtB,CAAC;YACF,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBAChB,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,uEAAuE;YACvE,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,uBAAA,IAAI,wEAAe,MAAnB,IAAI,EAAgB;gBAC1C,aAAa;gBACb,UAAU;gBACV,UAAU,EAAE,KAAK;aAClB,CAAC,CAAC;YAEH,IAAA,cAAM,EAAC,OAAO,EAAE,yBAAyB,CAAC,CAAC;YAC3C,IAAA,cAAM,EACJ,qBAAqB,KAAK,OAAO,CAAC,OAAO,EACzC,0DAA0D,CAC3D,CAAC;YAEF,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CACjC,+BAA+B,EAC/B,OAAO,CAAC,EAAE,CACX,CAAC;YACF,2BAA2B,CAAC,OAAO,CAAC,CAAC;YACrC,IAAA,+CAAoB,EAAC,OAAO,CAAC,CAAC;YAC9B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC9B,OAAO,CAAC,OAAO,CAAC,CAAC;QACnB,CAAC,CACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,4EAA4E;QAC5E,qBAAqB;IACvB,CAAC;;AAxWH,gDAyWC;;AA9SC;;;;;;;;;GASG;AACH,KAAK,4CAAgB,EACnB,aAAa,EACb,UAAU,EACV,UAAU,GAKX;IACC,OAAO,MAAM,IAAI,CAAC,aAAa,CAC7B,EAAE,EAAE,EAAE,aAAa,EAAE,EACrB,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACpB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;QAC7C,IAAI,UAAU,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;YACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;QAChC,CAAC;QAED,0EAA0E;QAC1E,IAAI,UAAU,IAAI,UAAU,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,CAAC;QAED,OAAO,MAAM,OAAO,CAAC,cAAc,CAAC;YAClC,IAAI,EAAE,iCAAmB,CAAC,gBAAgB;YAC1C,aAAa;YACb,UAAU;SACX,CAAC,CAAC;IACL,CAAC,CACF,CAAC;AACJ,CAAC;AA4GD;;;;;;;;;;;;GAYG;AACH,KAAK,uDAA2B,EAC9B,aAAa,EACb,UAAU,GAIX;IACC,4FAA4F;IAC5F,mCAAmC;IACnC,OAAO,MAAM,IAAI,CAAC,aAAa,CAC7B,EAAE,EAAE,EAAE,aAAa,EAAE,EACrB,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACpB,+EAA+E;QAC/E,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;QAC7C,IAAI,UAAU,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;YACjC,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC,OAAc,CAAC;QAC7C,CAAC;QAED,8EAA8E;QAC9E,IAAA,cAAM,EAAC,OAAO,CAAC,IAAI,EAAE,oCAAoC,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QACnD,IAAA,cAAM,EAAC,KAAK,CAAC,SAAS,EAAE,+BAA+B,CAAC,CAAC;QAEzD,OAAO,IAAA,aAAK,EACV,IAAA,kBAAU,EAAC,IAAA,sBAAe,EAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CACjE,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,kDACH,QAAkB,EAClB,OAAe;IAEf,MAAM,MAAM,GAAG,yBAAyB,CAAC;IAEzC,MAAM,QAAQ,GAAG,MAAM,IAAA,iBAAS,EAC9B,GAAG,EAAE,CACH,IAAA,mBAAW,EACT,GAAG,EAAE,CACH,QAAQ,CAAC,OAAO,CAAC;QACf,MAAM;QACN,MAAM,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;KAC5B,CAAC,EACJ,uBAAA,IAAI,kCAAQ,CAAC,SAAS,CAAC,SAAS,CACjC,EACH;QACE,WAAW,EAAE,uBAAA,IAAI,kCAAQ,CAAC,SAAS,CAAC,WAAW;QAC/C,SAAS,EAAE,uBAAA,IAAI,kCAAQ,CAAC,SAAS,CAAC,SAAS;KAC5C,CACF,CAAC;IAEF,gHAAgH;IAChH,IAAI,CAAC,IAAA,yBAAiB,EAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,uCAAuC,MAAM,cAAc,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;QAEtG,IAAA,sBAAG,EAAC,GAAG,uBAAc,IAAI,OAAO,EAAE,CAAC,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEtB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAChC,CAAC;AAjSM,uBAAI,GAAG,iCAAyB,AAA5B,CAA6B","sourcesContent":["import { publicToAddress } from '@ethereumjs/util';\nimport type { Bip44Account } from '@metamask/account-api';\nimport type { TraceCallback } from '@metamask/controller-utils';\nimport type { HdKeyring } from '@metamask/eth-hd-keyring/v2';\nimport type {\n CreateAccountOptions,\n EntropySourceId,\n KeyringAccount,\n} from '@metamask/keyring-api';\nimport {\n AccountCreationType,\n assertCreateAccountOptionIsSupported,\n EthAccountType,\n EthScope,\n} from '@metamask/keyring-api';\nimport type { KeyringCapabilities, Keyring } from '@metamask/keyring-api/v2';\nimport { KeyringTypes } from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport { AccountId } from '@metamask/keyring-utils';\nimport type { Provider } from '@metamask/network-controller';\nimport { add0x, assert, bytesToHex, isStrictHexString } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\n\nimport { traceFallback } from '../analytics';\nimport { TraceName } from '../analytics/traces';\nimport { projectLogger as log, WARNING_PREFIX } from '../logger';\nimport type { MultichainAccountServiceMessenger } from '../types';\nimport {\n assertAreBip44Accounts,\n assertIsBip44Account,\n BaseBip44AccountProvider,\n} from './BaseBip44AccountProvider';\nimport { withRetry, withTimeout } from './utils';\n\nconst ETH_MAINNET_CHAIN_ID = '0x1';\n\n/**\n * Asserts an internal account exists.\n *\n * @param account - The internal account to check.\n * @throws An error if the internal account does not exist.\n */\nfunction assertInternalAccountExists(\n account: InternalAccount | undefined,\n): asserts account is InternalAccount {\n if (!account) {\n throw new Error('Internal account does not exist');\n }\n}\n\nexport type EvmAccountProviderConfig = {\n discovery: {\n enabled?: boolean;\n maxAttempts: number;\n timeoutMs: number;\n backOffMs: number;\n };\n};\n\nexport const EVM_ACCOUNT_PROVIDER_NAME = 'EVM';\n\nexport const EVM_ACCOUNT_PROVIDER_DEFAULT_CONFIG = {\n discovery: {\n maxAttempts: 3,\n timeoutMs: 500,\n backOffMs: 500,\n },\n};\n\nexport class EvmAccountProvider extends BaseBip44AccountProvider {\n static NAME = EVM_ACCOUNT_PROVIDER_NAME;\n\n readonly #config: EvmAccountProviderConfig;\n\n readonly #trace: TraceCallback;\n\n readonly capabilities: KeyringCapabilities = {\n scopes: [EthScope.Eoa],\n bip44: {\n deriveIndex: true,\n deriveIndexRange: true,\n },\n };\n\n constructor(\n messenger: MultichainAccountServiceMessenger,\n config: EvmAccountProviderConfig = EVM_ACCOUNT_PROVIDER_DEFAULT_CONFIG,\n trace?: TraceCallback,\n ) {\n super(messenger);\n this.#config = {\n ...config,\n discovery: {\n ...config.discovery,\n enabled: config.discovery.enabled ?? true,\n },\n };\n this.#trace = trace ?? traceFallback;\n }\n\n isAccountCompatible(account: Bip44Account<InternalAccount>): boolean {\n return (\n account.type === EthAccountType.Eoa &&\n account.metadata.keyring.type === (KeyringTypes.hd as string)\n );\n }\n\n getName(): string {\n return EvmAccountProvider.NAME;\n }\n\n /**\n * Get the EVM provider.\n *\n * @returns The EVM provider.\n */\n getEvmProvider(): Provider {\n const networkClientId = this.messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n ETH_MAINNET_CHAIN_ID,\n );\n const { provider } = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return provider;\n }\n\n /**\n * Create an EVM account.\n *\n * @param opts - The options for the creation of the account.\n * @param opts.entropySource - The entropy source to use for the creation of the account.\n * @param opts.groupIndex - The index of the group to create the account for.\n * @param opts.throwOnGap - Whether to throw an error if the account index is not contiguous.\n * @returns The created or existing keyring account(s) at the requested group\n * index. Returns an empty array if the keyring did not create an account.\n */\n async #createAccount({\n entropySource,\n groupIndex,\n throwOnGap,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n throwOnGap: boolean;\n }): Promise<KeyringAccount[]> {\n return await this.withKeyringV2<Keyring, KeyringAccount[]>(\n { id: entropySource },\n async ({ keyring }) => {\n const existing = await keyring.getAccounts();\n if (groupIndex < existing.length) {\n return [existing[groupIndex]];\n }\n\n // If the throwOnGap flag is set, we throw an error to prevent index gaps.\n if (throwOnGap && groupIndex !== existing.length) {\n throw new Error('Trying to create too many accounts');\n }\n\n return await keyring.createAccounts({\n type: AccountCreationType.Bip44DeriveIndex,\n entropySource,\n groupIndex,\n });\n },\n );\n }\n\n /**\n * Create accounts for the EVM provider.\n *\n * @param options - The options for the creation of the accounts.\n * @returns The accounts for the EVM provider.\n */\n async createAccounts(\n options: CreateAccountOptions,\n ): Promise<Bip44Account<KeyringAccount>[]> {\n assertCreateAccountOptionIsSupported(options, [\n `${AccountCreationType.Bip44DeriveIndex}`,\n `${AccountCreationType.Bip44DeriveIndexRange}`,\n ]);\n\n const { entropySource } = options;\n\n if (options.type === AccountCreationType.Bip44DeriveIndexRange) {\n const { range } = options;\n\n // Use a single withKeyring call for the entire range.\n const accountIds = await this.withKeyringV2<Keyring, AccountId[]>(\n { id: entropySource },\n async ({ keyring }) => {\n const existing = await keyring.getAccounts();\n\n // Validate no gaps: we can only create accounts starting from existing.length.\n if (range.from > existing.length) {\n throw new Error(\n `Bad account creation request, group index range would create gaps (${range.from} (from) > ${existing.length} (next available index))`,\n );\n }\n\n const result: AccountId[] = [];\n\n // Collect existing accounts within the range.\n for (\n let groupIndex = range.from;\n groupIndex <= range.to;\n groupIndex++\n ) {\n if (groupIndex < existing.length) {\n // Account already exists.\n result.push(existing[groupIndex].id);\n }\n }\n\n // Create new accounts one-by-one since HdKeyringV2 only supports\n // bip44:derive-index (not bip44:derive-index-range).\n for (\n let groupIndex = Math.max(range.from, existing.length);\n groupIndex <= range.to;\n groupIndex++\n ) {\n const [created] = await keyring.createAccounts({\n type: AccountCreationType.Bip44DeriveIndex,\n entropySource,\n groupIndex,\n });\n assert(created, 'Account creation failed');\n result.push(created.id);\n }\n\n return result;\n },\n );\n\n const accounts: InternalAccount[] = [];\n for (const account of this.messenger.call(\n 'AccountsController:getAccounts',\n accountIds,\n )) {\n assertInternalAccountExists(account);\n this.accounts.add(account.id);\n accounts.push(account);\n }\n\n assertAreBip44Accounts(accounts);\n return accounts;\n }\n\n // Handle Bip44DeriveIndex (single account creation).\n const { groupIndex } = options;\n\n const [created] = await this.#createAccount({\n entropySource,\n groupIndex,\n throwOnGap: true,\n });\n\n assert(created, 'Account creation failed');\n\n const account = this.messenger.call(\n 'AccountsController:getAccount',\n created.id,\n );\n\n // We MUST have the associated internal account.\n assertInternalAccountExists(account);\n\n const accountsArray = [account];\n assertAreBip44Accounts(accountsArray);\n\n this.accounts.add(account.id);\n return accountsArray;\n }\n\n /**\n * Get the address that would be derived for a given group index without\n * persisting an account in the keyring.\n *\n * Peeks at the next address via the HD `root` so discovery can short-circuit\n * (and skip the vault write + `stateChange` event) when there is no on-chain\n * activity at this index.\n *\n * @param opts - The options for the address derivation.\n * @param opts.entropySource - The entropy source to derive from.\n * @param opts.groupIndex - The group index to derive at.\n * @returns The derived address for the given group index.\n */\n async #getAddressFromGroupIndex({\n entropySource,\n groupIndex,\n }: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Hex> {\n // NOTE: To avoid exposing this function at keyring level, we just re-use its internal state\n // and compute the derivation here.\n return await this.withKeyringV2<HdKeyring, Hex>(\n { id: entropySource },\n async ({ keyring }) => {\n // If the account already exist, do not re-derive and just re-use that account.\n const existing = await keyring.getAccounts();\n if (groupIndex < existing.length) {\n return existing[groupIndex].address as Hex;\n }\n\n // If not, then we just \"peek\" the next address to avoid creating the account.\n assert(keyring.root, 'Expected HD keyring.root to be set');\n const hdKey = keyring.root.deriveChild(groupIndex);\n assert(hdKey.publicKey, 'Expected public key to be set');\n\n return add0x(\n bytesToHex(publicToAddress(hdKey.publicKey, true)).toLowerCase(),\n );\n },\n );\n }\n\n /**\n * Get the transaction count for an EVM account.\n * This method uses a retry and timeout mechanism to handle transient failures.\n *\n * @param provider - The provider to use for the transaction count.\n * @param address - The address of the account.\n * @returns The transaction count.\n */\n async #getTransactionCount(\n provider: Provider,\n address: string,\n ): Promise<number> {\n const method = 'eth_getTransactionCount';\n\n const response = await withRetry(\n () =>\n withTimeout(\n () =>\n provider.request({\n method,\n params: [address, 'latest'],\n }),\n this.#config.discovery.timeoutMs,\n ),\n {\n maxAttempts: this.#config.discovery.maxAttempts,\n backOffMs: this.#config.discovery.backOffMs,\n },\n );\n\n // Make sure we got the right response format, if not, we fallback to \"0x0\", to avoid having to deal with `NaN`.\n if (!isStrictHexString(response)) {\n const message = `Received invalid hex response from \"${method}\" request: ${JSON.stringify(response)}`;\n\n log(`${WARNING_PREFIX} ${message}`);\n console.warn(message);\n\n return 0;\n }\n\n return parseInt(response, 16);\n }\n\n /**\n * Discover and create accounts for the EVM provider.\n *\n * @param opts - The options for the discovery and creation of accounts.\n * @param opts.entropySource - The entropy source to use for the discovery and creation of accounts.\n * @param opts.groupIndex - The index of the group to create the accounts for.\n * @returns The accounts for the EVM provider.\n */\n async discoverAccounts(opts: {\n entropySource: EntropySourceId;\n groupIndex: number;\n }): Promise<Bip44Account<KeyringAccount>[]> {\n return this.#trace(\n {\n name: TraceName.EvmDiscoverAccounts,\n data: {\n provider: this.getName(),\n },\n },\n async () => {\n if (!this.#config.discovery.enabled) {\n return [];\n }\n\n const provider = this.getEvmProvider();\n const { entropySource, groupIndex } = opts;\n\n const addressFromGroupIndex = await this.#getAddressFromGroupIndex({\n entropySource,\n groupIndex,\n });\n\n const count = await this.#getTransactionCount(\n provider,\n addressFromGroupIndex,\n );\n if (count === 0) {\n return [];\n }\n\n // We have some activity on this address, we try to create the account.\n const [created] = await this.#createAccount({\n entropySource,\n groupIndex,\n throwOnGap: false,\n });\n\n assert(created, 'Account creation failed');\n assert(\n addressFromGroupIndex === created.address,\n 'Created account does not match address from group index.',\n );\n\n const account = this.messenger.call(\n 'AccountsController:getAccount',\n created.id,\n );\n assertInternalAccountExists(account);\n assertIsBip44Account(account);\n this.accounts.add(account.id);\n return [account];\n },\n );\n }\n\n async resyncAccounts(): Promise<void> {\n // No-op for the EVM account provider, since keyring accounts are already on\n // the MetaMask side.\n }\n}\n"]}
@@ -1,10 +1,11 @@
1
1
  import type { Bip44Account } from "@metamask/account-api";
2
2
  import type { TraceCallback } from "@metamask/controller-utils";
3
- import type { CreateAccountOptions, EntropySourceId, KeyringAccount, KeyringCapabilities } from "@metamask/keyring-api";
3
+ import type { CreateAccountOptions, EntropySourceId, KeyringAccount } from "@metamask/keyring-api";
4
+ import type { KeyringCapabilities } from "@metamask/keyring-api/v2";
4
5
  import type { InternalAccount } from "@metamask/keyring-internal-api";
5
6
  import type { Provider } from "@metamask/network-controller";
6
- import { BaseBip44AccountProvider } from "./BaseBip44AccountProvider.cjs";
7
7
  import type { MultichainAccountServiceMessenger } from "../types.cjs";
8
+ import { BaseBip44AccountProvider } from "./BaseBip44AccountProvider.cjs";
8
9
  export type EvmAccountProviderConfig = {
9
10
  discovery: {
10
11
  enabled?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"EvmAccountProvider.d.cts","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,mCAAmC;AAEhE,OAAO,KAAK,EACV,oBAAoB,EACpB,eAAe,EACf,cAAc,EACd,mBAAmB,EACpB,8BAA8B;AAQ/B,OAAO,KAAK,EAEV,eAAe,EAChB,uCAAuC;AAExC,OAAO,KAAK,EAAE,QAAQ,EAAE,qCAAqC;AAI7D,OAAO,EAGL,wBAAwB,EACzB,uCAAmC;AAKpC,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAkBlE,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE;QACT,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAAQ,CAAC;AAE/C,eAAO,MAAM,mCAAmC;;;;;;CAM/C,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,wBAAwB;;IAC9D,MAAM,CAAC,IAAI,SAA6B;IAMxC,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAMxC;gBAGA,SAAS,EAAE,iCAAiC,EAC5C,MAAM,GAAE,wBAA8D,EACtE,KAAK,CAAC,EAAE,aAAa;IAavB,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC,GAAG,OAAO;IAOpE,OAAO,IAAI,MAAM;IAIjB;;;;OAIG;IACH,cAAc,IAAI,QAAQ;IAgE1B;;;;;OAKG;IACG,cAAc,CAClB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAwK1C;;;;;;;OAOG;IACG,gBAAgB,CAAC,IAAI,EAAE;QAC3B,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAqDrC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAItC"}
1
+ {"version":3,"file":"EvmAccountProvider.d.cts","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,mCAAmC;AAEhE,OAAO,KAAK,EACV,oBAAoB,EACpB,eAAe,EACf,cAAc,EACf,8BAA8B;AAO/B,OAAO,KAAK,EAAE,mBAAmB,EAAW,iCAAiC;AAE7E,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAEtE,OAAO,KAAK,EAAE,QAAQ,EAAE,qCAAqC;AAO7D,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAClE,OAAO,EAGL,wBAAwB,EACzB,uCAAmC;AAmBpC,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE;QACT,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAAQ,CAAC;AAE/C,eAAO,MAAM,mCAAmC;;;;;;CAM/C,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,wBAAwB;;IAC9D,MAAM,CAAC,IAAI,SAA6B;IAMxC,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAMxC;gBAGA,SAAS,EAAE,iCAAiC,EAC5C,MAAM,GAAE,wBAA8D,EACtE,KAAK,CAAC,EAAE,aAAa;IAavB,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC,GAAG,OAAO;IAOpE,OAAO,IAAI,MAAM;IAIjB;;;;OAIG;IACH,cAAc,IAAI,QAAQ;IAqD1B;;;;;OAKG;IACG,cAAc,CAClB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAwL1C;;;;;;;OAOG;IACG,gBAAgB,CAAC,IAAI,EAAE;QAC3B,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAsDrC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAItC"}
@@ -1,10 +1,11 @@
1
1
  import type { Bip44Account } from "@metamask/account-api";
2
2
  import type { TraceCallback } from "@metamask/controller-utils";
3
- import type { CreateAccountOptions, EntropySourceId, KeyringAccount, KeyringCapabilities } from "@metamask/keyring-api";
3
+ import type { CreateAccountOptions, EntropySourceId, KeyringAccount } from "@metamask/keyring-api";
4
+ import type { KeyringCapabilities } from "@metamask/keyring-api/v2";
4
5
  import type { InternalAccount } from "@metamask/keyring-internal-api";
5
6
  import type { Provider } from "@metamask/network-controller";
6
- import { BaseBip44AccountProvider } from "./BaseBip44AccountProvider.mjs";
7
7
  import type { MultichainAccountServiceMessenger } from "../types.mjs";
8
+ import { BaseBip44AccountProvider } from "./BaseBip44AccountProvider.mjs";
8
9
  export type EvmAccountProviderConfig = {
9
10
  discovery: {
10
11
  enabled?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"EvmAccountProvider.d.mts","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,mCAAmC;AAEhE,OAAO,KAAK,EACV,oBAAoB,EACpB,eAAe,EACf,cAAc,EACd,mBAAmB,EACpB,8BAA8B;AAQ/B,OAAO,KAAK,EAEV,eAAe,EAChB,uCAAuC;AAExC,OAAO,KAAK,EAAE,QAAQ,EAAE,qCAAqC;AAI7D,OAAO,EAGL,wBAAwB,EACzB,uCAAmC;AAKpC,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAkBlE,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE;QACT,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAAQ,CAAC;AAE/C,eAAO,MAAM,mCAAmC;;;;;;CAM/C,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,wBAAwB;;IAC9D,MAAM,CAAC,IAAI,SAA6B;IAMxC,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAMxC;gBAGA,SAAS,EAAE,iCAAiC,EAC5C,MAAM,GAAE,wBAA8D,EACtE,KAAK,CAAC,EAAE,aAAa;IAavB,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC,GAAG,OAAO;IAOpE,OAAO,IAAI,MAAM;IAIjB;;;;OAIG;IACH,cAAc,IAAI,QAAQ;IAgE1B;;;;;OAKG;IACG,cAAc,CAClB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAwK1C;;;;;;;OAOG;IACG,gBAAgB,CAAC,IAAI,EAAE;QAC3B,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAqDrC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAItC"}
1
+ {"version":3,"file":"EvmAccountProvider.d.mts","sourceRoot":"","sources":["../../src/providers/EvmAccountProvider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,mCAAmC;AAEhE,OAAO,KAAK,EACV,oBAAoB,EACpB,eAAe,EACf,cAAc,EACf,8BAA8B;AAO/B,OAAO,KAAK,EAAE,mBAAmB,EAAW,iCAAiC;AAE7E,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AAEtE,OAAO,KAAK,EAAE,QAAQ,EAAE,qCAAqC;AAO7D,OAAO,KAAK,EAAE,iCAAiC,EAAE,qBAAiB;AAClE,OAAO,EAGL,wBAAwB,EACzB,uCAAmC;AAmBpC,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE;QACT,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAAQ,CAAC;AAE/C,eAAO,MAAM,mCAAmC;;;;;;CAM/C,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,wBAAwB;;IAC9D,MAAM,CAAC,IAAI,SAA6B;IAMxC,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAMxC;gBAGA,SAAS,EAAE,iCAAiC,EAC5C,MAAM,GAAE,wBAA8D,EACtE,KAAK,CAAC,EAAE,aAAa;IAavB,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,eAAe,CAAC,GAAG,OAAO;IAOpE,OAAO,IAAI,MAAM;IAIjB;;;;OAIG;IACH,cAAc,IAAI,QAAQ;IAqD1B;;;;;OAKG;IACG,cAAc,CAClB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAwL1C;;;;;;;OAOG;IACG,gBAAgB,CAAC,IAAI,EAAE;QAC3B,aAAa,EAAE,eAAe,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAsDrC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAItC"}
@@ -9,17 +9,16 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _EvmAccountProvider_instances, _EvmAccountProvider_config, _EvmAccountProvider_trace, _EvmAccountProvider_getAccountId, _EvmAccountProvider_createAccount, _EvmAccountProvider_getTransactionCount, _EvmAccountProvider_getAddressFromGroupIndex;
12
+ var _EvmAccountProvider_instances, _EvmAccountProvider_config, _EvmAccountProvider_trace, _EvmAccountProvider_createAccount, _EvmAccountProvider_getAddressFromGroupIndex, _EvmAccountProvider_getTransactionCount;
13
13
  import { publicToAddress } from "@ethereumjs/util";
14
- import { getUUIDFromAddressOfNormalAccount } from "@metamask/accounts-controller";
15
14
  import { AccountCreationType, assertCreateAccountOptionIsSupported, EthAccountType, EthScope } from "@metamask/keyring-api";
16
15
  import { KeyringTypes } from "@metamask/keyring-controller";
17
16
  import { add0x, assert, bytesToHex, isStrictHexString } from "@metamask/utils";
18
- import { assertAreBip44Accounts, assertIsBip44Account, BaseBip44AccountProvider } from "./BaseBip44AccountProvider.mjs";
19
- import { withRetry, withTimeout } from "./utils.mjs";
20
17
  import { traceFallback } from "../analytics/index.mjs";
21
18
  import { TraceName } from "../analytics/traces.mjs";
22
19
  import { projectLogger as log, WARNING_PREFIX } from "../logger.mjs";
20
+ import { assertAreBip44Accounts, assertIsBip44Account, BaseBip44AccountProvider } from "./BaseBip44AccountProvider.mjs";
21
+ import { withRetry, withTimeout } from "./utils.mjs";
23
22
  const ETH_MAINNET_CHAIN_ID = '0x1';
24
23
  /**
25
24
  * Asserts an internal account exists.
@@ -94,7 +93,7 @@ export class EvmAccountProvider extends BaseBip44AccountProvider {
94
93
  if (options.type === AccountCreationType.Bip44DeriveIndexRange) {
95
94
  const { range } = options;
96
95
  // Use a single withKeyring call for the entire range.
97
- const accountIds = await this.withKeyring({ id: entropySource }, async ({ keyring }) => {
96
+ const accountIds = await this.withKeyringV2({ id: entropySource }, async ({ keyring }) => {
98
97
  const existing = await keyring.getAccounts();
99
98
  // Validate no gaps: we can only create accounts starting from existing.length.
100
99
  if (range.from > existing.length) {
@@ -105,17 +104,19 @@ export class EvmAccountProvider extends BaseBip44AccountProvider {
105
104
  for (let groupIndex = range.from; groupIndex <= range.to; groupIndex++) {
106
105
  if (groupIndex < existing.length) {
107
106
  // Account already exists.
108
- result.push(__classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_getAccountId).call(this, existing[groupIndex]));
107
+ result.push(existing[groupIndex].id);
109
108
  }
110
109
  }
111
- // Determine if we need to create new accounts.
112
- const from = Math.max(range.from, existing.length);
113
- if (from <= range.to) {
114
- // Calculate how many new accounts to create.
115
- const accountsToCreate = range.to - existing.length + 1;
116
- // Create all new accounts in one call.
117
- const newAccounts = await keyring.addAccounts(accountsToCreate);
118
- result.push(...newAccounts.map((address) => __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_getAccountId).call(this, address)));
110
+ // Create new accounts one-by-one since HdKeyringV2 only supports
111
+ // bip44:derive-index (not bip44:derive-index-range).
112
+ for (let groupIndex = Math.max(range.from, existing.length); groupIndex <= range.to; groupIndex++) {
113
+ const [created] = await keyring.createAccounts({
114
+ type: AccountCreationType.Bip44DeriveIndex,
115
+ entropySource,
116
+ groupIndex,
117
+ });
118
+ assert(created, 'Account creation failed');
119
+ result.push(created.id);
119
120
  }
120
121
  return result;
121
122
  });
@@ -130,13 +131,13 @@ export class EvmAccountProvider extends BaseBip44AccountProvider {
130
131
  }
131
132
  // Handle Bip44DeriveIndex (single account creation).
132
133
  const { groupIndex } = options;
133
- const [address] = await __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_createAccount).call(this, {
134
+ const [created] = await __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_createAccount).call(this, {
134
135
  entropySource,
135
136
  groupIndex,
136
137
  throwOnGap: true,
137
138
  });
138
- const accountId = __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_getAccountId).call(this, address);
139
- const account = this.messenger.call('AccountsController:getAccount', accountId);
139
+ assert(created, 'Account creation failed');
140
+ const account = this.messenger.call('AccountsController:getAccount', created.id);
140
141
  // We MUST have the associated internal account.
141
142
  assertInternalAccountExists(account);
142
143
  const accountsArray = [account];
@@ -173,13 +174,14 @@ export class EvmAccountProvider extends BaseBip44AccountProvider {
173
174
  return [];
174
175
  }
175
176
  // We have some activity on this address, we try to create the account.
176
- const [address] = await __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_createAccount).call(this, {
177
+ const [created] = await __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_createAccount).call(this, {
177
178
  entropySource,
178
179
  groupIndex,
180
+ throwOnGap: false,
179
181
  });
180
- assert(addressFromGroupIndex === address, 'Created account does not match address from group index.');
181
- const accoundId = __classPrivateFieldGet(this, _EvmAccountProvider_instances, "m", _EvmAccountProvider_getAccountId).call(this, address);
182
- const account = this.messenger.call('AccountsController:getAccount', accoundId);
182
+ assert(created, 'Account creation failed');
183
+ assert(addressFromGroupIndex === created.address, 'Created account does not match address from group index.');
184
+ const account = this.messenger.call('AccountsController:getAccount', created.id);
183
185
  assertInternalAccountExists(account);
184
186
  assertIsBip44Account(account);
185
187
  this.accounts.add(account.id);
@@ -191,9 +193,7 @@ export class EvmAccountProvider extends BaseBip44AccountProvider {
191
193
  // the MetaMask side.
192
194
  }
193
195
  }
194
- _EvmAccountProvider_config = new WeakMap(), _EvmAccountProvider_trace = new WeakMap(), _EvmAccountProvider_instances = new WeakSet(), _EvmAccountProvider_getAccountId = function _EvmAccountProvider_getAccountId(address) {
195
- return getUUIDFromAddressOfNormalAccount(address);
196
- }, _EvmAccountProvider_createAccount =
196
+ _EvmAccountProvider_config = new WeakMap(), _EvmAccountProvider_trace = new WeakMap(), _EvmAccountProvider_instances = new WeakSet(), _EvmAccountProvider_createAccount =
197
197
  /**
198
198
  * Create an EVM account.
199
199
  *
@@ -201,22 +201,54 @@ _EvmAccountProvider_config = new WeakMap(), _EvmAccountProvider_trace = new Weak
201
201
  * @param opts.entropySource - The entropy source to use for the creation of the account.
202
202
  * @param opts.groupIndex - The index of the group to create the account for.
203
203
  * @param opts.throwOnGap - Whether to throw an error if the account index is not contiguous.
204
- * @returns The account ID and a boolean indicating if the account was created.
204
+ * @returns The created or existing keyring account(s) at the requested group
205
+ * index. Returns an empty array if the keyring did not create an account.
205
206
  */
206
- async function _EvmAccountProvider_createAccount({ entropySource, groupIndex, throwOnGap = false, }) {
207
- const result = await this.withKeyring({ id: entropySource }, async ({ keyring }) => {
207
+ async function _EvmAccountProvider_createAccount({ entropySource, groupIndex, throwOnGap, }) {
208
+ return await this.withKeyringV2({ id: entropySource }, async ({ keyring }) => {
208
209
  const existing = await keyring.getAccounts();
209
210
  if (groupIndex < existing.length) {
210
- return [existing[groupIndex], false];
211
+ return [existing[groupIndex]];
211
212
  }
212
213
  // If the throwOnGap flag is set, we throw an error to prevent index gaps.
213
214
  if (throwOnGap && groupIndex !== existing.length) {
214
215
  throw new Error('Trying to create too many accounts');
215
216
  }
216
- const [added] = await keyring.addAccounts(1);
217
- return [added, true];
217
+ return await keyring.createAccounts({
218
+ type: AccountCreationType.Bip44DeriveIndex,
219
+ entropySource,
220
+ groupIndex,
221
+ });
222
+ });
223
+ }, _EvmAccountProvider_getAddressFromGroupIndex =
224
+ /**
225
+ * Get the address that would be derived for a given group index without
226
+ * persisting an account in the keyring.
227
+ *
228
+ * Peeks at the next address via the HD `root` so discovery can short-circuit
229
+ * (and skip the vault write + `stateChange` event) when there is no on-chain
230
+ * activity at this index.
231
+ *
232
+ * @param opts - The options for the address derivation.
233
+ * @param opts.entropySource - The entropy source to derive from.
234
+ * @param opts.groupIndex - The group index to derive at.
235
+ * @returns The derived address for the given group index.
236
+ */
237
+ async function _EvmAccountProvider_getAddressFromGroupIndex({ entropySource, groupIndex, }) {
238
+ // NOTE: To avoid exposing this function at keyring level, we just re-use its internal state
239
+ // and compute the derivation here.
240
+ return await this.withKeyringV2({ id: entropySource }, async ({ keyring }) => {
241
+ // If the account already exist, do not re-derive and just re-use that account.
242
+ const existing = await keyring.getAccounts();
243
+ if (groupIndex < existing.length) {
244
+ return existing[groupIndex].address;
245
+ }
246
+ // If not, then we just "peek" the next address to avoid creating the account.
247
+ assert(keyring.root, 'Expected HD keyring.root to be set');
248
+ const hdKey = keyring.root.deriveChild(groupIndex);
249
+ assert(hdKey.publicKey, 'Expected public key to be set');
250
+ return add0x(bytesToHex(publicToAddress(hdKey.publicKey, true)).toLowerCase());
218
251
  });
219
- return result;
220
252
  }, _EvmAccountProvider_getTransactionCount =
221
253
  /**
222
254
  * Get the transaction count for an EVM account.
@@ -243,21 +275,6 @@ async function _EvmAccountProvider_getTransactionCount(provider, address) {
243
275
  return 0;
244
276
  }
245
277
  return parseInt(response, 16);
246
- }, _EvmAccountProvider_getAddressFromGroupIndex = async function _EvmAccountProvider_getAddressFromGroupIndex({ entropySource, groupIndex, }) {
247
- // NOTE: To avoid exposing this function at keyring level, we just re-use its internal state
248
- // and compute the derivation here.
249
- return await this.withKeyring({ id: entropySource }, async ({ keyring }) => {
250
- // If the account already exist, do not re-derive and just re-use that account.
251
- const existing = await keyring.getAccounts();
252
- if (groupIndex < existing.length) {
253
- return existing[groupIndex];
254
- }
255
- // If not, then we just "peek" the next address to avoid creating the account.
256
- assert(keyring.root, 'Expected HD keyring.root to be set');
257
- const hdKey = keyring.root.deriveChild(groupIndex);
258
- assert(hdKey.publicKey, 'Expected public key to be set');
259
- return add0x(bytesToHex(publicToAddress(hdKey.publicKey, true)).toLowerCase());
260
- });
261
278
  };
262
279
  EvmAccountProvider.NAME = EVM_ACCOUNT_PROVIDER_NAME;
263
280
  //# sourceMappingURL=EvmAccountProvider.mjs.map