@msafe/sui-app-store 0.0.361 → 0.0.362
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 +135 -115
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,127 +1,196 @@
|
|
|
1
1
|
# MSafe Sui App Store
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img alt="Helper integration deprecated" src="https://img.shields.io/badge/helper_PRs-DEPRECATED-dc2626?style=for-the-badge">
|
|
5
|
+
<img alt="Closed to new apps" src="https://img.shields.io/badge/this_repo-CLOSED_to_new_apps-111827?style=for-the-badge">
|
|
6
|
+
<img alt="New path" src="https://img.shields.io/badge/new_dApps-submit_a_real_Transaction-059669?style=for-the-badge">
|
|
7
|
+
</p>
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
<table>
|
|
10
|
+
<tr>
|
|
11
|
+
<td align="center">
|
|
6
12
|
|
|
7
|
-
|
|
13
|
+
### This repository is not an onboarding surface
|
|
8
14
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
**Writing a helper, forking `src/apps/**`, or opening a PR here will not list your dApp.**
|
|
16
|
+
|
|
17
|
+
MSafe no longer accepts new App Store adapters. Integrate the same way you integrate Slush: build a real Sui `Transaction` in your dApp and submit it with `@msafe/sui-wallet`.
|
|
18
|
+
|
|
19
|
+
**If you already started the old helper work → [How to change your dApp](#how-to-change-your-dapp)**
|
|
20
|
+
**If you are new → [Current integration](#current-integration)**
|
|
21
|
+
|
|
22
|
+
</td>
|
|
23
|
+
</tr>
|
|
24
|
+
</table>
|
|
25
|
+
|
|
26
|
+
> [!CAUTION]
|
|
27
|
+
> **DEPRECATED:** `BaseIntention`, `IAppHelperInternal`, `src/apps/<your-app>`, `appContext`, and “fork this repo + wait for our release” are retired for **all new listings**.
|
|
28
|
+
>
|
|
29
|
+
> New helper PRs will **not** be merged. Waiting for `@msafe/sui-app-store` to publish will **not** unblock you.
|
|
30
|
+
|
|
31
|
+
> [!IMPORTANT]
|
|
32
|
+
> **Do this instead:** assemble the PTB yourself → `registerWallet(new MSafeWallet('your-app-name', rpcUrl, network))` → `signAndExecuteTransaction({ transaction: tx })`. Ask MSafe only for a store **card** (name, icon, URL).
|
|
14
33
|
|
|
15
34
|
---
|
|
16
35
|
|
|
17
|
-
##
|
|
36
|
+
## How to change your dApp
|
|
18
37
|
|
|
19
|
-
|
|
38
|
+
Use this section if your team followed the old README: created an intention class, a helper, `appContext`, or a PR against this repo.
|
|
20
39
|
|
|
21
|
-
###
|
|
40
|
+
### Stop / start
|
|
41
|
+
|
|
42
|
+
| Stop (deprecated) | Start (required) |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| ~~`yarn add @msafe/sui-app-store`~~ / import `appHelpers` | Delete the dependency. Your dApp must not import this package. |
|
|
45
|
+
| ~~`src/apps/<your-app>` intention + helper~~ | Delete the fork / local helper. MSafe will not review or ship it. |
|
|
46
|
+
| ~~Open a PR to register `new YourHelper()` in `src/index.ts`~~ | Close the PR. Listing is a store card, not a helper publish. |
|
|
47
|
+
| ~~`signTransaction({ transaction: new Transaction(), appContext })`~~ | Pass a **fully built** `Transaction` (`commands.length > 0`). **No `appContext`.** |
|
|
48
|
+
| ~~Wait for MSafe to release `@msafe/sui-app-store`~~ | Ship your dApp. Then send name / icon / URL for the card. |
|
|
49
|
+
| ~~`new MSafeWallet('app')` only~~ | `new MSafeWallet('your-app-name', rpcUrl, 'sui:mainnet')` |
|
|
22
50
|
|
|
23
|
-
|
|
51
|
+
### Before → after
|
|
52
|
+
|
|
53
|
+
**1. Wallet registration**
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
// DEPRECATED — incomplete constructor, often paired with a helper name
|
|
57
|
+
registerWallet(new MSafeWallet('your-app-name'));
|
|
58
|
+
```
|
|
24
59
|
|
|
25
60
|
```ts
|
|
61
|
+
// REQUIRED
|
|
26
62
|
import { MSafeWallet } from '@msafe/sui-wallet';
|
|
27
63
|
import { registerWallet } from '@mysten/wallet-standard';
|
|
28
64
|
|
|
29
|
-
const rpcUrl = 'https://fullnode.mainnet.sui.io:443';
|
|
30
|
-
|
|
31
65
|
registerWallet(new MSafeWallet('your-app-name', rpcUrl, 'sui:mainnet'));
|
|
32
66
|
```
|
|
33
67
|
|
|
34
|
-
|
|
68
|
+
Use the **same** `your-app-name` in history and in the store card.
|
|
35
69
|
|
|
36
|
-
|
|
70
|
+
**2. Submit**
|
|
37
71
|
|
|
38
|
-
|
|
72
|
+
```ts
|
|
73
|
+
// DEPRECATED — empty PTB + helper payload. Unregistered apps are rejected.
|
|
74
|
+
await signAndExecuteTransaction({
|
|
75
|
+
transaction: new Transaction(),
|
|
76
|
+
appContext: { action: 'swap', txbParams },
|
|
77
|
+
});
|
|
78
|
+
```
|
|
39
79
|
|
|
40
80
|
```ts
|
|
81
|
+
// REQUIRED — same Transaction you would send to Slush / any wallet
|
|
41
82
|
import { Transaction } from '@mysten/sui/transactions';
|
|
42
83
|
|
|
43
84
|
const tx = new Transaction();
|
|
44
|
-
tx.setSender(multisigAddress);
|
|
45
|
-
//
|
|
46
|
-
tx.moveCall(/* ... */);
|
|
85
|
+
tx.setSender(multisigAddress); // connected MSafe account
|
|
86
|
+
// ...real moveCall / transfer / SDK calls — commands.length must be > 0
|
|
47
87
|
|
|
48
88
|
await dAppKit.signAndExecuteTransaction({ transaction: tx });
|
|
89
|
+
// Do not pass appContext.
|
|
49
90
|
```
|
|
50
91
|
|
|
51
|
-
|
|
92
|
+
**3. Remove helper-only code**
|
|
52
93
|
|
|
53
|
-
|
|
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()`. |
|
|
94
|
+
Search the dApp and delete:
|
|
59
95
|
|
|
60
|
-
|
|
96
|
+
- `from '@msafe/sui-app-store'`
|
|
97
|
+
- `appContext`
|
|
98
|
+
- `BaseIntention` / `YourHelper` / `deserialize` / `intentionData`
|
|
99
|
+
- empty `new Transaction()` built only so the helper can `build()` later
|
|
61
100
|
|
|
62
|
-
|
|
63
|
-
| --- | --- |
|
|
64
|
-
| `signTransaction({ transaction })` | Propose. Preferred. |
|
|
65
|
-
| `signAndExecuteTransaction({ transaction })` | Same propose path. No digest in the result. |
|
|
66
|
-
| `signTransactionBlock` / `signAndExecuteTransactionBlock` | Legacy aliases. |
|
|
101
|
+
Keep your protocol SDK (Cetus SDK, NAVI SDK, your own `moveCall`s). Those already produce a `Transaction`. Submit **that** object.
|
|
67
102
|
|
|
68
|
-
###
|
|
103
|
+
### Migration checklist
|
|
69
104
|
|
|
70
|
-
-
|
|
71
|
-
-
|
|
105
|
+
- [ ] Remove `@msafe/sui-app-store` from `package.json`
|
|
106
|
+
- [ ] Register `MSafeWallet` with **name + RPC URL + network**
|
|
107
|
+
- [ ] Connect via `@mysten/dapp-kit` (or wallet-standard) as you do for other wallets
|
|
108
|
+
- [ ] Every MSafe sign path sends a PTB with **at least one command**
|
|
109
|
+
- [ ] No `appContext` on `signTransaction` / `signAndExecuteTransaction`
|
|
110
|
+
- [ ] `tx.setSender` is the **multisig** address (the connected MSafe account)
|
|
111
|
+
- [ ] Close any helper PR against this repository
|
|
112
|
+
- [ ] Send MSafe: app name, icon, production URL — for the store card only
|
|
72
113
|
|
|
73
|
-
|
|
114
|
+
`signAndExecuteTransaction` **proposes** to the multisig queue. It does **not** return an on-chain digest. Owners vote and execute in MSafe.
|
|
74
115
|
|
|
75
|
-
|
|
116
|
+
Empty `new Transaction()` from an unregistered app is rejected:
|
|
76
117
|
|
|
77
|
-
|
|
118
|
+
> Empty transaction. Unregistered apps must pass a fully assembled Transaction (`commands.length > 0`). Do not send `new Transaction()`.
|
|
78
119
|
|
|
79
|
-
|
|
80
|
-
- Icon
|
|
81
|
-
- Production dApp URL (the iframe `dappLink`)
|
|
120
|
+
---
|
|
82
121
|
|
|
83
|
-
|
|
122
|
+
## Current integration
|
|
84
123
|
|
|
85
|
-
|
|
124
|
+
```mermaid
|
|
125
|
+
flowchart LR
|
|
126
|
+
A[Your dApp builds a real Transaction] --> B["MSafeWallet signAndExecuteTransaction"]
|
|
127
|
+
B --> C[MSafe simulates]
|
|
128
|
+
C --> D[Owners vote in MSafe]
|
|
129
|
+
D --> E[Execute on chain]
|
|
130
|
+
```
|
|
86
131
|
|
|
87
|
-
|
|
132
|
+
Inside the MSafe store iframe, treat MSafe as a normal wallet. You own the PTB. MSafe owns simulate → vote → execute. New apps use the generic payload view (simulation + raw transaction), not a custom “swap / deposit” card.
|
|
88
133
|
|
|
89
|
-
|
|
90
|
-
- Live: https://sui-ptx.m-safe.io/
|
|
134
|
+
### 1. Register the wallet
|
|
91
135
|
|
|
92
|
-
|
|
136
|
+
```ts
|
|
137
|
+
import { MSafeWallet } from '@msafe/sui-wallet';
|
|
138
|
+
import { registerWallet } from '@mysten/wallet-standard';
|
|
139
|
+
|
|
140
|
+
registerWallet(new MSafeWallet('your-app-name', rpcUrl, 'sui:mainnet'));
|
|
141
|
+
```
|
|
93
142
|
|
|
94
|
-
|
|
143
|
+
Call this once at startup (`main.tsx`). Use `MSafeWallet.inMSafeWallet()` if the page should behave differently inside the iframe versus standalone.
|
|
95
144
|
|
|
96
|
-
|
|
145
|
+
### 2. Submit the transaction
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
await dAppKit.signAndExecuteTransaction({ transaction: tx });
|
|
149
|
+
```
|
|
97
150
|
|
|
98
|
-
|
|
151
|
+
| Rule | Detail |
|
|
152
|
+
| --- | --- |
|
|
153
|
+
| Real PTB | `tx.getData().commands.length > 0` |
|
|
154
|
+
| Sender | Connected MSafe **multisig** |
|
|
155
|
+
| No helper | Do not import this package. Do not pass `appContext`. |
|
|
156
|
+
| Encoding | Mysten V2 `Transaction` / `toJSON()`. Do not use V1 `serialize()`. |
|
|
99
157
|
|
|
100
|
-
|
|
158
|
+
| API | Behavior |
|
|
159
|
+
| --- | --- |
|
|
160
|
+
| `signTransaction({ transaction })` | Propose. Preferred. |
|
|
161
|
+
| `signAndExecuteTransaction({ transaction })` | Same propose path. **No digest** in the result. |
|
|
162
|
+
| `signTransactionBlock` / `signAndExecuteTransactionBlock` | Legacy aliases. |
|
|
101
163
|
|
|
102
|
-
-
|
|
103
|
-
- Pass a real `Transaction` that the helper can `deserialize`.
|
|
164
|
+
The store iframe accepts **one** in-flight proposal. If the multisig already has a pending transaction or future intentions, a new submit is rejected until that queue is cleared.
|
|
104
165
|
|
|
105
|
-
|
|
166
|
+
### 3. List in the store
|
|
106
167
|
|
|
107
|
-
|
|
168
|
+
Listing is a **card**: name, icon, URL. MSafe adds `id` / `image` / `dappLink` on the web app. There is no adapter review and no `@msafe/sui-app-store` release on the critical path.
|
|
169
|
+
|
|
170
|
+
### Reference
|
|
171
|
+
|
|
172
|
+
- Wallet SDK: https://github.com/Momentum-Safe/msafe-sui-wallet
|
|
173
|
+
- Sample dApp: https://github.com/Momentum-Safe/msafe-sui-app-arbitrary-transaction — follow the **wallet `Transaction`** path, not old `appContext` commits
|
|
174
|
+
- Live sample: https://sui-ptx.m-safe.io/
|
|
108
175
|
|
|
109
176
|
---
|
|
110
177
|
|
|
111
|
-
##
|
|
178
|
+
## Already-listed apps with a helper
|
|
112
179
|
|
|
113
|
-
|
|
180
|
+
Cetus, NAVI, MMT, mpay, `msafe-core`, `msafe-plain-tx`, and other **already registered** helpers may keep empty PTB + `appContext` until they migrate.
|
|
114
181
|
|
|
115
|
-
- Do
|
|
116
|
-
-
|
|
117
|
-
|
|
182
|
+
- Do not add helpers for **new** products or new protocols.
|
|
183
|
+
- New features on a listed brand should still use [How to change your dApp](#how-to-change-your-dapp) when you can.
|
|
184
|
+
|
|
185
|
+
This package remains a **compatibility library** only. MSafe may still publish it to patch an existing helper. That is not how new apps go live.
|
|
118
186
|
|
|
119
187
|
---
|
|
120
188
|
|
|
121
|
-
|
|
189
|
+
<details>
|
|
190
|
+
<summary><strong>⛔ DEPRECATED archive — old helper guide (do not follow)</strong></summary>
|
|
122
191
|
|
|
123
192
|
> [!CAUTION]
|
|
124
|
-
>
|
|
193
|
+
> Everything below is the previous contribution guide. It is **deprecated** and kept only so reviewers can see what was retired. **Do not copy it.** Jump back to [How to change your dApp](#how-to-change-your-dapp).
|
|
125
194
|
|
|
126
195
|
### ~~Background~~
|
|
127
196
|
|
|
@@ -176,7 +245,7 @@ Frozen examples include Cetus, NAVI, MMT, mpay, `msafe-core`, and `msafe-plain-t
|
|
|
176
245
|
|
|
177
246
|
~~If you are using @mysten/sui.js, you can refer to the following code:~~
|
|
178
247
|
|
|
179
|
-
Historical example — do not copy
|
|
248
|
+
~~Historical example — do not copy:~~
|
|
180
249
|
|
|
181
250
|
```typescript
|
|
182
251
|
import { SuiClient } from '@mysten/sui.js/client';
|
|
@@ -210,8 +279,6 @@ export class ExampleIntention extends BaseIntentionLegacy<ExampleIntentionData>
|
|
|
210
279
|
|
|
211
280
|
~~If you are using @mysten/sui, you can refer to the following code:~~
|
|
212
281
|
|
|
213
|
-
Historical example — do not copy for new apps:
|
|
214
|
-
|
|
215
282
|
```typescript
|
|
216
283
|
import { SuiClient } from '@mysten/sui/client';
|
|
217
284
|
import { Transaction } from '@mysten/sui/transactions';
|
|
@@ -251,10 +318,6 @@ export class ExampleIntention extends BaseIntention<ExampleIntentionData> {
|
|
|
251
318
|
|
|
252
319
|
- ~~Create helper ts at `src/apps/<your app>/intention.ts`~~
|
|
253
320
|
|
|
254
|
-
~~Here is an example of intention.ts file~~
|
|
255
|
-
|
|
256
|
-
Historical example — do not copy for new apps:
|
|
257
|
-
|
|
258
321
|
```typescript
|
|
259
322
|
export type CoreIntention = CoinTransferIntention | ObjectTransferIntention;
|
|
260
323
|
|
|
@@ -301,10 +364,6 @@ export class CoreHelper implements IAppHelperInternalLegacy<CoreIntention, CoreI
|
|
|
301
364
|
|
|
302
365
|
- ~~Create your test at `test/<your app>.test.ts`~~
|
|
303
366
|
|
|
304
|
-
~~You can follow be example to write test~~
|
|
305
|
-
|
|
306
|
-
Historical example — do not copy for new apps:
|
|
307
|
-
|
|
308
367
|
```typescript
|
|
309
368
|
import { TransactionType } from '@msafe/sui3-utils';
|
|
310
369
|
|
|
@@ -350,8 +409,6 @@ describe('MSafe Core Wallet', () => {
|
|
|
350
409
|
|
|
351
410
|
- ~~You can pass custom parameters into the `appContext` parameter of the Helper.deserialize method.~~
|
|
352
411
|
|
|
353
|
-
Historical example — do not copy for new apps:
|
|
354
|
-
|
|
355
412
|
```typescript
|
|
356
413
|
deserialize(input: {
|
|
357
414
|
transaction: Transaction;
|
|
@@ -369,10 +426,6 @@ deserialize(input: {
|
|
|
369
426
|
|
|
370
427
|
- ~~When implementing your app's `Helper.deserialize`, you can write your business logic based on the custom parameters you've passed in.~~
|
|
371
428
|
|
|
372
|
-
- ~~For reference, you can review the implementation logic demo code below.~~
|
|
373
|
-
|
|
374
|
-
Historical example — do not copy for new apps:
|
|
375
|
-
|
|
376
429
|
```typescript
|
|
377
430
|
export class DemoHelper implements IAppHelperInternal<DemoIntentionData> {
|
|
378
431
|
|
|
@@ -407,8 +460,6 @@ async deserialize(input: {
|
|
|
407
460
|
|
|
408
461
|
- ~~Add your app helper to file `src/index.ts`~~
|
|
409
462
|
|
|
410
|
-
Historical example — do not copy for new apps:
|
|
411
|
-
|
|
412
463
|
```typescript
|
|
413
464
|
export const appHelpers = new MSafeApps([new CoreHelper(), <your app helper instance here>]);
|
|
414
465
|
```
|
|
@@ -416,9 +467,6 @@ export const appHelpers = new MSafeApps([new CoreHelper(), <your app helper inst
|
|
|
416
467
|
#### ~~Test your integration with our test framework `TestSuite`~~
|
|
417
468
|
|
|
418
469
|
- ~~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~~
|
|
420
|
-
|
|
421
|
-
Historical example — do not copy for new apps:
|
|
422
470
|
|
|
423
471
|
```typescript
|
|
424
472
|
import { TestSuite, TestSuiteLegacy } from './TestSuite';
|
|
@@ -431,12 +479,7 @@ describe('Main flow', () => {
|
|
|
431
479
|
features: [],
|
|
432
480
|
};
|
|
433
481
|
|
|
434
|
-
// Choose one of the following to instantiate TestSuite according to your implementation (helper.supportSDK: @mysten/sui or @mysten/sui.js)
|
|
435
|
-
// Instantiate TestSuite with your test wallet, network, and the app helper(implement with @mysten/sui)
|
|
436
|
-
|
|
437
482
|
let ts: TestSuite<YourIntentionData>;
|
|
438
|
-
|
|
439
|
-
// (implement with @mysten/sui.js)
|
|
440
483
|
let ts: TestSuiteLegacy<YourIntentionData>;
|
|
441
484
|
|
|
442
485
|
beforeEach(() => {
|
|
@@ -445,11 +488,7 @@ describe('Main flow', () => {
|
|
|
445
488
|
|
|
446
489
|
describe('overall flow', () => {
|
|
447
490
|
it('overall flow', async () => {
|
|
448
|
-
// Mock application and user behavior
|
|
449
491
|
const appTxb = new TransactionBlock();
|
|
450
|
-
// ...
|
|
451
|
-
// programming your transaction block here
|
|
452
|
-
// ...
|
|
453
492
|
await ts.signAndSubmitTransaction({ txb: appTxb, appContext: {
|
|
454
493
|
// ... your app context here, will be passed to your helper.deserialize method
|
|
455
494
|
} });
|
|
@@ -458,23 +497,6 @@ describe('Main flow', () => {
|
|
|
458
497
|
expect(finalizedTxb).toBeDefined();
|
|
459
498
|
});
|
|
460
499
|
});
|
|
461
|
-
|
|
462
|
-
it('deserialize', async () => {
|
|
463
|
-
const appTxb = new TransactionBlock();
|
|
464
|
-
// ...
|
|
465
|
-
// programming your transaction block here
|
|
466
|
-
// ...
|
|
467
|
-
await ts.signAndSubmitTransaction({ txb: appTxb });
|
|
468
|
-
|
|
469
|
-
expect(ts.pendingIntention).toBeDefined();
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
it('build', async () => {
|
|
473
|
-
ts.setIntention({} as any);
|
|
474
|
-
const txb = await ts.voteAndExecuteIntention();
|
|
475
|
-
|
|
476
|
-
expect(txb).toBeDefined();
|
|
477
|
-
});
|
|
478
500
|
});
|
|
479
501
|
```
|
|
480
502
|
|
|
@@ -486,13 +508,9 @@ describe('Main flow', () => {
|
|
|
486
508
|
|
|
487
509
|
### ~~Integrate MSafe wallet with your app~~
|
|
488
510
|
|
|
489
|
-
~~The last step is to integrate MSafe wallet with your application~~
|
|
490
|
-
|
|
491
511
|
- ~~Run command `yarn add @msafe/sui-wallet` to add MSafe wallet package to your project~~
|
|
492
512
|
- ~~Add below code to your application, basically it should be added to your `main.tsx` file~~
|
|
493
513
|
|
|
494
|
-
Historical example — superseded by [Register the MSafe wallet](#1-register-the-msafe-wallet). The constructor also requires `rpcUrl` and `network`:
|
|
495
|
-
|
|
496
514
|
```typescript
|
|
497
515
|
import { MSafeWallet } from '@msafe/sui-wallet';
|
|
498
516
|
import { registerWallet } from '@mysten/wallet-standard';
|
|
@@ -503,3 +521,5 @@ registerWallet(new MSafeWallet('<your app name>'));
|
|
|
503
521
|
#### ~~Next Step~~
|
|
504
522
|
|
|
505
523
|
~~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.~~
|
|
524
|
+
|
|
525
|
+
</details>
|