### 主要使用 Suiet Wallet套件 及 Mysten Sui.js套件
## 參考資料
[Suiet Wallet Kit 文件](https://kit.suiet.app/docs/QuickStart)
[Suiet Wallet Kit GitHub](https://github.com/suiet/wallet-kit)
[Mysten sui.js api文件](https://sdk.mystenlabs.com/typedoc/index.html)
[Mysten sui.js GitHub](https://github.com/MystenLabs/sui)
[SUI 主網上線,前端開發者的DApp 開發指南](https://juejin.cn/post/7229984415329337400)
## 讓Demo Project跑起來
[Demo GitHub](https://github.com/ryan19910912/dapp_demo)
git clone
```
git clone https://github.com/ryan19910912/dapp_demo.git
```
進入到Demo專案並安裝Lib
```
npm install
```
讓Demo專案跑起來
```
npm run dev
```

## 連接錢包


## 程式解說
我們主要會修改main.jsx及App.jsx這2個檔案

- ### main.jsx
main.jsx主要是引入suiet wallet套件的樣式CSS檔及WalletProvider

- ### App.jsx
App.jsx主要用來寫跟智能合約互動的主程式

- ConnectButton為Suiet Wallet套件內的連接錢包按鈕

- useWallet為Suiet Wallet套件內的錢包功能

```typescript=
export interface WalletContextState {
configuredWallets: IWallet[]; //目前配置的錢包選項
detectedWallets: IWallet[];
allAvailableWallets: IWallet[]; //目前可用的錢包選項
chains: Chain[]; //所有的Sui鏈(id, name, rpcUrl)
chain: Chain | undefined; //目前所在的Sui鏈
name: string | undefined; //錢包名稱
adapter: IWalletAdapter | undefined;
account: WalletAccount | undefined; //錢包帳號資訊(常用)
address: string | undefined; //錢包地址(account內也有)
connecting: boolean;
connected: boolean; //是否連線中
status: "disconnected" | "connected" | "connecting"; //目前連線狀態
}
```

- devnetConnection、testnetConnection及mainnetConnet是Sui的節點Rpc Url

- JsonRpcProvider主要用來查詢合約用
[JsonRpcProvider參考文件](http://typescript-sdk-docs.s3-website-us-east-1.amazonaws.com/classes/JsonRpcProvider.html)
需要先new一個JsonRpcProvider物件出來,並傳入節點Rpc Url


- TransactionBlock主要用來執行合約用
[TransactionBlock參考文件](http://typescript-sdk-docs.s3-website-us-east-1.amazonaws.com/classes/TransactionBlock.html)
需要先new一個TransactionBlock物件出來
並於最後該錢包使用簽名及執行交易區塊時,傳入TransactionBlock當作參數

### 常用的查詢方法
JsonRpcProvider內的方法
1. getOwnedObjects (取得該Owner底下所有物件資訊,可用Filter篩選)
[getOwnedObjects參考文件](http://typescript-sdk-docs.s3-website-us-east-1.amazonaws.com/classes/JsonRpcProvider.html#getOwnedObjects)
```javascript=
let ownedObject = {
owner: wallet?.account?.address,
options: {
showType: true,
showOwner: true,
showContent: true,
}
}
if (structType !== ""){
ownedObject.filter = {
MatchAny: [
{
StructType: structType
}
]
}
}
provider.getOwnedObjects(
ownedObject
).then(data => {
console.log("getOwnedObjectsFunction");
console.log(data);
setOwendObjects(jsonFormat(data.data));
});
```
2. getObject (取得任何物件資訊,不管是SharedObject或是OwnedObject)
[getObject參考文件](http://typescript-sdk-docs.s3-website-us-east-1.amazonaws.com/classes/JsonRpcProvider.html#getObject)
```javascript=
provider.getObject({
id: objectId,
options: {
showType: true,
showOwner: true,
showContent: true,
}
}).then(data => {
console.log("getObjectFunction");
console.log(data);
setObject(jsonFormat(data.data));
});
```
3. getDynamicFields (取得動態欄位,通常用於查找Table)
[getDynamicFields參考文件](http://typescript-sdk-docs.s3-website-us-east-1.amazonaws.com/classes/JsonRpcProvider.html#getDynamicFields)
```javascript=
provider.getDynamicFields({
parentId: parentId,
}).then(data => {
console.log("getDynamicFieldsFunction");
console.log(data);
setDynamicFields(jsonFormat(data.data));
});
```
4. getDynamicFieldObject (取得動態欄位內的物件資訊)
[getDynamicFieldObject參考文件](http://typescript-sdk-docs.s3-website-us-east-1.amazonaws.com/classes/JsonRpcProvider.html#getDynamicFieldObject)
```javascript=
provider.getDynamicFieldObject({
parentId: parentId,
name: {
type: type,
value: value
}
}).then(data => {
console.log("getDynamicFieldObjectFunction");
console.log(data);
setDynamicFieldObject(jsonFormat(data.data));
});
```
5. getCoins (該Owner底下所有Coin資訊)
[getCoins參考文件](http://typescript-sdk-docs.s3-website-us-east-1.amazonaws.com/classes/JsonRpcProvider.html#getCoins)
```javascript=
provider.getCoins({
// coinType: coinType,
owner: wallet?.address,
}).then(data => {
console.log("getCoinsFunction");
console.log(data);
setCoins(jsonFormat(data.data));
});
```
### 常用的執行方法
TransactionBlock內的方法
1. splitCoins (拆分Coin) + transferObjects (傳遞物件給某個地址)
[splitCoins參考文件](http://typescript-sdk-docs.s3-website-us-east-1.amazonaws.com/classes/TransactionBlock.html#splitCoins-2)、[transferObjects參考文件](http://typescript-sdk-docs.s3-website-us-east-1.amazonaws.com/classes/TransactionBlock.html#transferObjects-2)
```javascript=
let txObj = new TransactionBlock();
let main_coin = splitCoin === "" ? txObj.gas : txObj.object(splitCoin);
let [coins] = txObj.splitCoins(main_coin, [txObj.pure(Number(splitAmount) * 1000000000)]);
txObj.transferObjects([coins], txObj.pure(wallet.account.address));
wallet.signAndExecuteTransactionBlock({
transactionBlock: txObj,
options: { showEffects: true },
}).then(data => {
console.log("splitCoinFunction");
console.log(data.effects);
setSplitResult(jsonFormat(data.effects));
});
```
2. mergeCoins (合併Coin)
[mergeCoins參考文件](http://typescript-sdk-docs.s3-website-us-east-1.amazonaws.com/classes/TransactionBlock.html#mergeCoins-2)
```javascript=
let txObj = new TransactionBlock();
let merge_coins = [];
let main_coin = mainCoin === "" ? txObj.gas : txObj.object(mainCoin);
for (let coin_object_id of mergeCoin.split(",")) {
merge_coins.push(txObj.object(coin_object_id));
}
txObj.mergeCoins(main_coin, merge_coins);
wallet.signAndExecuteTransactionBlock({
transactionBlock: txObj,
options: { showEffects: true },
}).then(data => {
console.log("mergeCoinFunction");
console.log(data.effects);
setMergeResult(jsonFormat(data.effects));
});
```
3. moveCall (跟智能合約做互動)
[moveCall參考文件](http://typescript-sdk-docs.s3-website-us-east-1.amazonaws.com/classes/TransactionBlock.html#moveCall-2)
```javascript=
let txObj = new TransactionBlock();
let type_args = [
coinType
];
let args = [
txObj.object(objectId),
txObj.pure(Number(maxSupply) * 1000000000),
txObj.object(trader),
txObj.pure(Number(commissionPercentage)),
txObj.pure(name),
txObj.pure(desc),
];
// call sui move smart contract
txObj.moveCall({
target: `${packageId}::${moduleName}::${functionName}`,
typeArguments: type_args,
arguments: args,
})
wallet.signAndExecuteTransactionBlock({
transactionBlock: txObj,
options: { showEffects: true },
}).then(data => {
console.log("moveCallFunction");
console.log(data.effects);
setMoveCallResult(jsonFormat(data.effects));
});
```
最後都需要使用wallet.signAndExecuteTransactionBlock來讓用戶簽名並執行上述動作
```javascript=
wallet.signAndExecuteTransactionBlock({
transactionBlock: txObj,
options: { showEffects: true },
}).then(data => {
console.log("splitCoinFunction");
console.log(data.effects);
setSplitResult(jsonFormat(data.effects));
});
```
### TransactionBlock傳遞參數方法詳解

介紹幾個常用的
1. pure (會自行判斷一般類型(數字、字串)及物件類型) (推薦)
2. object (用於傳遞物件)
3. makeMoveVec (用於傳遞陣列Vector)
sui move合約範例
```move=
public entry fun merge_shares<T: drop>(
shares1: &mut PuddleShares<T>,
shares2Arr: vector<PuddleShares<T>>,
_ctx: &mut TxContext,
)
```
Javascript範例
```javascript=
let objects_arr = [];
merge_id_arr.forEach(merge_id => {
objects_arr.push(txObj.object(merge_id));
});
txObj.pure(shares_id),
txObj.makeMoveVec({ objects: objects_arr })
```