@msafe/sui-app-store 0.0.7 → 0.0.9
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 +173 -2
- package/dist/index.global.js +4 -4
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +32 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +32 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,3 +1,174 @@
|
|
|
1
|
-
# MSafe Sui
|
|
1
|
+
# MSafe Sui App Store
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## How to contribute
|
|
4
|
+
|
|
5
|
+
- Fork the repository
|
|
6
|
+
- Create a new branch for your app development
|
|
7
|
+
- Create pull request for review
|
|
8
|
+
|
|
9
|
+
## How to develop
|
|
10
|
+
|
|
11
|
+
### Setup
|
|
12
|
+
|
|
13
|
+
- Create your app folder under `src/apps/` folder
|
|
14
|
+
|
|
15
|
+
### Create intentions
|
|
16
|
+
|
|
17
|
+
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.
|
|
18
|
+
|
|
19
|
+
- Create your dapp intentions under `src/apps/<your app>` folder
|
|
20
|
+
|
|
21
|
+
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.
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
export interface CoinTransferIntentionData {
|
|
25
|
+
recipient: string;
|
|
26
|
+
coinType: string;
|
|
27
|
+
amount: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class CoinTransferIntention extends CoreBaseIntention<CoinTransferIntentionData> {
|
|
31
|
+
txType: TransactionType.Assets;
|
|
32
|
+
|
|
33
|
+
txSubType: 'coin-transfer';
|
|
34
|
+
|
|
35
|
+
constructor(public readonly data: CoinTransferIntentionData) {
|
|
36
|
+
super(data);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async build(input: { suiClient: SuiClient; account: WalletAccount }): Promise<TransactionBlock> {
|
|
40
|
+
const { suiClient, account } = input;
|
|
41
|
+
return buildCoinTransferTxb(suiClient, this.data, account.address);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static fromData(data: CoinTransferIntentionData) {
|
|
45
|
+
return new CoinTransferIntention(data);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Each intention should have one data structure to store transaction information for future build.
|
|
51
|
+
This structure can be defined according to your own business logic, it can be any type of data, (should be JSON serializable)
|
|
52
|
+
|
|
53
|
+
Transaction intention implement mainly one API `build(): Promise<TransactionBlock>` which will build Sui transaction block from your defined business data.
|
|
54
|
+
|
|
55
|
+
### Create helper
|
|
56
|
+
|
|
57
|
+
- Create helper ts at `src/apps/<your app>/intention.ts`
|
|
58
|
+
|
|
59
|
+
Here is an example of intention.ts file
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
export type CoreIntention = CoinTransferIntention | ObjectTransferIntention;
|
|
63
|
+
|
|
64
|
+
export type CoreIntentionData = CoinTransferIntentionData | ObjectTransferIntentionData;
|
|
65
|
+
|
|
66
|
+
export class CoreHelper implements MSafeAppHelper<CoreIntention, CoreIntentionData> {
|
|
67
|
+
application: string;
|
|
68
|
+
|
|
69
|
+
constructor() {
|
|
70
|
+
this.application = 'msafe-core';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
deserialize(): CoreIntention {
|
|
74
|
+
throw new Error('MSafe core transaction intention should be build from API');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async build(input: {
|
|
78
|
+
intentionData: CoreIntentionData;
|
|
79
|
+
txType: TransactionType;
|
|
80
|
+
txSubType: string;
|
|
81
|
+
suiClient: SuiClient;
|
|
82
|
+
account: WalletAccount;
|
|
83
|
+
}): Promise<TransactionBlock> {
|
|
84
|
+
const { suiClient, account } = input;
|
|
85
|
+
let intention: CoreIntention;
|
|
86
|
+
switch (input.txSubType) {
|
|
87
|
+
case 'coin-transfer':
|
|
88
|
+
intention = CoinTransferIntention.fromData(input.intentionData as CoinTransferIntentionData);
|
|
89
|
+
break;
|
|
90
|
+
case 'object-transfer':
|
|
91
|
+
intention = ObjectTransferIntention.fromData(input.intentionData as ObjectTransferIntentionData);
|
|
92
|
+
break;
|
|
93
|
+
default:
|
|
94
|
+
throw new Error('not implemented');
|
|
95
|
+
}
|
|
96
|
+
return intention.build({ suiClient, account });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
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.
|
|
102
|
+
|
|
103
|
+
### Write test for your business logic
|
|
104
|
+
|
|
105
|
+
- Create your test at `test/<your app>.test.ts`
|
|
106
|
+
|
|
107
|
+
You can follow be example to write test
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import { TransactionType } from '@msafe/sui3-utils';
|
|
111
|
+
|
|
112
|
+
import { CoinTransferIntention, CoinTransferIntentionData } from '@/apps/msafe-core/coin-transfer';
|
|
113
|
+
import { appHelpers } from '@/index';
|
|
114
|
+
|
|
115
|
+
import { Account, Client } from './config';
|
|
116
|
+
|
|
117
|
+
describe('MSafe Core Wallet', () => {
|
|
118
|
+
it('Core transaction build', async () => {
|
|
119
|
+
const appHelper = appHelpers.getAppHelper('msafe-core');
|
|
120
|
+
|
|
121
|
+
expect(appHelper.application).toBe('msafe-core');
|
|
122
|
+
|
|
123
|
+
const res = await appHelper.build({
|
|
124
|
+
txType: TransactionType.Assets,
|
|
125
|
+
txSubType: 'coin-transfer',
|
|
126
|
+
suiClient: Client,
|
|
127
|
+
account: Account,
|
|
128
|
+
intentionData: {
|
|
129
|
+
amount: '1000',
|
|
130
|
+
coinType: '0x2::sui::SUI',
|
|
131
|
+
recipient: '123',
|
|
132
|
+
} as CoinTransferIntentionData,
|
|
133
|
+
});
|
|
134
|
+
expect(res.blockData.version).toBe(1);
|
|
135
|
+
expect(res.blockData.sender).toBe('0x0df172b18d30935ad68b2f9d6180e5adcf8edfd7df874852817002e6eccada66');
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('Test intention serialization', () => {
|
|
139
|
+
const intention = CoinTransferIntention.fromData({
|
|
140
|
+
recipient: 'a',
|
|
141
|
+
coinType: 'b',
|
|
142
|
+
amount: '100',
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
expect(intention.serialize()).toBe('{"amount":"100","coinType":"b","recipient":"a"}');
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Register your app helper
|
|
151
|
+
|
|
152
|
+
- Add your app helper to file `src/index.ts`
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
export const appHelpers = new MSafeApps([new CoreHelper(), <your app helper instance here>]);
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Create pull request for submit
|
|
159
|
+
|
|
160
|
+
Once you finish development, you can create a PR to submit your changes.
|
|
161
|
+
|
|
162
|
+
## Integrate MSafe wallet with your app
|
|
163
|
+
|
|
164
|
+
The last step is to integrate MSafe wallet with your application
|
|
165
|
+
|
|
166
|
+
- Run command `yarn add @msafe/sui-wallet` to add MSafe wallet package to your project
|
|
167
|
+
- Add below code to your application, basically it should be added to your `main.tsx` file
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { MSafeWallet } from '@msafe/sui-wallet';
|
|
171
|
+
import { registerWallet } from '@mysten/wallet-standard';
|
|
172
|
+
|
|
173
|
+
registerWallet(new MSafeWallet('<your app name>'));
|
|
174
|
+
```
|