@msafe/sui-app-store 0.0.359 → 0.0.360
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +203 -60
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,56 +1,182 @@
|
|
|
1
1
|
# MSafe Sui App Store
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**This package is closed to new applications.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
New dApps integrate with MSafe the same way they integrate any Sui wallet: assemble a real `Transaction` and submit it through `@msafe/sui-wallet`. You do **not** add a helper under `src/apps/**`, open a pull request against this repository, or wait for an `@msafe/sui-app-store` release.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Existing helpers (Cetus, NAVI, MMT, mpay, `msafe-core`, `msafe-plain-tx`, and other already-registered apps) stay in this package for compatibility only. Do not extend them for new products.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
| Audience | What to read |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| New dApp / new listing | [Integrate a new dApp](#integrate-a-new-dapp) |
|
|
12
|
+
| Already listed with a helper | [Existing registered apps](#existing-registered-apps) |
|
|
13
|
+
| Historical helper guide | [Deprecated: helper-based integration](#deprecated-helper-based-integration) |
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
---
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
## Integrate a new dApp
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
Treat MSafe as a wallet-standard wallet inside the MSafe store iframe. Build the programmable transaction yourself. MSafe simulates it, collects multisig votes, and executes it. Transaction details for new apps use the generic payload view (simulation + raw transaction). There is no per-protocol “swap / deposit” card unless MSafe later ships one as a separate product request.
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
### 1. Register the MSafe wallet
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
- Initiate MSafe Wallet
|
|
21
|
-
- Connect to MSafe Wallet using `@mysten/dapp-kit`
|
|
22
|
-
- Sign transaction with MSafe Wallet (also using `@msafe/dapp-kit`)
|
|
23
|
+
Install `@msafe/sui-wallet` and register it with **your application name**. Use the same name you want to appear in MSafe history.
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
```ts
|
|
26
|
+
import { MSafeWallet } from '@msafe/sui-wallet';
|
|
27
|
+
import { registerWallet } from '@mysten/wallet-standard';
|
|
28
|
+
|
|
29
|
+
const rpcUrl = 'https://fullnode.mainnet.sui.io:443';
|
|
30
|
+
|
|
31
|
+
registerWallet(new MSafeWallet('your-app-name', rpcUrl, 'sui:mainnet'));
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Register once at app startup (typically `main.tsx`). Detect the iframe with `MSafeWallet.inMSafeWallet()` if you need different wallet UX inside MSafe versus a standalone page.
|
|
35
|
+
|
|
36
|
+
Connect with `@mysten/dapp-kit` (or any wallet-standard client) as you would for Slush or any other Sui wallet.
|
|
37
|
+
|
|
38
|
+
### 2. Submit a fully assembled transaction
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { Transaction } from '@mysten/sui/transactions';
|
|
42
|
+
|
|
43
|
+
const tx = new Transaction();
|
|
44
|
+
tx.setSender(multisigAddress);
|
|
45
|
+
// Add real commands. An empty Transaction is rejected.
|
|
46
|
+
tx.moveCall(/* ... */);
|
|
47
|
+
|
|
48
|
+
await dAppKit.signAndExecuteTransaction({ transaction: tx });
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Requirements:
|
|
52
|
+
|
|
53
|
+
| Rule | Detail |
|
|
54
|
+
| --- | --- |
|
|
55
|
+
| Real PTB | `tx.getData().commands.length > 0`. Do not send `new Transaction()`. |
|
|
56
|
+
| Sender | The connected MSafe **multisig** address. |
|
|
57
|
+
| No helper | Do not import `@msafe/sui-app-store`. Do not pass `appContext`. |
|
|
58
|
+
| Serialization | Prefer Mysten V2 (`Transaction` / `toJSON()`). Do not use V1 `serialize()`. |
|
|
59
|
+
|
|
60
|
+
`signAndExecuteTransaction` and `signTransaction` both **propose** the transaction to the MSafe queue. The Promise does **not** resolve with an on-chain digest. Owners approve and execute inside MSafe.
|
|
61
|
+
|
|
62
|
+
| Wallet API | Behavior |
|
|
63
|
+
| --- | --- |
|
|
64
|
+
| `signTransaction({ transaction })` | Propose. Preferred. |
|
|
65
|
+
| `signAndExecuteTransaction({ transaction })` | Same propose path. No digest in the result. |
|
|
66
|
+
| `signTransactionBlock` / `signAndExecuteTransactionBlock` | Legacy aliases. |
|
|
67
|
+
|
|
68
|
+
### 3. Empty and queued transactions
|
|
69
|
+
|
|
70
|
+
- An unregistered app that submits an empty transaction is rejected: *Empty transaction. Unregistered apps must pass a fully assembled Transaction (`commands.length > 0`). Do not send `new Transaction()`.*
|
|
71
|
+
- The store iframe allows **one** in-flight proposal at a time. If the multisig already has a pending transaction or future intentions, a new submit from the iframe is rejected until that queue is cleared.
|
|
72
|
+
|
|
73
|
+
### 4. List the app in the MSafe store
|
|
74
|
+
|
|
75
|
+
Listing is a **store card only**: name, icon, and URL. MSafe adds the card in the web app (`id` / `image` / `dappLink`). There is no adapter to write, no review of helper code, and no `@msafe/sui-app-store` publish.
|
|
76
|
+
|
|
77
|
+
Send the MSafe team:
|
|
78
|
+
|
|
79
|
+
- Application name (must match `new MSafeWallet('...')`)
|
|
80
|
+
- Icon
|
|
81
|
+
- Production dApp URL (the iframe `dappLink`)
|
|
82
|
+
|
|
83
|
+
After the card is live, users open your app from the MSafe store and sign with the flow above.
|
|
84
|
+
|
|
85
|
+
### Reference
|
|
86
|
+
|
|
87
|
+
A sample dApp that talks to MSafe as a wallet:
|
|
88
|
+
|
|
89
|
+
- Repository: https://github.com/Momentum-Safe/msafe-sui-app-arbitrary-transaction
|
|
90
|
+
- Live: https://sui-ptx.m-safe.io/
|
|
91
|
+
|
|
92
|
+
Follow the **wallet `Transaction` path** in that project. Do not copy helper / `appContext` patterns from older commits.
|
|
93
|
+
|
|
94
|
+
Wallet SDK notes: [`@msafe/sui-wallet`](https://github.com/Momentum-Safe/msafe-sui-wallet).
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Existing registered apps
|
|
99
|
+
|
|
100
|
+
Apps that already ship a helper in this package may keep the previous contract:
|
|
101
|
+
|
|
102
|
+
- Call `signTransaction` with an empty `Transaction` plus `appContext`, **or**
|
|
103
|
+
- Pass a real `Transaction` that the helper can `deserialize`.
|
|
25
104
|
|
|
26
|
-
|
|
105
|
+
Do not add new helpers for new features or new protocols. New work goes through [Integrate a new dApp](#integrate-a-new-dapp).
|
|
27
106
|
|
|
28
|
-
|
|
107
|
+
Frozen examples include Cetus, NAVI, MMT, mpay, `msafe-core`, and `msafe-plain-tx`.
|
|
29
108
|
|
|
30
|
-
|
|
31
|
-
- Create a new branch for your app development
|
|
32
|
-
- Create pull request for review
|
|
109
|
+
---
|
|
33
110
|
|
|
34
|
-
##
|
|
111
|
+
## This repository
|
|
35
112
|
|
|
36
|
-
|
|
37
|
-
There are two ways to integrate with the MSafe Sui App store:
|
|
113
|
+
`@msafe/sui-app-store` is a **compatibility library** for those frozen helpers. MSafe still publishes it when an already-listed helper needs a fix. It is not an onboarding surface.
|
|
38
114
|
|
|
39
|
-
|
|
115
|
+
- Do **not** create `src/apps/<your-app>`.
|
|
116
|
+
- Do **not** open a pull request to register a new helper.
|
|
117
|
+
- Do **not** wait on this package’s version to go live in the store.
|
|
40
118
|
|
|
41
|
-
|
|
119
|
+
---
|
|
42
120
|
|
|
43
|
-
|
|
121
|
+
## Deprecated: helper-based integration
|
|
44
122
|
|
|
45
|
-
|
|
123
|
+
> [!CAUTION]
|
|
124
|
+
> The remainder of this document is the previous contribution guide. It is **deprecated**. New dApps must not follow it. New pull requests that add helpers will not be accepted.
|
|
46
125
|
|
|
47
|
-
###
|
|
126
|
+
### ~~Background~~
|
|
48
127
|
|
|
49
|
-
|
|
128
|
+
~~Due to Sui blockchain version limitations, multisig account can't propose multiple transactions at the same time. It's needed to be create as transaction intention first and propose transaction 1 by 1 for vote & execution.~~
|
|
50
129
|
|
|
51
|
-
|
|
130
|
+
### ~~Overview~~
|
|
52
131
|
|
|
53
|
-
|
|
132
|
+
~~~~
|
|
133
|
+
|
|
134
|
+
### ~~Demos~~
|
|
135
|
+
|
|
136
|
+
~~We provide a demo dApp for MSafe app store integration. please refer below GitHub repository: https://github.com/Momentum-Safe/msafe-sui-app-arbitrary-transaction~~
|
|
137
|
+
|
|
138
|
+
~~In this demo, we implement a dApp that allows users to execute arbitrary transaction on Sui.~~
|
|
139
|
+
|
|
140
|
+
~~You can see how to implement with `@msafe/sui-app-store` in this demo.~~
|
|
141
|
+
|
|
142
|
+
~~Including:~~
|
|
143
|
+
|
|
144
|
+
- ~~Initiate MSafe Wallet~~
|
|
145
|
+
- ~~Connect to MSafe Wallet using `@mysten/dapp-kit`~~
|
|
146
|
+
- ~~Sign transaction with MSafe Wallet (also using `@msafe/dapp-kit`)~~
|
|
147
|
+
|
|
148
|
+
~~The main logic is implemented in `src/App.tsx`~~
|
|
149
|
+
|
|
150
|
+
~~Demo dApp: https://sui-ptx.m-safe.io/~~
|
|
151
|
+
|
|
152
|
+
### ~~How to contribute~~
|
|
153
|
+
|
|
154
|
+
- ~~Fork the repository~~
|
|
155
|
+
- ~~Create a new branch for your app development~~
|
|
156
|
+
- ~~Create pull request for review~~
|
|
157
|
+
|
|
158
|
+
### ~~How to develop~~
|
|
159
|
+
|
|
160
|
+
#### ~~Summary~~
|
|
161
|
+
|
|
162
|
+
~~There are two ways to integrate with the MSafe Sui App store:~~
|
|
163
|
+
|
|
164
|
+
1. ~~When dapp call signTransaction method, directly pass in the assembled Transaction (Transaction Block), and the user can then complete the subsequent transaction process.~~
|
|
165
|
+
2. ~~Through the create helper method (see below)~~
|
|
166
|
+
|
|
167
|
+
#### ~~Setup~~
|
|
168
|
+
|
|
169
|
+
- ~~Create your app folder under `src/apps/` folder~~
|
|
170
|
+
|
|
171
|
+
#### ~~Create intentions~~
|
|
172
|
+
|
|
173
|
+
- ~~Create your dapp intentions under `src/apps/<your app>` folder~~
|
|
174
|
+
|
|
175
|
+
~~Here is an example for transaction intention, if your dapp have multiple transaction types, you need to define 1 by 1 for each type of transaction intention.~~
|
|
176
|
+
|
|
177
|
+
~~If you are using @mysten/sui.js, you can refer to the following code:~~
|
|
178
|
+
|
|
179
|
+
Historical example — do not copy for new apps:
|
|
54
180
|
|
|
55
181
|
```typescript
|
|
56
182
|
import { SuiClient } from '@mysten/sui.js/client';
|
|
@@ -82,7 +208,9 @@ export class ExampleIntention extends BaseIntentionLegacy<ExampleIntentionData>
|
|
|
82
208
|
}
|
|
83
209
|
```
|
|
84
210
|
|
|
85
|
-
If you are using @mysten/sui, you can refer to the following code
|
|
211
|
+
~~If you are using @mysten/sui, you can refer to the following code:~~
|
|
212
|
+
|
|
213
|
+
Historical example — do not copy for new apps:
|
|
86
214
|
|
|
87
215
|
```typescript
|
|
88
216
|
import { SuiClient } from '@mysten/sui/client';
|
|
@@ -114,16 +242,18 @@ export class ExampleIntention extends BaseIntention<ExampleIntentionData> {
|
|
|
114
242
|
}
|
|
115
243
|
```
|
|
116
244
|
|
|
117
|
-
Each intention should have one data structure to store transaction information for future build
|
|
118
|
-
This structure can be defined according to your own business logic, it can be any type of data, (should be JSON serializable)
|
|
245
|
+
~~Each intention should have one data structure to store transaction information for future build.~~
|
|
246
|
+
~~This structure can be defined according to your own business logic, it can be any type of data, (should be JSON serializable)~~
|
|
119
247
|
|
|
120
|
-
Transaction intention implement mainly one API `build(): Promise<TransactionBlock>` which will build Sui transaction block from your defined business data
|
|
248
|
+
~~Transaction intention implement mainly one API `build(): Promise<TransactionBlock>` which will build Sui transaction block from your defined business data.~~
|
|
121
249
|
|
|
122
|
-
|
|
250
|
+
#### ~~Create helper~~
|
|
123
251
|
|
|
124
|
-
- Create helper ts at `src/apps/<your app>/intention.ts
|
|
252
|
+
- ~~Create helper ts at `src/apps/<your app>/intention.ts`~~
|
|
125
253
|
|
|
126
|
-
Here is an example of intention.ts file
|
|
254
|
+
~~Here is an example of intention.ts file~~
|
|
255
|
+
|
|
256
|
+
Historical example — do not copy for new apps:
|
|
127
257
|
|
|
128
258
|
```typescript
|
|
129
259
|
export type CoreIntention = CoinTransferIntention | ObjectTransferIntention;
|
|
@@ -165,13 +295,15 @@ export class CoreHelper implements IAppHelperInternalLegacy<CoreIntention, CoreI
|
|
|
165
295
|
}
|
|
166
296
|
```
|
|
167
297
|
|
|
168
|
-
The helper is responsible for convert a transaction block to your own transaction intention business data. this is call by SuiWallet standard API `sui:signTransactionBlock` feature
|
|
298
|
+
~~The helper is responsible for convert a transaction block to your own transaction intention business data. this is call by SuiWallet standard API `sui:signTransactionBlock` feature.~~
|
|
299
|
+
|
|
300
|
+
#### ~~Write test for your business logic~~
|
|
169
301
|
|
|
170
|
-
|
|
302
|
+
- ~~Create your test at `test/<your app>.test.ts`~~
|
|
171
303
|
|
|
172
|
-
|
|
304
|
+
~~You can follow be example to write test~~
|
|
173
305
|
|
|
174
|
-
|
|
306
|
+
Historical example — do not copy for new apps:
|
|
175
307
|
|
|
176
308
|
```typescript
|
|
177
309
|
import { TransactionType } from '@msafe/sui3-utils';
|
|
@@ -214,9 +346,11 @@ describe('MSafe Core Wallet', () => {
|
|
|
214
346
|
});
|
|
215
347
|
```
|
|
216
348
|
|
|
217
|
-
|
|
349
|
+
#### ~~App custom parameters~~
|
|
218
350
|
|
|
219
|
-
- You can pass custom parameters into the `appContext` parameter of the Helper.deserialize method
|
|
351
|
+
- ~~You can pass custom parameters into the `appContext` parameter of the Helper.deserialize method.~~
|
|
352
|
+
|
|
353
|
+
Historical example — do not copy for new apps:
|
|
220
354
|
|
|
221
355
|
```typescript
|
|
222
356
|
deserialize(input: {
|
|
@@ -233,9 +367,11 @@ deserialize(input: {
|
|
|
233
367
|
}>;
|
|
234
368
|
```
|
|
235
369
|
|
|
236
|
-
- When implementing your app's `Helper.deserialize`, you can write your business logic based on the custom parameters you've passed in
|
|
370
|
+
- ~~When implementing your app's `Helper.deserialize`, you can write your business logic based on the custom parameters you've passed in.~~
|
|
371
|
+
|
|
372
|
+
- ~~For reference, you can review the implementation logic demo code below.~~
|
|
237
373
|
|
|
238
|
-
|
|
374
|
+
Historical example — do not copy for new apps:
|
|
239
375
|
|
|
240
376
|
```typescript
|
|
241
377
|
export class DemoHelper implements IAppHelperInternal<DemoIntentionData> {
|
|
@@ -262,22 +398,27 @@ async deserialize(input: {
|
|
|
262
398
|
};
|
|
263
399
|
}
|
|
264
400
|
|
|
265
|
-
...
|
|
401
|
+
...
|
|
266
402
|
|
|
403
|
+
}
|
|
267
404
|
```
|
|
268
405
|
|
|
269
|
-
|
|
406
|
+
#### ~~Register your app helper~~
|
|
270
407
|
|
|
271
|
-
- Add your app helper to file `src/index.ts
|
|
408
|
+
- ~~Add your app helper to file `src/index.ts`~~
|
|
409
|
+
|
|
410
|
+
Historical example — do not copy for new apps:
|
|
272
411
|
|
|
273
412
|
```typescript
|
|
274
413
|
export const appHelpers = new MSafeApps([new CoreHelper(), <your app helper instance here>]);
|
|
275
414
|
```
|
|
276
415
|
|
|
277
|
-
|
|
416
|
+
#### ~~Test your integration with our test framework `TestSuite`~~
|
|
417
|
+
|
|
418
|
+
- ~~before create pull request, you should test your helper with test suite, add at least one test case before creating the PR.~~
|
|
419
|
+
- ~~here is an example for using test suite to test your helper~~
|
|
278
420
|
|
|
279
|
-
|
|
280
|
-
- here is an example for using test suite to test your helper
|
|
421
|
+
Historical example — do not copy for new apps:
|
|
281
422
|
|
|
282
423
|
```typescript
|
|
283
424
|
import { TestSuite, TestSuiteLegacy } from './TestSuite';
|
|
@@ -292,7 +433,7 @@ describe('Main flow', () => {
|
|
|
292
433
|
|
|
293
434
|
// Choose one of the following to instantiate TestSuite according to your implementation (helper.supportSDK: @mysten/sui or @mysten/sui.js)
|
|
294
435
|
// Instantiate TestSuite with your test wallet, network, and the app helper(implement with @mysten/sui)
|
|
295
|
-
|
|
436
|
+
|
|
296
437
|
let ts: TestSuite<YourIntentionData>;
|
|
297
438
|
|
|
298
439
|
// (implement with @mysten/sui.js)
|
|
@@ -336,19 +477,21 @@ describe('Main flow', () => {
|
|
|
336
477
|
});
|
|
337
478
|
});
|
|
338
479
|
```
|
|
339
|
-
You can refer to `test/core.test.ts` for more details implementation.
|
|
340
480
|
|
|
481
|
+
~~You can refer to `test/core.test.ts` for more details implementation.~~
|
|
482
|
+
|
|
483
|
+
#### ~~Create pull request for submit~~
|
|
341
484
|
|
|
342
|
-
|
|
485
|
+
~~Once you finish development, you can create a PR to submit your changes.~~
|
|
343
486
|
|
|
344
|
-
|
|
487
|
+
### ~~Integrate MSafe wallet with your app~~
|
|
345
488
|
|
|
346
|
-
|
|
489
|
+
~~The last step is to integrate MSafe wallet with your application~~
|
|
347
490
|
|
|
348
|
-
|
|
491
|
+
- ~~Run command `yarn add @msafe/sui-wallet` to add MSafe wallet package to your project~~
|
|
492
|
+
- ~~Add below code to your application, basically it should be added to your `main.tsx` file~~
|
|
349
493
|
|
|
350
|
-
|
|
351
|
-
- Add below code to your application, basically it should be added to your `main.tsx` file
|
|
494
|
+
Historical example — superseded by [Register the MSafe wallet](#1-register-the-msafe-wallet). The constructor also requires `rpcUrl` and `network`:
|
|
352
495
|
|
|
353
496
|
```typescript
|
|
354
497
|
import { MSafeWallet } from '@msafe/sui-wallet';
|
|
@@ -357,6 +500,6 @@ import { registerWallet } from '@mysten/wallet-standard';
|
|
|
357
500
|
registerWallet(new MSafeWallet('<your app name>'));
|
|
358
501
|
```
|
|
359
502
|
|
|
360
|
-
|
|
503
|
+
#### ~~Next Step~~
|
|
361
504
|
|
|
362
|
-
Once the development mentioned above is complete, MSafe team will assist in verifying the integration. Feedback will be provided to your team upon completion of the verification process
|
|
505
|
+
~~Once the development mentioned above is complete, MSafe team will assist in verifying the integration. Feedback will be provided to your team upon completion of the verification process.~~
|