Skip to content

Conversation

dphilipson
Copy link
Contributor

@dphilipson dphilipson commented Sep 26, 2025

Basic implementation of a connector which uses the Wallet API to perform actions using an Alchemy smart account, wrapping another connector to perform signing.

This version is tested to work with the Metamask connector, although there is additional work that can done to clean up code and polish edge cases, as marked with TODO's.

Pull Request Checklist


PR-Codex overview

This PR primarily focuses on enhancing the @alchemy/connectors-web library by introducing the alchemySmartWallet connector, updating existing connectors, and refining the integration with Alchemy's authentication and wallet APIs.

Detailed summary

  • Removed resolveConnector.ts and resolveAlchemyAuthConnector.mdx.
  • Updated package.json files to include new dependencies.
  • Added alchemySmartWallet connector with detailed options and parameters.
  • Refined resolveAlchemyAuthConnector to improve connector resolution.
  • Updated various functions to use destructured connector returns.
  • Enhanced error handling and logging in example files.
  • Added documentation for alchemySmartWallet functionality.

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Copy link

vercel bot commented Sep 26, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
aa-sdk-ui-demo Ignored Ignored Preview Oct 1, 2025 8:54pm

Copy link

github-actions bot commented Sep 26, 2025

🌿 Documentation Preview

Name Status Preview Updated (UTC)
Alchemy Docs ❌ Failed Oct 1, 2025, 8:54 PM

@github-actions github-actions bot temporarily deployed to docs-preview September 26, 2025 09:33 Inactive
Copy link
Collaborator

@blakecduncan blakecduncan left a comment

Choose a reason for hiding this comment

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

This is awesome, tested it out in the demo and it's working well!

Few comments but happy for any changes to be made in subsequent PRs if you wanna merge this

*/
const loggedOutProvider: Provider = {
on: () => {},
removeListener: () => {},
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure if this is overkill/needed, do you think we should have some code to remove the listeners?

const listeners = new Map();
const loggedOutProvider: Provider = {
  on: (event, listener) => {
    if (!listeners.has(event)) listeners.set(event, new Set());
    listeners.get(event)?.add(listener);
    return () => listeners.get(event)?.delete(listener);
  },
  removeListener: (event, listener) => {
    listeners.get(event)?.delete(listener);
  },
};

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since right now this provider never emits events, what I wrote should be equivalent behavior and I think there's no reason to store listeners that won't be called.

(We could forward listeners to the inner provider, but that feels like it could have unpredictable consequences.)

Copy link
Contributor

Choose a reason for hiding this comment

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

not sure if this is applicable here, but in alchemyAuth we used a resumePromise (link) as a standard promise that we wait for on reload.

does the getProvider() only get called on reload, which is the case that the logged out provider is supposed to be for?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh that's really interesting, I assumed that wagmi wouldn't accept us until we produced a provider, but it seems like just a promise of a provider is good enough for wagmi. Let me try that, and also see what built-in connectors are doing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

the only time we would need the dummy provider during this implementation is during reconnect, right?

when getProvider is called here, could we await the inner connector being ready, then await the smart wallet client creation so that we have the provider here?

Copy link
Contributor Author

@dphilipson dphilipson Oct 1, 2025

Choose a reason for hiding this comment

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

Thinking about it more, I'm not sure I like the idea of returning a suspended promise that resolves once the user logs in. That seems like it could be unexpected behavior for callers, who might call await connector.getProvider() and then be surprised that their program hangs forever. I think the expected behavior would be to return a provider that reflects the logged out state. What do you think?

*/
const loggedOutProvider: Provider = {
on: () => {},
removeListener: () => {},
Copy link
Contributor

Choose a reason for hiding this comment

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

not sure if this is applicable here, but in alchemyAuth we used a resumePromise (link) as a standard promise that we wait for on reload.

does the getProvider() only get called on reload, which is the case that the logged out provider is supposed to be for?

Copy link
Contributor

@jakehobbs jakehobbs left a comment

Choose a reason for hiding this comment

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

left a couple of questions. good work so far! cool to see this coming along.

could i request that we update the "send call via smart wallet client" button in the connector-web-example to just be "send call" and use the wagmi action to send a call via the connector?

*/
const loggedOutProvider: Provider = {
on: () => {},
removeListener: () => {},
Copy link
Contributor

Choose a reason for hiding this comment

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

*/
const loggedOutProvider: Provider = {
on: () => {},
removeListener: () => {},
Copy link
Contributor

Choose a reason for hiding this comment

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

the only time we would need the dummy provider during this implementation is during reconnect, right?

when getProvider is called here, could we await the inner connector being ready, then await the smart wallet client creation so that we have the provider here?

async connect(parameters) {
await baseConnector.connect(parameters);
throw new Error("Not implemented: connect");
async connect(params): Promise<{ accounts: Address[]; chainId: number }> {
Copy link
Contributor

Choose a reason for hiding this comment

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

not sure if this would change anything for your implementation, but just want to flag that connect has an { isReconnecting: true } param whenever it's called via wagmi's reconnect action.

@dphilipson dphilipson force-pushed the dp/smart-wallet-connector branch from b13c98a to 2429bd5 Compare October 1, 2025 20:40
@github-actions github-actions bot temporarily deployed to docs-preview October 1, 2025 20:41 Inactive
Basic implementation of a connector which uses the Wallet API to perform
actions using an Alchemy smart account, wrapping another connector to
perform signing.

This version is tested to work when wrapping both the Metamask connector
and the Alchemy Auth connector, including many edge cases such as
changing accounts or configs in the Metamask UI after connecting.
@dphilipson dphilipson force-pushed the dp/smart-wallet-connector branch from 2429bd5 to 8592acc Compare October 1, 2025 20:53
@github-actions github-actions bot had a problem deploying to docs-preview October 1, 2025 20:54 Failure
@dphilipson dphilipson marked this pull request as ready for review October 1, 2025 20:57
@Copilot Copilot AI review requested due to automatic review settings October 1, 2025 20:57
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

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.

4 participants