-
Notifications
You must be signed in to change notification settings - Fork 18
-
SIP-7: Snaps UI can be discussed here.
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 3 comments 4 replies
-
- What does panel mean? Should we just call that a div? What html element would a panel equate to?
- Should we have a mapping file and choose what components from the extension we want to use?
- How do we control the CSS of components? You mentioned that we can render children vertically or horizontally? (This refers to your comments made in the notion UI proposal)
- Can't we define a set of CSS rulesets?
- Instead of mode maybe we should have a CSS key
- Do we want snaps UI to be an RPC request? What if some snaps want to have UI that lives permanently in some place in the extension? i.e. headless snaps?
- With the
wallet.requestmethod it seems that we will be reconstructing the UI only ever when a snap runs? - Might be a stupid question, but isn’t the
ButtonClickEventinterface circular with extendingUserInputEvent? (asUserInputEventis just equal toButtonClickEvent)
- With the
- Is the idea that the UI key-value in
snap_showInterfaceis an object with the top level component and then any other components nested inside children and so on and so forth?- If so, I think this lends itself well to my idea of having a CSS key.
- I think snap UI should be an endowment, maybe something like "endowment:user-interface"
- We can then use
snap_showInterfaceto render UI for certain APIs like tx-insights- The issue with that is that what if you render some sort of UI for the tx-insight tab that needs to stay there as long as the user is on the tab? Seems like something that shouldn’t be defined in the UI api but something that is just handled on the front-end. This would work for static user interfaces, for dynamic interfaces maybe we can have some state-machine mechanism defined for different components? I.e. a form would always end up to a certain state (perhaps displaying a result from the form action (be it some success or error state).
- We can then use
Beta Was this translation helpful? Give feedback.
All reactions
-
- What does panel mean? Should we just call that a div? What html element would a panel equate to?
It's essentially just a container around other elements. It could be a div, depending on the platform. I don't think we should name it div, because on mobile it's likely not an actual <div /> element.
- Should we have a mapping file and choose what components from the extension we want to use?
I think that's an implementation detail, and not something we should specify in the SIP?
- How do we control the CSS of components? You mentioned that we can render children vertically or horizontally? (This refers to your comments made in the notion UI proposal)
In the actual implementation we'll have to do a mapping from SIP-7 component to React component. We can put any CSS needed to render stuff horizontally or vertically there. Horizontal rendering is something we'll likely implement somewhere in the future though, as for now it's easier to just render things vertically.
3.1 Can't we define a set of CSS rulesets?
3.2 Instead of mode maybe we should have a CSS key
I'm not sure what you mean by that.
- Do we want snaps UI to be an RPC request? What if some snaps want to have UI that lives permanently in some place in the extension? i.e. headless snaps?
4.1 With thewallet.requestmethod it seems that we will be reconstructing the UI only ever when a snap runs?
The main purpose for the RPC request is to let Snaps show a custom confirmation, popup, etc., similar to the snap_confirm JSON-RPC method. "Permanent" UI can be implemented differently, like how the SIP describes implementing UI for transaction insights. For headless Snaps we could expose a new entry point.
4.2 Might be a stupid question, but isn’t the
ButtonClickEventinterface circular with extendingUserInputEvent? (asUserInputEventis just equal toButtonClickEvent)
Good point. ButtonClickEvent is meant to extend a generic Event type, i.e.:
interface Event { type: string; }
And UserInputEvent should be a union of all the supported events. I'll update the SIP to clarify this.
- Is the idea that the UI key-value in snap_showInterface is an object with the top level component and then any other components nested inside children and so on and so forth?
5.1 If so, I think this lends itself well to my idea of having a CSS key.
The idea is that each UI consists of a single root element, similar to how in React you can't render an array of elements directly, without wrapping it inside another element.
The ui property of the snap_showInterface specifies the root element, which can have children, depending on the component you're using. Right now, we only have the Panel component for that, but in the future there could be other components that accept children.
- I think snap UI should be an endowment, maybe something like "endowment:user-interface"
6.1 We can then usesnap_showInterfaceto render UI for certain APIs like tx-insights
I think this adds a bunch of complexity, like handling a JSON-RPC method differently for different entry points (onRpcRequest versus onTransaction, ...). With the current implementation, Snaps can just return the UI in the onTransaction entry point, meaning that they need the endowment:transaction-insights permission to make use of the custom UI in the first place.
Snaps could for example show a button which opens a new pop up using snap_showInterface, from within the transaction insights.
6.1.1 The issue with that is that what if you render some sort of UI for the tx-insight tab that needs to stay there as long as the user is on the tab? Seems like something that shouldn’t be defined in the UI api but something that is just handled on the front-end. This would work for static user interfaces, for dynamic interfaces maybe we can have some state-machine mechanism defined for different components? I.e. a form would always end up to a certain state (perhaps displaying a result from the form action (be it some success or error state).
I'm not sure if I understand the problem?
Beta Was this translation helpful? Give feedback.
All reactions
-
3.1 Can't we define a set of CSS rulesets?
3.2 Instead of mode maybe we should have a CSS keyI'm not sure what you mean by that.
As far as CSS rulesets, I meant maybe we should have a pre-defined set of CSS rules that we allow for the components. I.e. display, flex related rules, font, etc. In order to avoid anything funky we can impose restrictions on those rules and completely disallow certain rules? I thought only having rendering children horizontally or vertically might be l limiting?
I think this adds a bunch of complexity, like handling a JSON-RPC method differently for different entry points (onRpcRequest versus onTransaction, ...)
I don't think that's too bad to implement technically, we already have handler types. I suppose I don't disagree with your method, especially for v1.
6.1.1 The issue with that is that what if you render some sort of UI for the tx-insight tab that needs to stay there as long as the user is on the tab? Seems like something that shouldn’t be defined in the UI api but something that is just handled on the front-end. This would work for static user interfaces, for dynamic interfaces maybe we can have some state-machine mechanism defined for different components? I.e. a form would always end up to a certain state (perhaps displaying a result from the form action (be it some success or error state).
I'm not sure if I understand the problem?
Sorry! Disregard this paragraph, I think I had some concerns based on the notion doc and didn't realize they were addressed here.
Beta Was this translation helpful? Give feedback.
All reactions
-
Components
-
The SIP talks about implementation details (this component will render
<h>, this<p>), I'd rather this SIP be talking about user visible behaviour than HTML since that might change in the future.Basic UI wireframes supporting each component created by Erik Nilsson might help here. Or just try to describe the component behaviour in words instead.
RPC
- I'm against the ability for snaps to show a UI whenever they want and would to remove
snap_showInterfacein general. The BlockKit UI has the concept of Surfaces, which are user activated entry points into custom UIs.- I'd suggest adding some kind of export like
exports.ui.onEntrywhich gets called whenever a user enters a surface that displays UI. - Snap Dialog would be an edge case with being 2 step process - open a dialog with RPC and return the UI in the
exports.onEntry - Example surfaces would be Snap Home, Transaction Insights, Add Account, Snap Dialog (fired by a separate RPC command)
- I'd suggest adding some kind of export like
snap_updateInterface- I also believe the interface shouldn't be allowed to be updated arbitrarily. The new interface could be returned fromexports.ui.onEntryor the proposedexports.onUserInputsnap_resolveInterface- From the specification I don't understand what this method does.
General
I feel the gist I've written some time ago is more comfortable way to write UIs.
Not only it is more similar to other features we have, such as keyrings, it also skips many implementation details not needed to be known by the user, such as maintaining the knowledge of which UI corresponds to which id.
It exposes 3 methods:
exports.ui.onEntry- Which gets executed whenever a user enters a Surface.exports.ui.onChange- When an input is updated with value such as text inputexports.ui.onPress- When a user presses a button.
All of the above return an object which can contain an action such as close the ui, or update the ui in question with new content. It's based on BlockingResponse api which also returns actions object.
Beta Was this translation helpful? Give feedback.
All reactions
-
Solving the snap_dialog edge case, example from internal conversation:
exports.onRpc = async () => { const continue = await wallet.request({method: 'snap_dialog', params: { ui: { type: "section", children: [ "Do you want to continue?", { type: "button", id: "shouldContinue", value: true, text: "Yes" }, { type: "button", id: "shouldContinue", value: false, text: "No" } ] }}}); assert(continue === true); } exports.ui.onPress = ({ location, action: { id, value } }) => { assert(location === 'dialog'); assert(id === 'shouldContinue'); return { action: 'close', value }; }
As you can see, snap_dialog is the only place where you can inject UI outside of returning it from exports.ui methods. There are some unsolved questions with that approach - would that call the exports.ui.onEntry as well?
Another solution would be to have the flow consistent:
exports.onRpc = async () => { const continue = await wallet.request({method: 'snap_dialog', params: { id: "confirmation" }); assert(continue === true); } exports.ui = { onEntry: ({ location, action: { id }) => { assert(location === "dialog"); assert(id === "confirmation"); return { ui: { type: "section", children: [ "Do you want to continue?", { type: "button", id: "shouldContinue", value: true, text: "Yes" }, { type: "button", id: "shouldContinue", value: false, text: "No" } ]} }; }, onPress: ({ location, action: { id, value } }) => { assert(location === 'dialog'); assert(id === 'shouldContinue'); return { action: 'close', value }; } }
And a third one, would be a hybrid, in which onEntry would be called if no ui was provided in snap_dialog call, and not be called if the ui was injected in the call itself.
Beta Was this translation helpful? Give feedback.
All reactions
-
Hey,
For our use case, we need a "MultiSelect List", where we provide a list of objects and let the user select one or more. A component identical to the one MetaMask uses when connecting to a dApp (where users can choose one or more addresses to connect with).
Another handy feature for us is "popups" that open a small popup that looks like an "Edit gas priority" popup and shows some text (or even describes an object similar to sign_typedData). In our case, this would be called from the "MultiSelect list" ("show more" button?) to display more details about the object user is selecting.
Should a component like this be included in the SIP, or is this something we can build ourselves later on? And would something like that even make sense to be a part of Snaps UI?
Beta Was this translation helpful? Give feedback.
All reactions
-
We're planning to add form components in the future, likely as part of another SIP. The aim of this SIP is to define an initial version of the UI API.
I'll keep this in mind when working on the next SIP!
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 3