solana-mobile / mobile-wallet-adapter

Other
224 stars 91 forks source link

DRAFT: One Off Transactions/Requests Specification #783

Open Funkatronics opened 2 months ago

Funkatronics commented 2 months ago

Summary

"One Off" transactions are transactions that do not require a previous authorization to complete. This is effectively a combination of authorize + sign_and_send_transactions into a single request. Wallet endpoints supporting this feature should show a single UI modal to sign the rquested transactions.

User stories

These user stories outline the goals and user experiences that this feature aims to enable.

  1. As a user, I want to be able to sign transactions with fewer steps and interactions so that I can interact with dapps in a seamless and less intrusive flow.
  2. As a dapp developer, I want the ability to send a one off request to wallet endpoints without needing to establish an authorized session with the wallet so that I can more easily send transactions that do not require subsequent requests.
Funkatronics commented 2 months ago

Idea:

what if we instead made this a "one off request" feature where any normally privileged request can be sent to wallet?

something like this:

Method
one_off_request
Params
{
    “identity”: {
        “uri”: “<dapp_uri>”,
        “icon”: “<dapp_icon_relative_path>”,
        “name”: “<dapp_name>”,
    },
    "cluster": "<cluster>",
    "<requested_method_name>": { <requested_method_params> }
}

where

  • requested_method_name: the name of the privileged method
  • requested_method_params: the method params for the request method, as according to the methods specification

@sdlaver

sdlaver commented 2 months ago

Idea:

what if we instead made this a "one off request" feature where any normally privileged request can be sent to wallet?

something like this:

Method
one_off_request
Params
{
    “identity”: {
        “uri”: “<dapp_uri>”,
        “icon”: “<dapp_icon_relative_path>”,
        “name”: “<dapp_name>”,
    },
    "cluster": "<cluster>",
    "<requested_method_name>": { <requested_method_params> }
}

where

  • requested_method_name: the name of the privileged method
  • requested_method_params: the method params for the request method, as according to the methods specification

@sdlaver

That would work, but it comes at the cost of expanding the protocol syntax by theoretically expanding the shape of the JSON payload for any request.

An alternative approach: a new authorize_oneshot method, which contains the identity but does not present any UI. It waits until the next operation arrives over the wire, and then the wallet would present a combined authorize + action UI to the user. It requires two messages over the wire, but each message payload retains the standard object shape. Thoughts?

Funkatronics commented 2 months ago

An alternative approach: a new authorize_oneshot method, which contains the identity but does not present any UI. It waits until the next operation arrives over the wire, and then the wallet would present a combined authorize + action UI to the user. It requires two messages over the wire, but each message payload retains the standard object shape. Thoughts?

yeah I like that, great call.

Funkatronics commented 2 months ago

@sdlaver I like the authorize_oneshot idea. a couple questions:

  1. In the case of a one shot transaction request, how will a dapp know what publickey to use in their transaction payload? is it assumed that in this case the dapp will already know the users public key? or will we additionally need to to define some kind of transaction template format (we discussed this a bit before) so that dapps can send a partially filled transaction, and allow the wallet to fill in the required accounts?

The way wallets work today, this is not a problem, as they don't currently allow a user to select an account during authorization; they always use the account that is currently set within the wallet. But with improved wallet UX this get messy from a UX standpoint.

  1. Should authorize_oneshot return an authToken? this would allow dapps to reauthorize again using the same authToken. I am thinking no, because of they intend to keep sending requests they should probably use the standard MWA flow but want to hear your thoughts.
sdlaver commented 2 months ago

@sdlaver I like the authorize_oneshot idea. a couple questions:

  1. In the case of a one shot transaction request, how will a dapp know what publickey to use in their transaction payload? is it assumed that in this case the dapp will already know the users public key? or will we additionally need to to define some kind of transaction template format (we discussed this a bit before) so that dapps can send a partially filled transaction, and allow the wallet to fill in the required accounts?

The way wallets work today, this is not a problem, as they don't currently allow a user to select an account during authorization; they always use the account that is currently set within the wallet. But with improved wallet UX this get messy from a UX standpoint.

I presume we'd use a well-known address (perhaps all 0's) as a placeholder, to be filled in by the wallet. Only a single placeholder would be allowed, so that the wallet does not need to interpret the intent of the transaction, just simulate the results.

  1. Should authorize_oneshot return an authToken? this would allow dapps to reauthorize again using the same authToken. I am thinking no, because of they intend to keep sending requests they should probably use the standard MWA flow but want to hear your thoughts.

I don't think so; it would affect the state of the connection, but does not provide any auth token to manage or recover that state later.