Skip to content
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

feat: add alchemy accounts context #539

Merged
merged 4 commits into from
Apr 10, 2024
Merged

feat: add alchemy accounts context #539

merged 4 commits into from
Apr 10, 2024

Conversation

moldy530
Copy link
Collaborator

@moldy530 moldy530 commented Mar 30, 2024

Pull Request Checklist


PR-Codex overview

This PR introduces new React hooks and config options, enhances error handling, and adds client-side properties.

Detailed summary

  • Added AWAITING_EMAIL_AUTH status in signer/types.ts
  • Created config with rpcUrl and chain in site/snippets/react/config.ts
  • Implemented ComponentWithSignerStatus and ComponentWithUser in site/snippets/react/useSignerStatus.tsx and site/snippets/react/useUser.tsx
  • Added NoAlchemyAccountContextError in packages/alchemy/src/react/errors.ts
  • Updated getBundlerClient, getUser, getSigner, getSignerStatus in packages/alchemy/src/config/actions/
  • Modified tsconfig.json for moduleResolution and module
  • Enhanced session management in packages/alchemy/src/signer/session/manager.ts
  • Added ClientOnlyPropertyError in packages/alchemy/src/config/errors.ts
  • Implemented ComponentWithSigner and ComponentWithBundlerClient in site/snippets/react/useSigner.tsx and site/snippets/react/useBundlerClient.tsx
  • Created Login component in site/snippets/react/login.tsx
  • Introduced watchUser, watchSigner, and watchSignerStatus in packages/alchemy/src/config/actions/
  • Updated useUser and useBundlerClient hooks in packages/alchemy/src/react/hooks/

The following files were skipped due to too many changes: packages/alchemy/src/client/smartAccountClient.ts, site/snippets/react/useAccount.tsx, site/snippets/react/useSmartAccountClient.tsx, packages/core/src/account/smartContractAccount.ts, packages/alchemy/src/react/hooks/useSigner.ts, site/react/useUser.md, packages/alchemy/src/config/actions/watchAccount.ts, packages/alchemy/src/config/actions/getAccount.ts, packages/alchemy/src/config/store/core.ts, packages/alchemy/src/config/index.ts, site/react/useBundlerClient.md, packages/alchemy/src/react/hooks/useSignerStatus.ts, site/react/useSigner.md, packages/alchemy/src/react/index.ts, packages/alchemy/package.json, packages/alchemy/src/react/hooks/useAuthenticate.ts, site/react/useAuthenticate.md, packages/alchemy/src/config/createConfig.ts, packages/alchemy/src/config/store/types.ts, packages/alchemy/src/react/context.ts, site/react/useSignerStatus.md, packages/alchemy/src/config/types.ts, packages/alchemy/src/react/hooks/useAccount.ts, site/react/createConfig.md, yarn.lock, site/react/overview.md, site/react/useAccount.md, packages/alchemy/src/config/actions/createAccount.ts, site/react/useSmartAccountClient.md, packages/alchemy/src/react/hooks/useSmartAccountClient.ts, packages/alchemy/src/config/store/client.ts

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

@moldy530
Copy link
Collaborator Author

example usage can be found in alchemyplatform/embedded-accounts-demo#4

@moldy530
Copy link
Collaborator Author

moldy530 commented Mar 30, 2024

TODOS

  • address TODOs in code
  • add a summary of the changes and the proposal for how this works

@moldy530 moldy530 force-pushed the moldy/prototype-context branch from dbca7a3 to bed4a62 Compare March 30, 2024 07:36
return user;
},
},
queryClient
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I had to do this because for w/e reason react-query exports hooks under modern or under legacy. aa-alchemy was using legacy and the demo app was using modern. doing it this way ensures a query client is always present

? Omit<CreateLightAccountParams, "signer" | "transport" | "chain">
: Omit<
CreateMultiOwnerModularAccountParams,
"signer" | "transport" | "chain"
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

actually, we shouldn't omit the signer here and instead make it optional. that would allow someone to create a session key signer based account

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

not gonna do this now actually as it requires customizing signer in a lot of other places. opting for simplicity over flexibility / power in this first approach

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

if we want session keys, we can always add a hook for that later

Copy link
Contributor

Choose a reason for hiding this comment

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

do we want this to be with the CreateModularAccountParams, since we made CreateMultiOwnerModularAccountParams different from the base modular account?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ah for now, I think we just want MultiOwner and LA and not MultiSig or other MA types.

export type CreateConfigProps = ConnectionConfig & {
chain: Chain;
sessionConfig?: AlchemySignerParams["sessionConfig"];
signerConnection?: ConnectionConfig;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this can be used as an override if you have different rpc urls. This is most useful if devs are doing what they shouldn't be doing and putting their API keys in the front end

children,
}: React.PropsWithChildren<AlchemyAccountsProviderProps>) => {
// Note: we don't use .tsx because we don't wanna use rollup or similar to bundle this package.
// This lets us continue to use TSC for building the packages which preserves the "use client" above
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

to expand a bit more, when I first prototyped this outside of this repo, I was initially using rollup to build. This was fine except that it wouldn't preserve the use client directive so some hooks weren't working well in nextjs.

We'll need to figure this out when we add UI components, but for hooks I think this is fine for now

Copy link
Contributor

Choose a reason for hiding this comment

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

i assume this .ts vs. .tsx reason applies to the other client-side hooks? if so, we should leave comments there too?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

the hooks files don't actually have any jsx syntax in them so we don't have to do that there

@moldy530 moldy530 force-pushed the moldy/prototype-context branch 5 times, most recently from 597086e to 2891ade Compare April 3, 2024 19:39
Copy link
Contributor

@dphilipson dphilipson left a comment

Choose a reason for hiding this comment

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

Still reading through this, some initial thoughts for now. This general approach seems great to me.

packages/alchemy/src/config/actions/createAccount.ts Outdated Show resolved Hide resolved
packages/alchemy/src/config/actions/watchAccount.ts Outdated Show resolved Hide resolved
packages/alchemy/src/react/hooks/useSmartAccountClient.ts Outdated Show resolved Hide resolved
@@ -232,5 +232,14 @@ export class SessionManager {

this.setSession({ type: "passkey", user });
});

window.addEventListener("storage", (e: StorageEvent) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I didn't know this event existed. This will be very useful to me in Worth of Words, thanks for showing it!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

oh speaking of worth of words! would be good to understand from your lens as a potential consumer of this what we should focus on supporting next for your use case. can be a good way to dogfood this; ideally, we can replace most of your aa-sdk usage with hooks from this package

@moldy530 moldy530 force-pushed the moldy/prototype-context branch from 2891ade to beb55c1 Compare April 4, 2024 03:05
@moldy530 moldy530 force-pushed the moldy/prototype-context branch 2 times, most recently from d84a1eb to 55f757f Compare April 9, 2024 22:29
@moldy530 moldy530 force-pushed the moldy/prototype-context branch from 55f757f to 5a88d2c Compare April 9, 2024 22:32
dphilipson
dphilipson previously approved these changes Apr 9, 2024
Copy link
Contributor

@dphilipson dphilipson left a comment

Choose a reason for hiding this comment

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

I really like the way this ended up! That's a really nice organization to have the state management outside of React. I haven't seen that before but it feels like everyone should be doing it.

packages/alchemy/src/config/actions/watchAccount.ts Outdated Show resolved Hide resolved
packages/alchemy/src/react/hooks/useSmartAccountClient.ts Outdated Show resolved Hide resolved
avasisht23
avasisht23 previously approved these changes Apr 9, 2024
Copy link
Contributor

@avasisht23 avasisht23 left a comment

Choose a reason for hiding this comment

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

some comments here, but looks good!

packages/alchemy/package.json Show resolved Hide resolved
? Omit<CreateLightAccountParams, "signer" | "transport" | "chain">
: Omit<
CreateMultiOwnerModularAccountParams,
"signer" | "transport" | "chain"
Copy link
Contributor

Choose a reason for hiding this comment

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

do we want this to be with the CreateModularAccountParams, since we made CreateMultiOwnerModularAccountParams different from the base modular account?

packages/alchemy/src/config/store/client.ts Outdated Show resolved Hide resolved
Comment on lines +10 to +17
// TODO: figure out how to handle this on the server
// I think we need a version of the signer that can be run on the server that essentially no-ops or errors
// for all calls
return useSyncExternalStore(
watchSigner(config),
() => config.signer,
// We don't want to return null here, should return something of type AlchemySigner
() => null
Copy link
Contributor

Choose a reason for hiding this comment

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

and the reason it can't run work on server is because the alchemy signer needs the turnkey iframe? have we chatted with them on server-side solutions?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

it's not just that, but server-side state becomes global to the application. that means you can run into weird issues where you accidentally log a user in server side and that has all your other requests from other users authenticated as that user

children,
}: React.PropsWithChildren<AlchemyAccountsProviderProps>) => {
// Note: we don't use .tsx because we don't wanna use rollup or similar to bundle this package.
// This lets us continue to use TSC for building the packages which preserves the "use client" above
Copy link
Contributor

Choose a reason for hiding this comment

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

i assume this .ts vs. .tsx reason applies to the other client-side hooks? if so, we should leave comments there too?

Co-authored-by: Ajay Vasisht <43521356+avasisht23@users.noreply.github.com>
@moldy530 moldy530 dismissed stale reviews from avasisht23 and dphilipson via d29e66e April 9, 2024 23:14
Comment on lines +68 to +71
const search = new URLSearchParams(window.location.search);
if (search.has("bundle")) {
signer.authenticate({ type: "email", bundle: search.get("bundle")! });
}
Copy link
Contributor

Choose a reason for hiding this comment

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

ultra nit: but "bundle" is a keyword and might be worth turning into a const that we can update in case we want to modify it in the future more easily if our email redirect flow changes.

not necessary to do in this pr

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

oh yea good shout

avasisht23
avasisht23 previously approved these changes Apr 10, 2024
* docs(hooks): add initial react hooks docs

* refactor: apply suggestions from code review

Co-authored-by: Ajay Vasisht <43521356+avasisht23@users.noreply.github.com>

---------

Co-authored-by: Ajay Vasisht <43521356+avasisht23@users.noreply.github.com>
@moldy530 moldy530 merged commit f92469e into main Apr 10, 2024
2 checks passed
@moldy530 moldy530 deleted the moldy/prototype-context branch April 10, 2024 21:25
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.

3 participants