Skip to content

Commit

Permalink
Update docs for the wallet-standard
Browse files Browse the repository at this point in the history
  • Loading branch information
hayes-mysten committed May 23, 2024
1 parent 8a95bb2 commit 4675ee5
Show file tree
Hide file tree
Showing 10 changed files with 596 additions and 1,775 deletions.
87 changes: 70 additions & 17 deletions docs/content/standards/wallet-standard.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ title: Wallet Standard
description: The Wallet Standard defines how wallets can automatically be discovered and interacted with from dApps.
---

Browser extension wallets built for Sui are defined using the [Wallet Standard](https://github.com/wallet-standard/wallet-standard/). This is a cross-chain standard that defines how wallets can automatically be discovered and interacted with from dApps.
Browser extension wallets built for Sui are defined using the
[Wallet Standard](https://github.com/wallet-standard/wallet-standard/). This is a cross-chain
standard that defines how wallets can automatically be discovered and interacted with from dApps.

If you are building a wallet, we publish a helper library `@mysten/wallet-standard` which provides types and utilities that make it simple to get started.
If you are building a wallet, we publish a helper library `@mysten/wallet-standard` which provides
types and utilities that make it simple to get started.

### Creating a wallet interface

Expand Down Expand Up @@ -43,11 +46,18 @@ wallet adapter, you must implement the following features in your wallet:
being added or removed.
- `sui:signPersonalMessage` - Used to prompt the user to sign a personal message, and return the
message signature back to the dApp. This can be used to verify the user’s public key.
- `sui:signTransactionBlock` - Used to prompt the user to sign a transaction block, and return the
serialized transaction block and signature back to the dApp. This method does not submit the
transaction block for execution.
- `sui:signAndExecuteTransactionBlock` - Used to prompt the user to sign a transaction, then submit
it for execution to the blockchain.
- `sui:signTransaction` - Used to prompt the user to sign a transaction, and return the serialized
transaction and signature back to the dApp. This method does not submit the transaction for
execution.
- `sui:signAndExecuteTransaction` - Used to prompt the user to sign a transaction, then submit it
for execution to the blockchain.
- `sui:reportTransactionEffects` - Used to report the effects of a transaction executed in the dApp
to the wallet. this allows the wallet to update it's internal state to reflect the changes made by
the transaction.
- `sui:signTransactionBlock` - The previous version of `sui:signTransaction`. It should still be
implemented for compatibility with dApps that have not updated to the new feature.
- `sui:signAndExecuteTransactionBlock` - The previous version of `sui:signAndExecuteTransaction`. It
should still be implemented for compatibility with dApps that have not updated to the new feature.

You can implement these features in your wallet class under the `features` property:

Expand All @@ -59,8 +69,9 @@ import {
EventsOnMethod,
SuiFeatures,
SuiSignPersonalMessageMethod,
SuiSignTransactionBlockMethod,
SuiSignAndExecuteTransactionBlockMethod
SuiSignTransactionMethod,
SuiSignAndExecuteTransactionMethod,
SuiReportTransactionEffectsMethod
} from "@mysten/wallet-standard";

class YourWallet implements Wallet {
Expand All @@ -80,14 +91,17 @@ class YourWallet implements Wallet {
version: "1.0.0",
signPersonalMessage: this.#signPersonalMessage,
},
"sui:signTransactionBlock": {
version: "1.0.0",
signTransactionBlock: this.#signTransactionBlock,
"sui:signTransaction": {
version: "2.0.0",
signTransaction: this.#signTransaction,
},
"sui:signAndExecuteTransactionBlock": {
version: "1.0.0",
signAndExecuteTransactionBlock: this.#signAndExecuteTransactionBlock,
"sui:signAndExecuteTransaction": {
version: "2.0.0",
signAndExecuteTransaction: this.#signAndExecuteTransactionBlock,
},
"sui:reportTransactionEffects": {
version: "1.0.0",
reportTransactionEffects: this.#reportTransactionEffects,
};
},

Expand All @@ -103,13 +117,17 @@ class YourWallet implements Wallet {
// Your wallet's signTransaction implementation
};

#signTransactionBlock: SuiSignTransactionBlockMethod = () => {
#signTransaction: SuiSignTransactionMethod = () => {
// Your wallet's signTransaction implementation
};

#signAndExecuteTransactionBlock: SuiSignAndExecuteTransactionBlockMethod = () => {
#signAndExecuteTransaction: SuiSignAndExecuteTransactionMethod = () => {
// Your wallet's signAndExecuteTransaction implementation
};

#reportTransactionEffects: SuiReportTransactionEffectsMethod = () => {
// Your wallet's reportTransactionEffects implementation
};
}
```
Expand Down Expand Up @@ -159,3 +177,38 @@ import { registerWallet } from '@mysten/wallet-standard';

registerWallet(new YourWallet());
```
### Best practices for efficient Transaction Execution
The wallet standard has recently been updated to reflect changes being implemented across the Sui
ecosystem. With the migration the new GraphQL API the previous `sui:signAndExecuteTransaction`
feature will become harder to maintain, and has been closely tied to the JSON RPC options and data
structures.
The new `sui:signAndExecuteTransaction` feature will be easier to implement for wallet builders
regardless of which API they are using to execute transactions. This simplicity comes at the expense
of flexibility in what is returned from the `sui:signAndExecuteTransaction` feature.
The solution to this problem is to use the `sui:signTransaction` feature to sign transactions, and
leave transaction execution up to the dApp, allowing it to query for additional data during
execution, using whichever API the dapp is using. This is consistent with the default we have used
in `@mysten/dapp-kit` for the `useSignAndExecuteTransaction` hook, and enables dApps to take
advantage of read-after-write consistency when interacting with the full-node based JSON RPC API.
The downside of this strategy has been that wallets end up using different RPC nodes than the dApp,
and may not have indexed the previous transaction when executing multiple transactions in rapid
succession. This leads to building transactions using stale data, that will fail when executed.
To mitigate this, wallets can use the `sui:reportTransactionEffects` feature so that apps can report
the effects of transactions to the wallet. Transaction effects contain the updated versions and
digests of any objects used or created in a transaction. By caching these values, wallets can build
transactions without needing to resolve the most recent versions through an API call.
The `@mysten/sui/transaction` SDK exports the `SerialTransactionExecutor` class, which can be used
to build Transaction using an object cache, and has a method to update it's internal cache using the
effects of a transaction.
Using the combination of `sui:signTransaction` and `sui:reportTransactionEffects` dApps can use
whichever API API they prefer to execute transactions, querying for whatever data the API exposes
for use in the dapp, and by reporting the effects of the transaction to the wallet, the wallet
should be able to execute transactions without running into issues caused by lagging indexer.
Loading

0 comments on commit 4675ee5

Please sign in to comment.