-
Notifications
You must be signed in to change notification settings - Fork 127
Add headless and styled UI to connect wallet #301
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
Conversation
…Flag to WalletList
…ive elements which prevents overriding of styles -- References: wevm/vocs#279 wevm/vocs#289
This PR adds support for the `get-starknet` wallet standard by allowed the Controller to conform to the `WalletWithStarknetFeatures` interface. ## Context @fracek reached out to us via Telegram asking us to add support for the `wallet-standard` interface (see [these docs](https://get-starknet.vercel.app/) and [this PR](starknet-io/get-starknet#301) for more context) by creating a connector which conforms to the `WalletWithStarknetFeatures` interface. The idea is to that [the `wallet-standard` interface](https://github.com/wallet-standard/wallet-standard) provides a higher-level interface than the current `StarknetWindowObject`, designed to be usable by frontend libraries like `starknet-react`, but also by command-line tools and more generic libraries like `solid.js`. The `wallet-standard` interface calls for only four functions to be implemented, with return values being similar but not identical to those used by `StarknetWindowObject`: - StandardConnect (~`connect`) - StandardDisconnect (~`disconnect`) - StandardEvents (~`on`) - StarknetWalletApi (~`request`) ## Approach 1 The first approach is to wrap the Controller in a custom connecter which implements `WalletWithStarknetFeatures` specifically for Controller. This implementation is available in `controllerWithStarknetFeatures.ts`. UPDATE: this implementation has been removed from the PR. ## Approach 2 As an alternative to this connector, we can cast the Controller as follows: ``` import Controller from "@cartridge/controller"; import { StarknetInjectedWallet } from "@starknet-io/get-starknet-wallet-standard"; const controller = new StarknetInjectedWallet(new Controller()) ``` The [`StarknetInjectedWallet` type](https://github.com/fracek/get-starknet/blob/develop/packages/wallet-standard/src/injected-wallet.ts#L27) implements `WalletWithStarknetFeatures` and wraps a `StarknetWindowObject`, which is what Controller implements: ``` export class StarknetInjectedWallet implements WalletWithStarknetFeatures { ... constructor(private readonly injected: StarknetWindowObject) { ... } ``` To simplify the experience for developers, we expose an `asWalletStandard()` type on ControllerConnector which performs the cast and returns the correct type: ``` (new ControllerConnector()).asWalletStandard() ``` This approach minimizes code changes on our end, but does reduce the ability to customize the integration. **I would personally lean towards this option for now.** UPDATE: this is the approach we have chosen ## Approach 3 Alternatively, we could direct developers to make the cast directly. This avoids any code changes on our end, although it does require documenting the typecast and limits our ability to customize the integration. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds `asWalletStandard()` to `ControllerConnector` using `StarknetInjectedWallet`, updates example import, expands TS libs, and adds a new wallet-standard dependency. > > - **Connector**: > - Adds `ControllerConnector.asWalletStandard()` returning `WalletWithStarknetFeatures` via `StarknetInjectedWallet` in `packages/connector/src/controller.ts`. > - Introduces dependency `@starknet-io/get-starknet-wallet-standard@5.0.0-beta.0` in `packages/connector/package.json`. > - **Examples**: > - Updates import to use `{ ControllerConnector }` from `@cartridge/connector` in `examples/next/src/components/DelegateAccount.tsx`. > - **TypeScript**: > - Expands `lib` targets (adds `ES2017+`, `DOM`, `DOM.Iterable`) in `packages/connector/tsconfig.json`. > - **Tooling**: > - Ignores `*.tgz` in `.gitignore`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 11dab3e. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Globally, it's working, but some errors have been encountered in specific cases.
- With the re-export of Wallet-standard types, I tested with Starknet.js v8 & PR1382 (starknet-io/starknet.js#1382). It works perfectly ; so as soon as get-starknet v5.0.0 is released in npm, we will be able to merge this PR#1382 in Starknet.js (CC @tabaktoni )
- I tested the new ui package in a
Next.jsproject, that is usingchakra-uilib. Using my own UI withget-starknet/wallet-standardlib, no problem. But usingUIpackage, I have several alerts and problems. Example:
I think that you should test this package with Next.js.
- I have a lot of wallets installed in Chrome:
I am encountering problems with many wallets, especially when changing current wallets. example:

Problems encountered with Rabby, Coinbase, Gate, ...
No problem if not using ui package.
docs/pages/wallet-standard.mdx
Outdated
| This wallet API has two properties: | ||
|
|
||
| ### `standard:disconnect` | ||
| - `accounts`: an array of `WalletAccount` objects. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From user side, isn't it StarknetWalletAccount type?
For information, WalletAccount is also a class in Starknet.js (https://github.com/starknet-io/starknet.js/blob/9592c7a697fb2b485df3830d70843520c1f3c1dc/src/wallet/account.ts#L41). It could be confusing to users to use WalletAccount objects of both get-starknet and starknet.js. Could be better to promote in the get-starknet documentation the StarknetWalletAccount type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed this.
|
Thank you for the review. I will also test with many wallets to see why that issues is happening. |
|
I think all issues are now fixed. |


Summary
This PR introduces the following packages:
@starknet-io/get-starknet-core: this package re-exports all the functions and types from the non-React packages. If someone wants to integrate get-starknet in vanilla javascript they can use this package.@starknet-io/get-starknet-modal: this is a "headless" UI that implements the behaviour of a connect wallet UI, without providing any style.@starknet-io/get-starknet-ui: this package contains the styled UI and that's what developers can use to quickly add a connect wallet UI to their application.I created a documentation mini-website to make it easier to follow along.
Important Changes
The core packages (discovery, virtual-wallet, wallet-standard, and wallets) are essentially unchanged.
The modal package implements the logic to handle wallet connection and track which wallet is currently in use. To do this, we use a React context.
The
GetStarknetProviderarguments pull together the wallet's store from the discovery package, the wallet information from the wallets package, and the wallet with starknet features from the wallet-standard package. These arguments are used, respectively, to track the injected wallets (store), the wallets available in the starknet ecosystem (wallets) and additional (non injected) wallets that follow theWalletWithStarknetFeaturesAPI (wallet-standard).The UI package is a "connect wallet" implementation that uses shadcn/ui under the hood. It allows minimal customization through the use of tailwindcss variables.
Preview
Styled UI
The wallet modal demo shows how the styled wallet component works and we show how to register a custom Starknet wallet implementation. On the left we have the wallets available for use ("available wallets") and the wallets the app wants to support but are not available ("more wallets"). In this demo, "Web Wallet" is a mock wallet we created.
Clicking on the injected wallet icon will prompt the user to connect.
If the user clicks on the web wallet icon, the modal shows the UI to login into that wallet. The idea is that wallet developers can provide "plugins" to render the UI to login into their custom (non injected) wallet.
Finally, if the user clicks on a wallet that's not available we display the installation instructions.
Headless UI
The headless UI package
@starknet-io/get-starknet-modalprovides three components:GetStarknetProvider: tracks the currently connected starknet wallet.WalletList: component to render the list of available wallets.SelectedWallet: component to render the connection view of the wallet currently selected in the wallet list.The documentation explains how to use these components to build custom dialogs.