Comments (7)
FYI - cleaned up some spam comments
from sips.
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 π€·ββ
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 β Wallet Client
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
β required
request(method: string, params?: JSONObject): Promise<T>
A request
method is accepted by clients, following the JSON RPC standard.
- The
method
parameter describes an action for the wallet to execute. - The optional
params
parameter offers arbitrary parameters to be passed as a JSON object.
listen
β required
listen(event: string, callback: (result) => void): void
A listen
method accepts an event parameter.
- The
event
parameter describes a wallet event. On the occurence of an event described by theevent
parameter, the wallet should call the provided callback. - The
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.
Examples
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");
});
Notes
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.
Comparison
Current State
- Safer to have individual RPCs for requesting specific information. E.g. a user might not want to share their mainnet address when sharing a testnet address.
- Better to have a smaller surface area, which doesn't grow stale as the ecosystem evolves (as we have seen in the past with many unused legacy features not needed any more).
- Better suited for multi-chain (e.g. adding BTC transfers)
Todo & Questions
-
params
always named or allow ordered params (without name) - Standardize errors? What does a failure look like, what does an abort/cancel look like? What do missing methods look like?
- Callback parameter -- Can
listen
have errors? - Add getter for retrieving available methods? Dangers? Fingerprinting?
- JSON RPC
notification
? Or generateid
(uuid) for each request? - JSON RPC response structure? (
error
,id
etc?) - Use MUST SHOULD MAY RFC language?
- As defined in JSON RPC, the client should set
"jsonrpc": "2.0"
and"id": new Uuid()
for requests ?? - Nostr compatible? different namespace? etc.
Sibling SIPs
#1: [Stacks] Types, Params Interface, Data Type Serialization
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 addressstring
version
= semverstring
; used for versioning the params structure (e.g. a wallet could provide an experimental request method and later use theversion
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
WalletConnect
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.
#2: [Bitcoin] Types
#3: Multi-Chain / Layer -- Client
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)
Related Work
- https://eips.ethereum.org/EIPS/eip-1102
- https://eips.ethereum.org/EIPS/eip-1474
- https://eips.ethereum.org/EIPS/eip-2255
- https://github.com/nostr-protocol/nips/blob/master/07.md
- https://walletconnect.com
- https://docs.walletconnect.com/2.0/specs/
- https://docs.walletconnect.com/2.0/specs/clients/sign/client-api
- https://docs.walletconnect.com/2.0/javascript/providers/ethereum#events
from sips.
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.
from sips.
Leaving my thoughts so far:
- I like the proposal of adding two simple flexible/generic methods that can be expanded by wallets without needing a SIP for everything. e.g. wallets could prefix beta features (similar to http headers or css rules) and alias them once a common standard is found/implemented by multiple wallets. And even if this is the standardized protocol of talking to a wallet that doesn't mean the interface exposed to application developer can't stay the same (i.e. we don't need to concern the web-app developer with available strings, unless they're playing with beta features and know what they're doing).
- I'm not too sure about the usage of
Observable
. I would prefer describing a native (or more seasoned) JS pattern like a simplylisten(event: string, callback: (error: Error, payload: any) => void)
via callback (which respective connect/client applications could wrap with their favoriteObservable
implementation, but don't have too). - I like the move away from the cluttered JWT wrapped protocol, in place currently. This simplified API can be used for secure contexts (eg talking to desktop browser extensions), while an additional SIP could target adding sessions (e.g. over relays, similar to wallet-connect, or implementing wallet-connect). Once a secure session is established the session instance could expose the same object as this Wallet API proposal.
- I'm in favor of short SIPs which can stack on top of each other well (similar to many NIPs eg) -- so it's nice to see a short and concise SIP which could standardize the parameters of a
send_transaction
request in a follow-up SIP. params
might need stricter types likeparams: jsonobject | json[]
?- It might make sense to at some point include (in this SIP or separately) how to serialize certain data-types, so they're always the same during transit. e.g. bytes as a
0x
prefixed string, bigint as string?
Would love to hear @yknl thoughts, especially regarding wallet-connect
from sips.
Wallet Connect docs from Xverse: https://docs.xverse.app/wallet-connect/reference/api_reference
from sips.
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
from sips.
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.
from sips.
Related Issues (20)
- Create template for CAB minutes HOT 1
- Draft SIP for apps requesting BTC transactions from wallet HOT 1
- SIP001, SIP002 and SIP004 still refer to Blockstack, should that be changed to Stacks? HOT 1
- sBTC has token ticker collisions, should it be changed? HOT 3
- Updated Harberger Tax Model for BNS HOT 18
- NFT(s) Staking SIP Research
- Draft SIP for ZK Verification Clarity Primitive HOT 1
- Documenting the SIP approval process
- Wishlist: Step by step tutorial to run a stacks node (w/o docker) - and/or single click install options HOT 1
- SIP specifying Clarity `slice` function HOT 3
- First step towards submitting a SIP HOT 6
- Weekly SIP Meeting Agenda & Notes HOT 32
- Use more GitHub labels
- Document members of the Steering Committee HOT 3
- Steering Committee Monthly SIP call - Agenda & Notes HOT 7
- SIP describing Stacks message signing HOT 6
- Draft for Standard trait definition for extending tokens HOT 16
- Quick test - please disregard HOT 3
- Reference List of Traits for Mainnet and Testnet HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sips.