@msafe/sui-app-store 0.0.361 → 0.0.363

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.
Files changed (2) hide show
  1. package/README.md +163 -115
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,127 +1,224 @@
1
1
  # MSafe Sui App Store
2
2
 
3
- **This package is closed to new applications.**
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
- 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.
9
+ <table>
10
+ <tr>
11
+ <td align="center">
6
12
 
7
- Existing helpers stay in this package for compatibility only. Do not extend them for new products.
13
+ ### Integration is now the same as any Sui wallet
8
14
 
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) |
15
+ You **do not write a helper**. You **do not wait for this package to publish**. You build a real `Transaction` in your dApp — the same object you already send to Slush — and submit it with `@msafe/sui-wallet`.
16
+
17
+ Writing a helper, forking `src/apps/**`, or opening a PR here will **not** list your dApp.
18
+
19
+ **New listing [What you gain](#what-you-gain-in-this-version)** then [Current integration](#current-integration)
20
+ **Already started a helper → [How to change your dApp](#how-to-change-your-dapp)**
21
+
22
+ </td>
23
+ </tr>
24
+ </table>
25
+
26
+ > [!TIP]
27
+ > **This version’s point:** drop the adapter. If your dApp can sign with a normal wallet, it can sign with MSafe. Listing is a store card (name, icon, URL), usually done in a day — not a week of helper review and an MSafe release.
14
28
 
15
29
  ---
16
30
 
17
- ## Integrate a new dApp
31
+ ## What you gain in this version
32
+
33
+ The old path existed because a queued multisig tx had to be **rebuilt** later, so every protocol needed an MSafe-owned helper. That is no longer how new apps enter the store. You submit the finished transaction once; MSafe simulates, votes, and executes **that** PTB.
34
+
35
+ | | ~~Before (helper)~~ | **Now (wallet `Transaction`)** |
36
+ | --- | --- | --- |
37
+ | What you write | Intention class + `deserialize` / `build` + tests + PR in **this** repo | The PTB you already build for other wallets |
38
+ | Extra dependency | `@msafe/sui-app-store` + `appContext` | `@msafe/sui-wallet` only |
39
+ | Who ships your adapter | MSafe reviews, merges, and **publishes a new app-store version** | **Nobody.** There is no adapter. |
40
+ | Time to first live tx | Often **weeks** (review + our release train) | **Days** — usually the time to wire the wallet and send a card |
41
+ | Blocked on | Our sprint, this repo’s CI, npm publish | Your own PTB being correct |
42
+ | Mysten / protocol SDK upgrades | Helper in this repo had to follow; you waited on us | You upgrade **your** dApp; we are not in the loop |
43
+ | Three new protocols at once | Three helper PRs, serialized on our side | Three teams in parallel; we only add three cards |
44
+
45
+ **You delete work, you do not add a new integration style.**
46
+
47
+ - No `BaseIntention` / `YourHelper` / `src/apps/<name>`
48
+ - No empty `new Transaction()` + `appContext` so we can rebuild later
49
+ - No “please merge our helper” email
50
+ - No holding a launch for `@msafe/sui-app-store@x.y.z`
51
+
52
+ Users still get the full multisig flow (simulate → approve → execute). New apps use a generic transaction view instead of a custom swap card. That is the trade for **not** being on our release calendar.
53
+
54
+ > [!CAUTION]
55
+ > **DEPRECATED:** `BaseIntention`, `IAppHelperInternal`, `src/apps/<your-app>`, `appContext`, and “fork this repo + wait for our release” are retired for **all new listings**.
56
+ >
57
+ > New helper PRs will **not** be merged. Waiting for `@msafe/sui-app-store` to publish will **not** unblock you.
58
+
59
+ > [!IMPORTANT]
60
+ > **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).
61
+
62
+ ---
63
+
64
+ ## How to change your dApp
65
+
66
+ Use this section if your team followed the old README: created an intention class, a helper, `appContext`, or a PR against this repo.
67
+
68
+ ### Stop / start
69
+
70
+ | Stop (deprecated) | Start (required) |
71
+ | --- | --- |
72
+ | ~~`yarn add @msafe/sui-app-store`~~ / import `appHelpers` | Delete the dependency. Your dApp must not import this package. |
73
+ | ~~`src/apps/<your-app>` intention + helper~~ | Delete the fork / local helper. MSafe will not review or ship it. |
74
+ | ~~Open a PR to register `new YourHelper()` in `src/index.ts`~~ | Close the PR. Listing is a store card, not a helper publish. |
75
+ | ~~`signTransaction({ transaction: new Transaction(), appContext })`~~ | Pass a **fully built** `Transaction` (`commands.length > 0`). **No `appContext`.** |
76
+ | ~~Wait for MSafe to release `@msafe/sui-app-store`~~ | Ship your dApp. Then send name / icon / URL for the card. |
77
+ | ~~`new MSafeWallet('app')` only~~ | `new MSafeWallet('your-app-name', rpcUrl, 'sui:mainnet')` |
18
78
 
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.
79
+ ### Before after
20
80
 
21
- ### 1. Register the MSafe wallet
81
+ **1. Wallet registration**
22
82
 
23
- Install `@msafe/sui-wallet` and register it with **your application name**. Use the same name you want to appear in MSafe history.
83
+ ```ts
84
+ // DEPRECATED — incomplete constructor, often paired with a helper name
85
+ registerWallet(new MSafeWallet('your-app-name'));
86
+ ```
24
87
 
25
88
  ```ts
89
+ // REQUIRED
26
90
  import { MSafeWallet } from '@msafe/sui-wallet';
27
91
  import { registerWallet } from '@mysten/wallet-standard';
28
92
 
29
- const rpcUrl = 'https://fullnode.mainnet.sui.io:443';
30
-
31
93
  registerWallet(new MSafeWallet('your-app-name', rpcUrl, 'sui:mainnet'));
32
94
  ```
33
95
 
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.
96
+ Use the **same** `your-app-name` in history and in the store card.
35
97
 
36
- Connect with `@mysten/dapp-kit` (or any wallet-standard client) as you would for Slush or any other Sui wallet.
98
+ **2. Submit**
37
99
 
38
- ### 2. Submit a fully assembled transaction
100
+ ```ts
101
+ // DEPRECATED — empty PTB + helper payload. Unregistered apps are rejected.
102
+ await signAndExecuteTransaction({
103
+ transaction: new Transaction(),
104
+ appContext: { action: 'swap', txbParams },
105
+ });
106
+ ```
39
107
 
40
108
  ```ts
109
+ // REQUIRED — same Transaction you would send to Slush / any wallet
41
110
  import { Transaction } from '@mysten/sui/transactions';
42
111
 
43
112
  const tx = new Transaction();
44
- tx.setSender(multisigAddress);
45
- // Add real commands. An empty Transaction is rejected.
46
- tx.moveCall(/* ... */);
113
+ tx.setSender(multisigAddress); // connected MSafe account
114
+ // ...real moveCall / transfer / SDK calls — commands.length must be > 0
47
115
 
48
116
  await dAppKit.signAndExecuteTransaction({ transaction: tx });
117
+ // Do not pass appContext.
49
118
  ```
50
119
 
51
- Requirements:
120
+ **3. Remove helper-only code**
52
121
 
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()`. |
122
+ Search the dApp and delete:
59
123
 
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.
124
+ - `from '@msafe/sui-app-store'`
125
+ - `appContext`
126
+ - `BaseIntention` / `YourHelper` / `deserialize` / `intentionData`
127
+ - empty `new Transaction()` built only so the helper can `build()` later
61
128
 
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. |
129
+ Keep your protocol SDK (Cetus SDK, NAVI SDK, your own `moveCall`s). Those already produce a `Transaction`. Submit **that** object.
67
130
 
68
- ### 3. Empty and queued transactions
131
+ ### Migration checklist
69
132
 
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.
133
+ - [ ] Remove `@msafe/sui-app-store` from `package.json`
134
+ - [ ] Register `MSafeWallet` with **name + RPC URL + network**
135
+ - [ ] Connect via `@mysten/dapp-kit` (or wallet-standard) as you do for other wallets
136
+ - [ ] Every MSafe sign path sends a PTB with **at least one command**
137
+ - [ ] No `appContext` on `signTransaction` / `signAndExecuteTransaction`
138
+ - [ ] `tx.setSender` is the **multisig** address (the connected MSafe account)
139
+ - [ ] Close any helper PR against this repository
140
+ - [ ] Send MSafe: app name, icon, production URL — for the store card only
72
141
 
73
- ### 4. List the app in the MSafe store
142
+ `signAndExecuteTransaction` **proposes** to the multisig queue. It does **not** return an on-chain digest. Owners vote and execute in MSafe.
74
143
 
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.
144
+ Empty `new Transaction()` from an unregistered app is rejected:
76
145
 
77
- Send the MSafe team:
146
+ > Empty transaction. Unregistered apps must pass a fully assembled Transaction (`commands.length > 0`). Do not send `new Transaction()`.
78
147
 
79
- - Application name (must match `new MSafeWallet('...')`)
80
- - Icon
81
- - Production dApp URL (the iframe `dappLink`)
148
+ ---
82
149
 
83
- After the card is live, users open your app from the MSafe store and sign with the flow above.
150
+ ## Current integration
84
151
 
85
- ### Reference
152
+ ```mermaid
153
+ flowchart LR
154
+ A[Your dApp builds a real Transaction] --> B["MSafeWallet signAndExecuteTransaction"]
155
+ B --> C[MSafe simulates]
156
+ C --> D[Owners vote in MSafe]
157
+ D --> E[Execute on chain]
158
+ ```
86
159
 
87
- A sample dApp that talks to MSafe as a wallet:
160
+ 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
161
 
89
- - Repository: https://github.com/Momentum-Safe/msafe-sui-app-arbitrary-transaction
90
- - Live: https://sui-ptx.m-safe.io/
162
+ ### 1. Register the wallet
91
163
 
92
- Follow the **wallet `Transaction` path** in that project. Do not copy helper / `appContext` patterns from older commits.
164
+ ```ts
165
+ import { MSafeWallet } from '@msafe/sui-wallet';
166
+ import { registerWallet } from '@mysten/wallet-standard';
93
167
 
94
- Wallet SDK notes: [`@msafe/sui-wallet`](https://github.com/Momentum-Safe/msafe-sui-wallet).
168
+ registerWallet(new MSafeWallet('your-app-name', rpcUrl, 'sui:mainnet'));
169
+ ```
95
170
 
96
- ---
171
+ Call this once at startup (`main.tsx`). Use `MSafeWallet.inMSafeWallet()` if the page should behave differently inside the iframe versus standalone.
97
172
 
98
- ## Existing registered apps
173
+ ### 2. Submit the transaction
99
174
 
100
- Apps that already ship a helper in this package may keep the previous contract:
175
+ ```ts
176
+ await dAppKit.signAndExecuteTransaction({ transaction: tx });
177
+ ```
101
178
 
102
- - Call `signTransaction` with an empty `Transaction` plus `appContext`, **or**
103
- - Pass a real `Transaction` that the helper can `deserialize`.
179
+ | Rule | Detail |
180
+ | --- | --- |
181
+ | Real PTB | `tx.getData().commands.length > 0` |
182
+ | Sender | Connected MSafe **multisig** |
183
+ | No helper | Do not import this package. Do not pass `appContext`. |
184
+ | Encoding | Mysten V2 `Transaction` / `toJSON()`. Do not use V1 `serialize()`. |
104
185
 
105
- Do not add new helpers for new features or new protocols. New work goes through [Integrate a new dApp](#integrate-a-new-dapp).
186
+ | API | Behavior |
187
+ | --- | --- |
188
+ | `signTransaction({ transaction })` | Propose. Preferred. |
189
+ | `signAndExecuteTransaction({ transaction })` | Same propose path. **No digest** in the result. |
190
+ | `signTransactionBlock` / `signAndExecuteTransactionBlock` | Legacy aliases. |
106
191
 
107
- Frozen examples include Cetus, NAVI, MMT, mpay, `msafe-core`, and `msafe-plain-tx`.
192
+ 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.
193
+
194
+ ### 3. List in the store
195
+
196
+ 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.
197
+
198
+ ### Reference
199
+
200
+ - Wallet SDK: https://github.com/Momentum-Safe/msafe-sui-wallet
201
+ - Sample dApp: https://github.com/Momentum-Safe/msafe-sui-app-arbitrary-transaction — follow the **wallet `Transaction`** path, not old `appContext` commits
202
+ - Live sample: https://sui-ptx.m-safe.io/
108
203
 
109
204
  ---
110
205
 
111
- ## This repository
206
+ ## Already-listed apps with a helper
112
207
 
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.
208
+ Cetus, NAVI, MMT, mpay, `msafe-core`, `msafe-plain-tx`, and other **already registered** helpers may keep empty PTB + `appContext` until they migrate.
114
209
 
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.
210
+ - Do not add helpers for **new** products or new protocols.
211
+ - New features on a listed brand should still use [How to change your dApp](#how-to-change-your-dapp) when you can.
212
+
213
+ 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
214
 
119
215
  ---
120
216
 
121
- ## Deprecated: helper-based integration
217
+ <details>
218
+ <summary><strong>⛔ DEPRECATED archive — old helper guide (do not follow)</strong></summary>
122
219
 
123
220
  > [!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.
221
+ > 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
222
 
126
223
  ### ~~Background~~
127
224
 
@@ -176,7 +273,7 @@ Frozen examples include Cetus, NAVI, MMT, mpay, `msafe-core`, and `msafe-plain-t
176
273
 
177
274
  ~~If you are using @mysten/sui.js, you can refer to the following code:~~
178
275
 
179
- Historical example — do not copy for new apps:
276
+ ~~Historical example — do not copy:~~
180
277
 
181
278
  ```typescript
182
279
  import { SuiClient } from '@mysten/sui.js/client';
@@ -210,8 +307,6 @@ export class ExampleIntention extends BaseIntentionLegacy<ExampleIntentionData>
210
307
 
211
308
  ~~If you are using @mysten/sui, you can refer to the following code:~~
212
309
 
213
- Historical example — do not copy for new apps:
214
-
215
310
  ```typescript
216
311
  import { SuiClient } from '@mysten/sui/client';
217
312
  import { Transaction } from '@mysten/sui/transactions';
@@ -251,10 +346,6 @@ export class ExampleIntention extends BaseIntention<ExampleIntentionData> {
251
346
 
252
347
  - ~~Create helper ts at `src/apps/<your app>/intention.ts`~~
253
348
 
254
- ~~Here is an example of intention.ts file~~
255
-
256
- Historical example — do not copy for new apps:
257
-
258
349
  ```typescript
259
350
  export type CoreIntention = CoinTransferIntention | ObjectTransferIntention;
260
351
 
@@ -301,10 +392,6 @@ export class CoreHelper implements IAppHelperInternalLegacy<CoreIntention, CoreI
301
392
 
302
393
  - ~~Create your test at `test/<your app>.test.ts`~~
303
394
 
304
- ~~You can follow be example to write test~~
305
-
306
- Historical example — do not copy for new apps:
307
-
308
395
  ```typescript
309
396
  import { TransactionType } from '@msafe/sui3-utils';
310
397
 
@@ -350,8 +437,6 @@ describe('MSafe Core Wallet', () => {
350
437
 
351
438
  - ~~You can pass custom parameters into the `appContext` parameter of the Helper.deserialize method.~~
352
439
 
353
- Historical example — do not copy for new apps:
354
-
355
440
  ```typescript
356
441
  deserialize(input: {
357
442
  transaction: Transaction;
@@ -369,10 +454,6 @@ deserialize(input: {
369
454
 
370
455
  - ~~When implementing your app's `Helper.deserialize`, you can write your business logic based on the custom parameters you've passed in.~~
371
456
 
372
- - ~~For reference, you can review the implementation logic demo code below.~~
373
-
374
- Historical example — do not copy for new apps:
375
-
376
457
  ```typescript
377
458
  export class DemoHelper implements IAppHelperInternal<DemoIntentionData> {
378
459
 
@@ -407,8 +488,6 @@ async deserialize(input: {
407
488
 
408
489
  - ~~Add your app helper to file `src/index.ts`~~
409
490
 
410
- Historical example — do not copy for new apps:
411
-
412
491
  ```typescript
413
492
  export const appHelpers = new MSafeApps([new CoreHelper(), <your app helper instance here>]);
414
493
  ```
@@ -416,9 +495,6 @@ export const appHelpers = new MSafeApps([new CoreHelper(), <your app helper inst
416
495
  #### ~~Test your integration with our test framework `TestSuite`~~
417
496
 
418
497
  - ~~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
498
 
423
499
  ```typescript
424
500
  import { TestSuite, TestSuiteLegacy } from './TestSuite';
@@ -431,12 +507,7 @@ describe('Main flow', () => {
431
507
  features: [],
432
508
  };
433
509
 
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
510
  let ts: TestSuite<YourIntentionData>;
438
-
439
- // (implement with @mysten/sui.js)
440
511
  let ts: TestSuiteLegacy<YourIntentionData>;
441
512
 
442
513
  beforeEach(() => {
@@ -445,11 +516,7 @@ describe('Main flow', () => {
445
516
 
446
517
  describe('overall flow', () => {
447
518
  it('overall flow', async () => {
448
- // Mock application and user behavior
449
519
  const appTxb = new TransactionBlock();
450
- // ...
451
- // programming your transaction block here
452
- // ...
453
520
  await ts.signAndSubmitTransaction({ txb: appTxb, appContext: {
454
521
  // ... your app context here, will be passed to your helper.deserialize method
455
522
  } });
@@ -458,23 +525,6 @@ describe('Main flow', () => {
458
525
  expect(finalizedTxb).toBeDefined();
459
526
  });
460
527
  });
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
528
  });
479
529
  ```
480
530
 
@@ -486,13 +536,9 @@ describe('Main flow', () => {
486
536
 
487
537
  ### ~~Integrate MSafe wallet with your app~~
488
538
 
489
- ~~The last step is to integrate MSafe wallet with your application~~
490
-
491
539
  - ~~Run command `yarn add @msafe/sui-wallet` to add MSafe wallet package to your project~~
492
540
  - ~~Add below code to your application, basically it should be added to your `main.tsx` file~~
493
541
 
494
- Historical example — superseded by [Register the MSafe wallet](#1-register-the-msafe-wallet). The constructor also requires `rpcUrl` and `network`:
495
-
496
542
  ```typescript
497
543
  import { MSafeWallet } from '@msafe/sui-wallet';
498
544
  import { registerWallet } from '@mysten/wallet-standard';
@@ -503,3 +549,5 @@ registerWallet(new MSafeWallet('<your app name>'));
503
549
  #### ~~Next Step~~
504
550
 
505
551
  ~~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.~~
552
+
553
+ </details>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@msafe/sui-app-store",
3
- "version": "0.0.361",
3
+ "version": "0.0.363",
4
4
  "description": "MSafe Sui app store repository",
5
5
  "author": "Momentum Safe",
6
6
  "license": "MIT",