Open kyranjamie opened 1 year ago
Leaving my thoughts so far:
Observable
. I would prefer describing a native (or more seasoned) JS pattern like a simply listen(event: string, callback: (error: Error, payload: any) => void)
via callback (which respective connect/client applications could wrap with their favorite Observable
implementation, but don't have too).send_transaction
request in a follow-up SIP.params
might need stricter types like params: jsonobject | json[]
?0x
prefixed string, bigint as string?Would love to hear @yknl thoughts, especially regarding wallet-connect
Wallet Connect docs from Xverse: https://docs.xverse.app/wallet-connect/reference/api_reference
FYI - cleaned up some spam comments
Leaving my thought and drafts here for now... Based on @kyranjamie's work -- Maybe we should use a more collaborative doc for this, if folks even agree. I don't want to overstep 🤷♂
This SIP describes a simpler standard for apps to interface with wallet clients.
This proposal outlines a uniform manner with which apps can interface with wallet clients.
It recommends to minimise the surface area of available APIs, and makes design decisions similar to those in other crypto ecosystems.
No standard exists describing how apps interact with Stacks-compatible wallets. Presently, ecosystem wallets adhere to an undocumented set of commands that wallets should implement. A well-documented API, that’s familiar to developers from other ecosystems, benefits both app and wallet developers.
The purpose of this SIP is to describe the outline of an API that can support multiple environments including, but not limited to, Web Extensions, mobile wallets, CLIs etc. It does not describe the individual methods that clients may commonly support.
A window.WalletClient
object can be provided by browsers or web extensions so websites/web-apps can check for it's availability and use the provided methods below.
request
— requiredrequest(method: string, params?: JSONObject): Promise<T>
A request
method is accepted by clients, following the JSON RPC standard.
method
parameter describes an action for the wallet to execute.params
parameter offers arbitrary parameters to be passed as a JSON object.listen
— requiredlisten(event: string, callback: (result) => void): void
A listen
method accepts an event parameter.
event
parameter describes a wallet event. On the occurence of an event described by the event
parameter, the wallet should call the provided callback.callback
parameter ...The injected provider should remain lightweight, unopinionated, and use proven JavaScript conventions.
Wrapper libraries (e.g. connect, micro-stacks/client) could choose to wrap the listen
interface in an TC 39 Observable
or any other interface.
request
const accounts = await window.WalletClient.request("stx_requestAccounts");
const accounts = await window.WalletClient.request("stx_sendTransaction", {
...
});
listen
window.WalletClient.listen("networkChange", (network) => {
alert("Switched network");
});
Event/Method Payloads
This SIP intentionally does not describe what actions/events examples and conventions can be.
Sessions
The approach described in this SIP is session-less and assumes a safe/encrypted communication between the wallet and the web-app.
params
always named or allow ordered params (without name)listen
have errors?notification
? Or generate id
(uuid) for each request?error
, id
etc?)"jsonrpc": "2.0"
and "id": new Uuid()
for requests ??It's up to the wallet what to respond to on RPC calls and how to parse data, etc.
But it is prefered to only use named-object params JSONObject.
Some proven defaults are recommended:
Request Methods
stx_stxTransfer
stx_ftTransfer
stx_nftTransfer
stx_contractCall
stx_contractDeploy
Events
'stx_networkChanged'
'stx_accountsChanged'
[ ] stx_connect
[ ] stx_disconnect
Params
recipient
= Stacks address string
version
= semver string
; used for versioning the params structure (e.g. a wallet could provide an experimental request method and later use the version
parameter to deprecate the legacy structure)Payload independany fields
field | type | examples |
---|---|---|
postConditions | ||
postConditionMode | ||
nonce | ||
fee |
Type Serialization/Deserialization
Bytes shall be encoded as strings prefixed by 0x
BigInts shall be encoded as strings parseable by the BigInt()
JS constructor.
fee
, from
attributes, which can be inferred or selected from the wallet are optional
[ ] Addresses?
[ ] fee
, nonce
= BigInt
The same params defined for Stacks SIPs should be re-used for adapters like WalletConnect. This way wallets can share code and provide the same interface directly or via WalletConnect sessions.
Provide Stacks
Client under window.WalletClient
which can expose multiple layers of bitcoin. This way
window.WalletClient.Stacks ...
// ↑
// The same as StacksClient, but can group more functionality (e.g. BTC transfers)
This proposal would help greatly in implementing wallet connecting for game engines with web exports, like Unity and Godot. The current JWT-based API is difficult to work with, so I support this change.
Xverse launched open source wallet connect standard called "Sats Connect", just to make sure it's captured in this conversation. Documentation here: https://docs.xverse.app/sats-connect/ Twitter post here: https://twitter.com/xverseapp/status/1635592234623021056
Note that the http://btckit.org/ standard we've started using for Hiro Wallet includes the .request
approach in this SIP issue from February.
Sats Connect chose not to apply such a .request
approach when it was released a couple weeks ago despite our hope that it would be adopted among wallets generally, and we don't seem to have heard anything about it from the Xverse team.
Sats Connect was also promoted as a new API / library, not a standard per se, so it's not clear whether as a library it can incorporate .request
going forward as well, or whether it proposes an alternative approach for specific reasons. We'd love to hear about them if there's a rationale to going in a different direction.
There should be a standard describing the style of API used by wallet clients.
@friedger pushed a draft SIP a while back describing the existing wallet API. Though, more recently, there's been some discussion about moving away from the existing JWT-style API towards something more consistent with other ecosystems, like an RPC style API.
I suggest a SIP that describes a feature-agnostic RPC API that works cross-platform: Web Extensions, mobile apps, CLIs etc, similar to that of
EIP-1102
.SIP Draft
# Wallet Client API This SIP describes a simpler standard for apps to interface with wallet clients. ## Abstract This proposal outlines a uniform manner with which apps can interface with wallet clients. It recommends to minimise the surface area of available APIs, and makes design decisions similar to those in other crypto ecosystems. ## Introduction No standard exists describing how apps interact with Stacks-compatible wallets. Presently, ecosystem wallets adhere to an undocumented set of commands that wallets should implement. A well-documented API, that’s familiar to developers from other ecosystems, benefits both app and wallet developers. The purpose of this SIP is to describe the outline of an API that can support multiple environments including, but not limited to, Web Extensions, mobile wallets, CLIs etc. It does not describe the individual methods that clients may commonly support. ## Specification Two methods are described. The methods can be typed such that the return value corresponds to the method name passed. ### `request` `request(method: string, params?: object[]): PromiseHappy to work on this with anyone that wants to collaborate.
cc/ @janniks @yknl @markmhx @fbwoolf @edu-stx
Edit: March 2023 update
With the suggestions/ideas from this SIP @janniks and I have started http://btckit.org, which aims to push this effort and form a community-driven, wallet-agnostic standard.