Skip to content

feat(account-api): add multichain accounts support #302

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

ccharly
Copy link
Contributor

@ccharly ccharly commented Jun 26, 2025

Draft implementation of the new multichain accounts API and some adapters around it to help with the integration.

@ccharly
Copy link
Contributor Author

ccharly commented Jun 26, 2025

@metamaskbot publish-preview

Copy link

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/keyring-api": "18.0.0-4ea0942",
  "@metamask-previews/eth-hd-keyring": "12.1.0-4ea0942",
  "@metamask-previews/eth-ledger-bridge-keyring": "11.1.0-4ea0942",
  "@metamask-previews/eth-simple-keyring": "10.0.0-4ea0942",
  "@metamask-previews/eth-trezor-keyring": "8.0.0-4ea0942",
  "@metamask-previews/keyring-internal-api": "6.2.0-4ea0942",
  "@metamask-previews/keyring-internal-snap-client": "4.1.0-4ea0942",
  "@metamask-previews/eth-snap-keyring": "13.0.0-4ea0942",
  "@metamask-previews/keyring-snap-client": "5.0.0-4ea0942",
  "@metamask-previews/keyring-snap-sdk": "4.0.0-4ea0942",
  "@metamask-previews/keyring-utils": "3.0.0-4ea0942",
  "@metamask-previews/multichain-account-api": "0.0.0-4ea0942"
}

@ccharly
Copy link
Contributor Author

ccharly commented Jun 26, 2025

@metamaskbot publish-preview

Copy link

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/keyring-api": "18.0.0-363355f",
  "@metamask-previews/eth-hd-keyring": "12.1.0-363355f",
  "@metamask-previews/eth-ledger-bridge-keyring": "11.1.0-363355f",
  "@metamask-previews/eth-simple-keyring": "10.0.0-363355f",
  "@metamask-previews/eth-trezor-keyring": "8.0.0-363355f",
  "@metamask-previews/keyring-internal-api": "6.2.0-363355f",
  "@metamask-previews/keyring-internal-snap-client": "4.1.0-363355f",
  "@metamask-previews/eth-snap-keyring": "13.0.0-363355f",
  "@metamask-previews/keyring-snap-client": "5.0.0-363355f",
  "@metamask-previews/keyring-snap-sdk": "4.0.0-363355f",
  "@metamask-previews/keyring-utils": "3.0.0-363355f",
  "@metamask-previews/multichain-account-api": "0.0.0-363355f"
}

@ccharly
Copy link
Contributor Author

ccharly commented Jun 26, 2025

@metamaskbot publish-preview

Copy link

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/keyring-api": "18.0.0-af0f0b2",
  "@metamask-previews/eth-hd-keyring": "12.1.0-af0f0b2",
  "@metamask-previews/eth-ledger-bridge-keyring": "11.1.0-af0f0b2",
  "@metamask-previews/eth-simple-keyring": "10.0.0-af0f0b2",
  "@metamask-previews/eth-trezor-keyring": "8.0.0-af0f0b2",
  "@metamask-previews/keyring-internal-api": "6.2.0-af0f0b2",
  "@metamask-previews/keyring-internal-snap-client": "4.1.0-af0f0b2",
  "@metamask-previews/eth-snap-keyring": "13.0.0-af0f0b2",
  "@metamask-previews/keyring-snap-client": "5.0.0-af0f0b2",
  "@metamask-previews/keyring-snap-sdk": "4.0.0-af0f0b2",
  "@metamask-previews/keyring-utils": "3.0.0-af0f0b2",
  "@metamask-previews/multichain-account-api": "0.0.0-af0f0b2"
}

@ccharly
Copy link
Contributor Author

ccharly commented Jul 3, 2025

@metamaskbot publish-preview

Copy link

github-actions bot commented Jul 3, 2025

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/keyring-api": "18.0.0-423d1ff",
  "@metamask-previews/eth-hd-keyring": "12.1.0-423d1ff",
  "@metamask-previews/eth-ledger-bridge-keyring": "11.1.0-423d1ff",
  "@metamask-previews/eth-simple-keyring": "10.0.0-423d1ff",
  "@metamask-previews/eth-trezor-keyring": "8.0.0-423d1ff",
  "@metamask-previews/keyring-internal-api": "6.2.0-423d1ff",
  "@metamask-previews/keyring-internal-snap-client": "4.1.0-423d1ff",
  "@metamask-previews/eth-snap-keyring": "13.0.0-423d1ff",
  "@metamask-previews/keyring-snap-client": "5.0.0-423d1ff",
  "@metamask-previews/keyring-snap-sdk": "4.0.0-423d1ff",
  "@metamask-previews/keyring-utils": "3.0.0-423d1ff",
  "@metamask-previews/multichain-account-api": "0.0.0-423d1ff"
}

@ccharly ccharly force-pushed the feat/multichain-accounts-api branch from 327416e to daddb4b Compare July 3, 2025 13:13
@ccharly
Copy link
Contributor Author

ccharly commented Jul 3, 2025

@metamaskbot publish-preview

Copy link

github-actions bot commented Jul 3, 2025

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/keyring-api": "18.0.0-daddb4b",
  "@metamask-previews/eth-hd-keyring": "12.1.0-daddb4b",
  "@metamask-previews/eth-ledger-bridge-keyring": "11.1.0-daddb4b",
  "@metamask-previews/eth-simple-keyring": "10.0.0-daddb4b",
  "@metamask-previews/eth-trezor-keyring": "8.0.0-daddb4b",
  "@metamask-previews/keyring-internal-api": "6.2.0-daddb4b",
  "@metamask-previews/keyring-internal-snap-client": "4.1.0-daddb4b",
  "@metamask-previews/eth-snap-keyring": "13.0.0-daddb4b",
  "@metamask-previews/keyring-snap-client": "5.0.0-daddb4b",
  "@metamask-previews/keyring-snap-sdk": "4.0.0-daddb4b",
  "@metamask-previews/keyring-utils": "3.0.0-daddb4b",
  "@metamask-previews/multichain-account-api": "0.0.0-daddb4b"
}

@ccharly
Copy link
Contributor Author

ccharly commented Jul 4, 2025

@metamaskbot publish-preview

Copy link

github-actions bot commented Jul 4, 2025

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/keyring-api": "18.0.0-6481f0d",
  "@metamask-previews/eth-hd-keyring": "12.1.0-6481f0d",
  "@metamask-previews/eth-ledger-bridge-keyring": "11.1.0-6481f0d",
  "@metamask-previews/eth-simple-keyring": "10.0.0-6481f0d",
  "@metamask-previews/eth-trezor-keyring": "8.0.0-6481f0d",
  "@metamask-previews/keyring-internal-api": "6.2.0-6481f0d",
  "@metamask-previews/keyring-internal-snap-client": "4.1.0-6481f0d",
  "@metamask-previews/eth-snap-keyring": "13.0.0-6481f0d",
  "@metamask-previews/keyring-snap-client": "5.0.0-6481f0d",
  "@metamask-previews/keyring-snap-sdk": "4.0.0-6481f0d",
  "@metamask-previews/keyring-utils": "3.0.0-6481f0d",
  "@metamask-previews/multichain-account-api": "0.0.0-6481f0d"
}

@ccharly
Copy link
Contributor Author

ccharly commented Jul 4, 2025

@metamaskbot publish-preview

Copy link

github-actions bot commented Jul 4, 2025

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/keyring-api": "18.0.0-5ab4699",
  "@metamask-previews/eth-hd-keyring": "12.1.0-5ab4699",
  "@metamask-previews/eth-ledger-bridge-keyring": "11.1.0-5ab4699",
  "@metamask-previews/eth-simple-keyring": "10.0.0-5ab4699",
  "@metamask-previews/eth-trezor-keyring": "8.0.0-5ab4699",
  "@metamask-previews/keyring-internal-api": "6.2.0-5ab4699",
  "@metamask-previews/keyring-internal-snap-client": "4.1.0-5ab4699",
  "@metamask-previews/eth-snap-keyring": "13.0.0-5ab4699",
  "@metamask-previews/keyring-snap-client": "5.0.0-5ab4699",
  "@metamask-previews/keyring-snap-sdk": "4.0.0-5ab4699",
  "@metamask-previews/keyring-utils": "3.0.0-5ab4699",
  "@metamask-previews/multichain-account-api": "0.0.0-5ab4699"
}

@ccharly ccharly marked this pull request as ready for review July 9, 2025 16:15
@ccharly ccharly requested review from a team as code owners July 9, 2025 16:15
cursor[bot]

This comment was marked as outdated.

Comment on lines 249 to 288
do {
// New index means new accounts.
accounts = [];

const missingProviders = [];
for (const provider of this.#providers) {
const discoveredAccounts = await provider.discoverAndCreateAccounts({
entropySource: this.#entropySource,
groupIndex,
});

if (discoveredAccounts.length) {
// This provider has discovered and created accounts, meaning there might
// be something to discover on the next index.
accounts = discoveredAccounts;
} else {
// This provider did not discover or create any accounts. We mark it as
// "missing", so we can create accounts on this index if other providers
// did discover something.
missingProviders.push(provider);
}
}

if (accounts.length) {
// We only create missing accounts if one of the provider has discovered
// and created accounts.
for (const provider of missingProviders) {
await provider.createAccounts({
entropySource: this.#entropySource,
groupIndex,
});
}

// We've got all the accounts now, we can create our multichain account.
multichainAccounts.push(this.#createMultichainAccount(groupIndex));

// We have accounts, we need to check the next index.
groupIndex += 1;
}
} while (accounts.length);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Maybe we should just run discovery with the providers that HAS discovered something? (e.g Provider1 found something on index 0, but Provider2 did not, then we continue with index 1 for Provider1 but without Provider2?

If we do that, then we can use the "alignment mechanism" at the end of the discovery to re-align all accounts accross the multichain account.

Comment on lines 224 to 229
for (const provider of this.#providers) {
await provider.createAccounts({
entropySource: this.#entropySource,
groupIndex,
});
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to async/parallel.

Comment on lines 7 to 10
getAccounts: (opts: {
entropySource: EntropySourceId;
groupIndex: number;
}) => AccountId[];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we make this async too? The main problem here would be that a MultichainAccount would need a async init() method too, because constructor cannot be async.

That was one of my initial pattern, and to make it easier to use, I introduced a static from(...) class method to be able to construct + init in one go.

If getAccounts is meant to be "wired up" to the keyring API {get,list}Accounts method, then yes, we might need to make it async. However, we could also keep a copy KeyringAccounts into each keyring instances on the client side, this way we can just use the copies and not "fetch" the accounts from the Snap itself, making it a "sync" call (similar to how AccountsController:listMultichainAccounts works today).

Comment on lines 275 to 280
for (const provider of missingProviders) {
await provider.createAccounts({
entropySource: this.#entropySource,
groupIndex,
});
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to async/parallel.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

@ccharly
Copy link
Contributor Author

ccharly commented Jul 10, 2025

@metamaskbot publish-preview

Copy link

Preview builds have been published. See these instructions (from the core monorepo) for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-api": "0.0.0-586437b",
  "@metamask-previews/keyring-api": "18.0.0-586437b",
  "@metamask-previews/eth-hd-keyring": "12.1.0-586437b",
  "@metamask-previews/eth-ledger-bridge-keyring": "11.1.0-586437b",
  "@metamask-previews/eth-simple-keyring": "10.0.0-586437b",
  "@metamask-previews/eth-trezor-keyring": "8.0.0-586437b",
  "@metamask-previews/keyring-internal-api": "6.2.0-586437b",
  "@metamask-previews/keyring-internal-snap-client": "4.1.0-586437b",
  "@metamask-previews/eth-snap-keyring": "13.0.0-586437b",
  "@metamask-previews/keyring-snap-client": "5.0.0-586437b",
  "@metamask-previews/keyring-snap-sdk": "4.0.0-586437b",
  "@metamask-previews/keyring-utils": "3.0.0-586437b"
}

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

@ccharly ccharly force-pushed the feat/multichain-accounts-api branch from 8c73ff3 to 76246b7 Compare July 15, 2025 16:15
@ccharly ccharly changed the title feat: add multichain-account-api feat(account-api): add multichain accounts support Jul 15, 2025
Copy link

cursor bot commented Jul 15, 2025

🚨 BugBot couldn't run

Something went wrong. Try again by commenting "bugbot run", or contact support (requestId: serverGenReqId_96e2ebca-429a-4355-ac04-242fb081de35).

Copy link

cursor bot commented Jul 15, 2025

🚨 BugBot couldn't run

Something went wrong. Try again by commenting "bugbot run", or contact support (requestId: serverGenReqId_78fda8b5-9885-4b8f-8cd7-782e4784412b).

@ccharly ccharly force-pushed the feat/multichain-accounts-api branch from f623e93 to 0457ad7 Compare July 16, 2025 08:29
cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

@ccharly ccharly force-pushed the feat/multichain-accounts-api branch from 1ff4115 to 3d4240e Compare July 16, 2025 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant