@stableflow/wallet-sui 0.0.0-experimental-5a8afd7389-20260703

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 StableFlow AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # @stableflow/wallet-sui
2
+
3
+ Sui wallet adapter for the StableFlow SDK.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @stableflow/wallet-sui @stableflow/core @stableflow/bridges
9
+ ```
10
+
11
+ **Peer dependencies:**
12
+
13
+ - `@mysten/sui` ^2.16.2
14
+
15
+ ## When to use
16
+
17
+ Sui chain transfers and quotes in `BridgeSFA` flows.
18
+
19
+ ## Main exports
20
+
21
+ ```ts
22
+ import SuiWallet, { SuiWallet as Named } from '@stableflow/wallet-sui';
23
+ ```
24
+
25
+ ## See also
26
+
27
+ - [Developer Guide](../../DEVELOPER_GUIDE.md)
28
+ - [@stableflow/bridges](../bridges/README.md)
@@ -0,0 +1,50 @@
1
+ import { Service, SendType } from '@stableflow/core';
2
+
3
+ declare class SuiWallet {
4
+ private account;
5
+ private signAndExecuteTransaction;
6
+ private suiClient;
7
+ private csl;
8
+ constructor(options: {
9
+ account: any | null;
10
+ signAndExecuteTransaction: any;
11
+ });
12
+ transferSUI(to: string, amount: string): Promise<string>;
13
+ transferToken(contractAddress: string, to: string, amount: string): Promise<string>;
14
+ transfer(data: {
15
+ originAsset: string;
16
+ depositAddress: string;
17
+ amount: string;
18
+ }): Promise<string>;
19
+ getSUIBalance(account: string): Promise<string>;
20
+ getTokenBalance(contractAddress: string, account: string): Promise<string>;
21
+ getBalance(token: any, account: string): Promise<string>;
22
+ balanceOf(token: any, account: string): Promise<string>;
23
+ estimateTransferGas(data: {
24
+ fromToken: any;
25
+ depositAddress: string;
26
+ amount: string;
27
+ }): Promise<{
28
+ gasLimit: bigint;
29
+ gasPrice: bigint;
30
+ estimateGas: bigint;
31
+ }>;
32
+ getEstimateGas(params: any): Promise<{
33
+ gasPrice: number;
34
+ usd: string;
35
+ wei: bigint;
36
+ amount: string;
37
+ }>;
38
+ estimateTransaction(params: any): Promise<{
39
+ estimateSourceGasLimit: bigint;
40
+ estimateSourceGas: bigint;
41
+ estimateSourceGasUsd: string;
42
+ }>;
43
+ checkTransactionStatus(signature: string): Promise<boolean>;
44
+ quoteOneClickProxy(params: any): Promise<any>;
45
+ sendTransaction(params: any): Promise<any>;
46
+ quote(type: Service, params: any): Promise<any>;
47
+ send(type: SendType, params: any): Promise<any>;
48
+ }
49
+
50
+ export { SuiWallet, SuiWallet as default };
@@ -0,0 +1,50 @@
1
+ import { Service, SendType } from '@stableflow/core';
2
+
3
+ declare class SuiWallet {
4
+ private account;
5
+ private signAndExecuteTransaction;
6
+ private suiClient;
7
+ private csl;
8
+ constructor(options: {
9
+ account: any | null;
10
+ signAndExecuteTransaction: any;
11
+ });
12
+ transferSUI(to: string, amount: string): Promise<string>;
13
+ transferToken(contractAddress: string, to: string, amount: string): Promise<string>;
14
+ transfer(data: {
15
+ originAsset: string;
16
+ depositAddress: string;
17
+ amount: string;
18
+ }): Promise<string>;
19
+ getSUIBalance(account: string): Promise<string>;
20
+ getTokenBalance(contractAddress: string, account: string): Promise<string>;
21
+ getBalance(token: any, account: string): Promise<string>;
22
+ balanceOf(token: any, account: string): Promise<string>;
23
+ estimateTransferGas(data: {
24
+ fromToken: any;
25
+ depositAddress: string;
26
+ amount: string;
27
+ }): Promise<{
28
+ gasLimit: bigint;
29
+ gasPrice: bigint;
30
+ estimateGas: bigint;
31
+ }>;
32
+ getEstimateGas(params: any): Promise<{
33
+ gasPrice: number;
34
+ usd: string;
35
+ wei: bigint;
36
+ amount: string;
37
+ }>;
38
+ estimateTransaction(params: any): Promise<{
39
+ estimateSourceGasLimit: bigint;
40
+ estimateSourceGas: bigint;
41
+ estimateSourceGasUsd: string;
42
+ }>;
43
+ checkTransactionStatus(signature: string): Promise<boolean>;
44
+ quoteOneClickProxy(params: any): Promise<any>;
45
+ sendTransaction(params: any): Promise<any>;
46
+ quote(type: Service, params: any): Promise<any>;
47
+ send(type: SendType, params: any): Promise<any>;
48
+ }
49
+
50
+ export { SuiWallet, SuiWallet as default };
package/dist/index.js ADDED
@@ -0,0 +1,354 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var transactions = require('@mysten/sui/transactions');
6
+ var Big = require('big.js');
7
+ var grpc = require('@mysten/sui/grpc');
8
+ var core = require('@stableflow/core');
9
+
10
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
11
+
12
+ var Big__default = /*#__PURE__*/_interopDefault(Big);
13
+
14
+ // src/sui.ts
15
+ var SUI_COIN_TYPE = "0x2::sui::SUI";
16
+ var DEFAULT_GAS_LIMIT = 3000000n;
17
+ var SuiWallet = class {
18
+ constructor(options) {
19
+ this.signAndExecuteTransaction = options.signAndExecuteTransaction;
20
+ this.account = options.account;
21
+ this.suiClient = new grpc.SuiGrpcClient({
22
+ network: "mainnet",
23
+ baseUrl: core.getChainRpcUrl("sui").rpcUrl
24
+ });
25
+ const cs = new core.Csl(core.OpenAPI.DEBUG);
26
+ this.csl = cs.log;
27
+ }
28
+ // Transfer SUI
29
+ async transferSUI(to, amount) {
30
+ if (!this.account) {
31
+ throw new Error("Wallet not connected");
32
+ }
33
+ try {
34
+ const tx = new transactions.Transaction();
35
+ const amountInMist = BigInt(Math.floor(parseFloat(amount) * 10 ** 9));
36
+ const [coinToSend] = tx.splitCoins(tx.gas, [amountInMist]);
37
+ tx.transferObjects([coinToSend], to);
38
+ const result = await this.signAndExecuteTransaction({
39
+ transaction: tx,
40
+ options: {
41
+ showEffects: true,
42
+ showBalanceChanges: true
43
+ }
44
+ });
45
+ return typeof result === "string" ? result : result.Transaction.digest;
46
+ } catch (error) {
47
+ this.csl("Sui transferSUI", "red-500", "Transfer APT failed: %o", error);
48
+ throw error;
49
+ }
50
+ }
51
+ // Transfer token
52
+ async transferToken(contractAddress, to, amount) {
53
+ if (!this.account) {
54
+ throw new Error("Wallet not connected");
55
+ }
56
+ try {
57
+ const owner = this.account?.address?.toString();
58
+ if (!owner) {
59
+ throw new Error("Invalid sender address");
60
+ }
61
+ const amountBigInt = BigInt(amount);
62
+ const coinsResponse = await this.suiClient.listCoins({
63
+ owner,
64
+ coinType: contractAddress,
65
+ limit: 50
66
+ });
67
+ if (!coinsResponse.objects?.length) {
68
+ throw new Error("Insufficient token balance");
69
+ }
70
+ const [primaryCoin, ...restCoins] = coinsResponse.objects;
71
+ const tx = new transactions.Transaction();
72
+ const primaryInput = tx.object(primaryCoin.objectId);
73
+ if (restCoins.length) {
74
+ tx.mergeCoins(
75
+ primaryInput,
76
+ restCoins.map((coin) => tx.object(coin.objectId))
77
+ );
78
+ }
79
+ const [coinToSend] = tx.splitCoins(primaryInput, [amountBigInt]);
80
+ tx.transferObjects([coinToSend], to);
81
+ const result = await this.signAndExecuteTransaction({
82
+ transaction: tx,
83
+ options: {
84
+ showEffects: true,
85
+ showBalanceChanges: true
86
+ }
87
+ });
88
+ return typeof result === "string" ? result : result.Transaction.digest;
89
+ } catch (error) {
90
+ this.csl("Sui transferToken", "red-500", "Transfer token failed: %o", error);
91
+ throw error;
92
+ }
93
+ }
94
+ // Generic transfer method
95
+ async transfer(data) {
96
+ const { originAsset, depositAddress, amount } = data;
97
+ if (originAsset === "SUI" || originAsset === "sui" || originAsset === "native") {
98
+ return await this.transferSUI(depositAddress, amount);
99
+ }
100
+ const result = await this.transferToken(
101
+ originAsset,
102
+ depositAddress,
103
+ amount
104
+ );
105
+ return result;
106
+ }
107
+ async getSUIBalance(account) {
108
+ try {
109
+ const response = await this.suiClient.core.getBalance({
110
+ owner: account,
111
+ coinType: SUI_COIN_TYPE
112
+ });
113
+ return response.balance.balance || "0";
114
+ } catch (error) {
115
+ this.csl("Sui getSUIBalance", "red-500", "Get SUI balance failed: %o", error);
116
+ return "0";
117
+ }
118
+ }
119
+ async getTokenBalance(contractAddress, account) {
120
+ try {
121
+ const response = await this.suiClient.core.getBalance({
122
+ owner: account,
123
+ coinType: contractAddress
124
+ });
125
+ return response.balance.balance || "0";
126
+ } catch (error) {
127
+ this.csl("Sui getTokenBalance", "red-500", "Get token balance failed: %o", error);
128
+ return "0";
129
+ }
130
+ }
131
+ async getBalance(token, account) {
132
+ if (token.symbol === "SUI" || token.symbol === "sui" || token.symbol === "native") {
133
+ return await this.getSUIBalance(account);
134
+ }
135
+ return await this.getTokenBalance(token.contractAddress, account);
136
+ }
137
+ async balanceOf(token, account) {
138
+ return await this.getBalance(token, account);
139
+ }
140
+ async estimateTransferGas(data) {
141
+ if (!this.account) {
142
+ throw new Error("Wallet not connected");
143
+ }
144
+ const { fromToken, depositAddress, amount } = data;
145
+ const sender = this.account?.address?.toString();
146
+ if (!sender) {
147
+ throw new Error("Invalid sender address");
148
+ }
149
+ const tx = new transactions.Transaction();
150
+ const originAsset = fromToken?.contractAddress;
151
+ const isNative = originAsset === "SUI" || originAsset === "sui" || originAsset === "native";
152
+ if (isNative) {
153
+ const [coinToSend] = tx.splitCoins(tx.gas, [BigInt(amount)]);
154
+ tx.transferObjects([coinToSend], depositAddress);
155
+ } else {
156
+ const coinsResponse = await this.suiClient.listCoins({
157
+ owner: sender,
158
+ coinType: originAsset,
159
+ limit: 50
160
+ });
161
+ if (!coinsResponse.objects?.length) {
162
+ throw new Error("No token coins found for gas estimation");
163
+ }
164
+ const [primaryCoin, ...restCoins] = coinsResponse.objects;
165
+ const primaryInput = tx.object(primaryCoin.objectId);
166
+ if (restCoins.length) {
167
+ tx.mergeCoins(
168
+ primaryInput,
169
+ restCoins.map((coin) => tx.object(coin.objectId))
170
+ );
171
+ }
172
+ const [coinToSend] = tx.splitCoins(primaryInput, [BigInt(amount)]);
173
+ tx.transferObjects([coinToSend], depositAddress);
174
+ }
175
+ const ett = await this.estimateTransaction({
176
+ dry: false,
177
+ tx,
178
+ fromToken,
179
+ prices: {}
180
+ });
181
+ return {
182
+ gasLimit: ett.estimateSourceGasLimit,
183
+ gasPrice: 1n,
184
+ estimateGas: ett.estimateSourceGas
185
+ };
186
+ }
187
+ async getEstimateGas(params) {
188
+ const { gasLimit, price, nativeToken } = params;
189
+ const finalGasPrice = 1;
190
+ const estimateGas = BigInt(gasLimit) * BigInt(finalGasPrice);
191
+ const estimateGasAmount = Big__default.default(estimateGas.toString()).div(10 ** nativeToken.decimals);
192
+ const estimateGasUsd = Big__default.default(estimateGasAmount).times(price || 1);
193
+ return {
194
+ gasPrice: finalGasPrice,
195
+ usd: core.numberRemoveEndZero(Big__default.default(estimateGasUsd).toFixed(20)),
196
+ wei: estimateGas,
197
+ amount: core.numberRemoveEndZero(Big__default.default(estimateGasAmount).toFixed(nativeToken.decimals))
198
+ };
199
+ }
200
+ async estimateTransaction(params) {
201
+ const {
202
+ dry,
203
+ tx,
204
+ fromToken,
205
+ prices,
206
+ defaultGasLimit = DEFAULT_GAS_LIMIT
207
+ } = params;
208
+ const nativeTokenPrice = core.getPrice(prices, fromToken.nativeToken.symbol);
209
+ const result = {
210
+ estimateSourceGasLimit: DEFAULT_GAS_LIMIT,
211
+ estimateSourceGas: 0n,
212
+ estimateSourceGasUsd: "0"
213
+ };
214
+ const setDefaultGasLimit = async () => {
215
+ const { usd, wei } = await this.getEstimateGas({
216
+ gasLimit: DEFAULT_GAS_LIMIT,
217
+ price: nativeTokenPrice,
218
+ nativeToken: fromToken.nativeToken
219
+ });
220
+ result.estimateSourceGas = wei;
221
+ result.estimateSourceGasUsd = usd;
222
+ };
223
+ let finalGasLimit = defaultGasLimit;
224
+ if (dry) {
225
+ await setDefaultGasLimit();
226
+ return result;
227
+ }
228
+ let sender = this.account?.address;
229
+ if (!sender) {
230
+ sender = core.DefaultAddresses["sui"];
231
+ }
232
+ try {
233
+ tx.setSender(sender);
234
+ const txBytes = await tx.build({ client: this.suiClient });
235
+ const simulation2 = await this.suiClient.core.simulateTransaction({
236
+ transaction: txBytes,
237
+ checksEnabled: false,
238
+ include: {
239
+ effects: true
240
+ }
241
+ });
242
+ const simulationTx = simulation2.$kind === "Transaction" ? simulation2.Transaction : simulation2.FailedTransaction;
243
+ const gasUsed = simulationTx?.effects?.gasUsed;
244
+ finalGasLimit = BigInt(gasUsed?.computationCost || "0") + BigInt(gasUsed?.storageCost || "0") - BigInt(gasUsed?.storageRebate || "0");
245
+ finalGasLimit = finalGasLimit * 150n / 100n;
246
+ const { usd, wei } = await this.getEstimateGas({
247
+ gasLimit: finalGasLimit,
248
+ price: nativeTokenPrice,
249
+ nativeToken: fromToken.nativeToken
250
+ });
251
+ result.estimateSourceGasLimit = finalGasLimit;
252
+ result.estimateSourceGas = wei;
253
+ result.estimateSourceGasUsd = usd;
254
+ } catch (error) {
255
+ this.csl("Aptos estimateTransaction", "red-500", "simulation failed: %o", error);
256
+ await setDefaultGasLimit();
257
+ }
258
+ return result;
259
+ }
260
+ async checkTransactionStatus(signature) {
261
+ try {
262
+ const tx = await this.suiClient.core.waitForTransaction({
263
+ digest: signature
264
+ });
265
+ return tx.Transaction?.status?.success === true;
266
+ } catch (error) {
267
+ this.csl("Sui checkTransactionStatus", "red-500", "Check transaction status failed: %o", error);
268
+ return false;
269
+ }
270
+ }
271
+ async quoteOneClickProxy(params) {
272
+ const {
273
+ dry,
274
+ proxyAddress,
275
+ fromToken,
276
+ depositAddress,
277
+ amountWei,
278
+ prices
279
+ } = params;
280
+ const result = { fees: {} };
281
+ if (!depositAddress) {
282
+ throw new Error("depositAddress is required");
283
+ }
284
+ const tx = new transactions.Transaction();
285
+ const payCoin = transactions.coinWithBalance({
286
+ type: fromToken.contractAddress,
287
+ balance: amountWei,
288
+ useGasCoin: false
289
+ });
290
+ tx.moveCall({
291
+ target: `${proxyAddress}::proxy_transfer::proxy_transfer`,
292
+ typeArguments: [fromToken.contractAddress],
293
+ arguments: [payCoin, tx.pure.u64(amountWei), tx.pure.address(depositAddress)]
294
+ });
295
+ result.sendParam = { tx };
296
+ const ett = await this.estimateTransaction({
297
+ dry,
298
+ tx,
299
+ fromToken,
300
+ prices
301
+ });
302
+ result.fees.estimateGasUsd = ett.estimateSourceGasUsd;
303
+ result.estimateSourceGas = ett.estimateSourceGas;
304
+ result.totalEstimateSourceGas = ett.estimateSourceGas;
305
+ result.estimateSourceGasUsd = ett.estimateSourceGasUsd;
306
+ return result;
307
+ }
308
+ async sendTransaction(params) {
309
+ if (!this.account) {
310
+ throw new Error("Wallet not connected");
311
+ }
312
+ const { tx } = params;
313
+ try {
314
+ const sender = this.account?.address?.toString();
315
+ if (!sender) {
316
+ throw new Error("Invalid sender address");
317
+ }
318
+ const result = await this.signAndExecuteTransaction({
319
+ transaction: tx,
320
+ options: {
321
+ showEffects: true,
322
+ showBalanceChanges: true
323
+ }
324
+ });
325
+ return typeof result === "string" ? result : result.Transaction.digest;
326
+ } catch (error) {
327
+ this.csl("Sui sendTransaction", "red-500", "Send transaction failed: %o", error);
328
+ throw error;
329
+ }
330
+ }
331
+ async quote(type, params) {
332
+ switch (type) {
333
+ case core.Service.OneClick:
334
+ return await this.quoteOneClickProxy(params);
335
+ default:
336
+ throw new Error(`Unsupported quote type: ${type}`);
337
+ }
338
+ }
339
+ async send(type, params) {
340
+ switch (type) {
341
+ case core.SendType.SEND:
342
+ return await this.sendTransaction(params);
343
+ case core.SendType.TRANSFER:
344
+ return await this.transfer(params);
345
+ default:
346
+ throw new Error(`Unsupported send type: ${type}`);
347
+ }
348
+ }
349
+ };
350
+
351
+ exports.SuiWallet = SuiWallet;
352
+ exports.default = SuiWallet;
353
+ //# sourceMappingURL=index.js.map
354
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sui.ts"],"names":["SuiGrpcClient","getChainRpcUrl","Csl","OpenAPI","Transaction","Big","numberRemoveEndZero","getPrice","DefaultAddresses","simulation","coinWithBalance","Service","SendType"],"mappings":"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","file":"index.js","sourcesContent":["import { coinWithBalance, Transaction } from \"@mysten/sui/transactions\";\nimport Big from \"big.js\";\nimport { SuiGrpcClient } from \"@mysten/sui/grpc\";\nimport {\n DefaultAddresses,\n getChainRpcUrl,\n Csl,\n OpenAPI,\n numberRemoveEndZero,\n SendType,\n Service,\n getPrice,\n} from '@stableflow/core';\n\nconst SUI_COIN_TYPE = \"0x2::sui::SUI\";\nconst DEFAULT_GAS_LIMIT = 3000000n;\n\nexport default class SuiWallet {\n private account: any | null;\n private signAndExecuteTransaction: any;\n private suiClient: SuiGrpcClient;\n private csl;\n\n constructor(options: { account: any | null; signAndExecuteTransaction: any; }) {\n this.signAndExecuteTransaction = options.signAndExecuteTransaction;\n this.account = options.account;\n this.suiClient = new SuiGrpcClient({\n network: \"mainnet\",\n baseUrl: getChainRpcUrl(\"sui\").rpcUrl,\n });\n\n const cs = new Csl(OpenAPI.DEBUG);\n this.csl = cs.log;\n }\n\n // Transfer SUI\n async transferSUI(to: string, amount: string): Promise<string> {\n if (!this.account) {\n throw new Error(\"Wallet not connected\");\n }\n\n try {\n const tx = new Transaction();\n\n // Convert amount to octas (1 SUI = 10^9)\n const amountInMist = BigInt(Math.floor(parseFloat(amount) * 10 ** 9));\n\n const [coinToSend] = tx.splitCoins(tx.gas, [amountInMist]);\n\n tx.transferObjects([coinToSend], to);\n\n // Sign and submit transaction\n const result = await this.signAndExecuteTransaction({\n transaction: tx,\n options: {\n showEffects: true,\n showBalanceChanges: true,\n },\n });\n\n return typeof result === \"string\" ? result : result.Transaction.digest;\n } catch (error) {\n this.csl(\"Sui transferSUI\", \"red-500\", \"Transfer APT failed: %o\", error);\n throw error;\n }\n }\n\n // Transfer token\n async transferToken(contractAddress: string, to: string, amount: string): Promise<string> {\n if (!this.account) {\n throw new Error(\"Wallet not connected\");\n }\n\n try {\n const owner = this.account?.address?.toString();\n if (!owner) {\n throw new Error(\"Invalid sender address\");\n }\n\n const amountBigInt = BigInt(amount);\n const coinsResponse = await this.suiClient.listCoins({\n owner,\n coinType: contractAddress,\n limit: 50,\n });\n\n if (!coinsResponse.objects?.length) {\n throw new Error(\"Insufficient token balance\");\n }\n\n const [primaryCoin, ...restCoins] = coinsResponse.objects;\n const tx = new Transaction();\n const primaryInput = tx.object(primaryCoin.objectId);\n\n if (restCoins.length) {\n tx.mergeCoins(\n primaryInput,\n restCoins.map((coin: any) => tx.object(coin.objectId)),\n );\n }\n\n const [coinToSend] = tx.splitCoins(primaryInput, [amountBigInt]);\n tx.transferObjects([coinToSend], to);\n\n const result = await this.signAndExecuteTransaction({\n transaction: tx,\n options: {\n showEffects: true,\n showBalanceChanges: true,\n },\n });\n\n return typeof result === \"string\" ? result : result.Transaction.digest;\n } catch (error) {\n this.csl(\"Sui transferToken\", \"red-500\", \"Transfer token failed: %o\", error);\n throw error;\n }\n }\n\n // Generic transfer method\n async transfer(data: {\n originAsset: string;\n depositAddress: string;\n amount: string;\n }): Promise<string> {\n const { originAsset, depositAddress, amount } = data;\n\n // Transfer SUI\n if (originAsset === \"SUI\" || originAsset === \"sui\" || originAsset === \"native\") {\n return await this.transferSUI(depositAddress, amount);\n }\n\n // Transfer token\n const result = await this.transferToken(\n originAsset,\n depositAddress,\n amount\n );\n return result;\n }\n\n async getSUIBalance(account: string) {\n try {\n const response = await this.suiClient.core.getBalance({\n owner: account,\n coinType: SUI_COIN_TYPE,\n });\n return response.balance.balance || \"0\";\n } catch (error) {\n this.csl(\"Sui getSUIBalance\", \"red-500\", \"Get SUI balance failed: %o\", error);\n return \"0\";\n }\n }\n\n async getTokenBalance(contractAddress: string, account: string) {\n try {\n const response = await this.suiClient.core.getBalance({\n owner: account,\n coinType: contractAddress,\n });\n return response.balance.balance || \"0\";\n } catch (error) {\n this.csl(\"Sui getTokenBalance\", \"red-500\", \"Get token balance failed: %o\", error);\n return \"0\";\n }\n }\n\n async getBalance(token: any, account: string) {\n if (token.symbol === \"SUI\" || token.symbol === \"sui\" || token.symbol === \"native\") {\n return await this.getSUIBalance(account);\n }\n return await this.getTokenBalance(token.contractAddress, account);\n }\n\n async balanceOf(token: any, account: string) {\n return await this.getBalance(token, account);\n }\n\n async estimateTransferGas(data: {\n fromToken: any;\n depositAddress: string;\n amount: string;\n }): Promise<{\n gasLimit: bigint;\n gasPrice: bigint;\n estimateGas: bigint;\n }> {\n if (!this.account) {\n throw new Error(\"Wallet not connected\");\n }\n\n const { fromToken, depositAddress, amount } = data;\n const sender = this.account?.address?.toString();\n if (!sender) {\n throw new Error(\"Invalid sender address\");\n }\n\n const tx = new Transaction();\n const originAsset = fromToken?.contractAddress;\n const isNative = originAsset === \"SUI\" || originAsset === \"sui\" || originAsset === \"native\";\n\n if (isNative) {\n const [coinToSend] = tx.splitCoins(tx.gas, [BigInt(amount)]);\n tx.transferObjects([coinToSend], depositAddress);\n } else {\n const coinsResponse = await this.suiClient.listCoins({\n owner: sender,\n coinType: originAsset,\n limit: 50,\n });\n\n if (!coinsResponse.objects?.length) {\n throw new Error(\"No token coins found for gas estimation\");\n }\n\n const [primaryCoin, ...restCoins] = coinsResponse.objects;\n const primaryInput = tx.object(primaryCoin.objectId);\n if (restCoins.length) {\n tx.mergeCoins(\n primaryInput,\n restCoins.map((coin: any) => tx.object(coin.objectId)),\n );\n }\n const [coinToSend] = tx.splitCoins(primaryInput, [BigInt(amount)]);\n tx.transferObjects([coinToSend], depositAddress);\n }\n\n const ett = await this.estimateTransaction({\n dry: false,\n tx,\n fromToken,\n prices: {},\n });\n\n return {\n gasLimit: ett.estimateSourceGasLimit,\n gasPrice: 1n,\n estimateGas: ett.estimateSourceGas,\n };\n }\n\n async getEstimateGas(params: any) {\n const { gasLimit, price, nativeToken } = params;\n\n const finalGasPrice = 1;\n // try {\n // const { referenceGasPrice } = await this.suiClient.getReferenceGasPrice();\n // finalGasPrice = referenceGasPrice || BigInt(\"600\");\n // } catch {\n // }\n\n const estimateGas = BigInt(gasLimit) * BigInt(finalGasPrice);\n const estimateGasAmount = Big(estimateGas.toString()).div(10 ** nativeToken.decimals);\n const estimateGasUsd = Big(estimateGasAmount).times(price || 1);\n\n return {\n gasPrice: finalGasPrice,\n usd: numberRemoveEndZero(Big(estimateGasUsd).toFixed(20)),\n wei: estimateGas,\n amount: numberRemoveEndZero(Big(estimateGasAmount).toFixed(nativeToken.decimals)),\n };\n }\n\n async estimateTransaction(params: any) {\n const {\n dry,\n tx,\n fromToken,\n prices,\n defaultGasLimit = DEFAULT_GAS_LIMIT,\n } = params;\n\n const nativeTokenPrice = getPrice(prices, fromToken.nativeToken.symbol);\n\n const result = {\n estimateSourceGasLimit: DEFAULT_GAS_LIMIT,\n estimateSourceGas: 0n,\n estimateSourceGasUsd: \"0\",\n };\n\n const setDefaultGasLimit = async () => {\n const { usd, wei } = await this.getEstimateGas({\n gasLimit: DEFAULT_GAS_LIMIT,\n price: nativeTokenPrice,\n nativeToken: fromToken.nativeToken,\n });\n result.estimateSourceGas = wei;\n result.estimateSourceGasUsd = usd;\n };\n\n let finalGasLimit = defaultGasLimit;\n\n if (dry) {\n await setDefaultGasLimit();\n return result;\n }\n\n let sender = this.account?.address;\n if (!sender) {\n sender = DefaultAddresses[\"sui\"];\n }\n let simulation: any;\n try {\n tx.setSender(sender);\n\n const txBytes = await tx.build({ client: this.suiClient });\n\n const simulation = await this.suiClient.core.simulateTransaction({\n transaction: txBytes,\n checksEnabled: false,\n include: {\n effects: true,\n },\n });\n\n const simulationTx = simulation.$kind === \"Transaction\" ? simulation.Transaction : simulation.FailedTransaction;\n const gasUsed = simulationTx?.effects?.gasUsed;\n finalGasLimit = BigInt(gasUsed?.computationCost || \"0\")\n + BigInt(gasUsed?.storageCost || \"0\")\n - BigInt(gasUsed?.storageRebate || \"0\");\n\n finalGasLimit = (finalGasLimit * 150n) / 100n; // Add 50% buffer\n\n const { usd, wei } = await this.getEstimateGas({\n gasLimit: finalGasLimit,\n price: nativeTokenPrice,\n nativeToken: fromToken.nativeToken,\n });\n\n result.estimateSourceGasLimit = finalGasLimit;\n result.estimateSourceGas = wei;\n result.estimateSourceGasUsd = usd;\n } catch (error) {\n this.csl(\"Aptos estimateTransaction\", \"red-500\", \"simulation failed: %o\", error);\n await setDefaultGasLimit();\n }\n\n return result;\n }\n\n async checkTransactionStatus(signature: string) {\n try {\n const tx = await this.suiClient.core.waitForTransaction({\n digest: signature,\n });\n return tx.Transaction?.status?.success === true;\n } catch (error) {\n this.csl(\"Sui checkTransactionStatus\", \"red-500\", \"Check transaction status failed: %o\", error);\n return false;\n }\n }\n\n async quoteOneClickProxy(params: any) {\n const {\n dry,\n proxyAddress,\n fromToken,\n depositAddress,\n amountWei,\n prices,\n } = params;\n\n const result: any = { fees: {} };\n\n if (!depositAddress) {\n throw new Error(\"depositAddress is required\");\n }\n\n const tx = new Transaction();\n\n const payCoin = coinWithBalance({\n type: fromToken.contractAddress,\n balance: amountWei,\n useGasCoin: false,\n });\n\n tx.moveCall({\n target: `${proxyAddress}::proxy_transfer::proxy_transfer`,\n typeArguments: [fromToken.contractAddress],\n arguments: [payCoin, tx.pure.u64(amountWei), tx.pure.address(depositAddress)],\n });\n\n result.sendParam = { tx };\n\n const ett = await this.estimateTransaction({\n dry,\n tx,\n fromToken,\n prices,\n });\n result.fees.estimateGasUsd = ett.estimateSourceGasUsd;\n result.estimateSourceGas = ett.estimateSourceGas;\n result.totalEstimateSourceGas = ett.estimateSourceGas;\n result.estimateSourceGasUsd = ett.estimateSourceGasUsd;\n\n return result;\n }\n\n async sendTransaction(params: any) {\n if (!this.account) {\n throw new Error(\"Wallet not connected\");\n }\n\n const { tx } = params;\n\n try {\n const sender = this.account?.address?.toString();\n if (!sender) {\n throw new Error(\"Invalid sender address\");\n }\n\n const result = await this.signAndExecuteTransaction({\n transaction: tx,\n options: {\n showEffects: true,\n showBalanceChanges: true,\n },\n });\n\n return typeof result === \"string\" ? result : result.Transaction.digest;\n } catch (error) {\n this.csl(\"Sui sendTransaction\", \"red-500\", \"Send transaction failed: %o\", error);\n throw error;\n }\n }\n\n async quote(type: Service, params: any) {\n switch (type) {\n case Service.OneClick:\n return await this.quoteOneClickProxy(params);\n default:\n throw new Error(`Unsupported quote type: ${type}`);\n }\n }\n\n async send(type: SendType, params: any) {\n switch (type) {\n case SendType.SEND:\n return await this.sendTransaction(params);\n case SendType.TRANSFER:\n return await this.transfer(params);\n default:\n throw new Error(`Unsupported send type: ${type}`);\n }\n }\n}\n\nexport { SuiWallet };\n"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,345 @@
1
+ import { Transaction, coinWithBalance } from '@mysten/sui/transactions';
2
+ import Big from 'big.js';
3
+ import { SuiGrpcClient } from '@mysten/sui/grpc';
4
+ import { getChainRpcUrl, Csl, OpenAPI, numberRemoveEndZero, getPrice, DefaultAddresses, Service, SendType } from '@stableflow/core';
5
+
6
+ // src/sui.ts
7
+ var SUI_COIN_TYPE = "0x2::sui::SUI";
8
+ var DEFAULT_GAS_LIMIT = 3000000n;
9
+ var SuiWallet = class {
10
+ constructor(options) {
11
+ this.signAndExecuteTransaction = options.signAndExecuteTransaction;
12
+ this.account = options.account;
13
+ this.suiClient = new SuiGrpcClient({
14
+ network: "mainnet",
15
+ baseUrl: getChainRpcUrl("sui").rpcUrl
16
+ });
17
+ const cs = new Csl(OpenAPI.DEBUG);
18
+ this.csl = cs.log;
19
+ }
20
+ // Transfer SUI
21
+ async transferSUI(to, amount) {
22
+ if (!this.account) {
23
+ throw new Error("Wallet not connected");
24
+ }
25
+ try {
26
+ const tx = new Transaction();
27
+ const amountInMist = BigInt(Math.floor(parseFloat(amount) * 10 ** 9));
28
+ const [coinToSend] = tx.splitCoins(tx.gas, [amountInMist]);
29
+ tx.transferObjects([coinToSend], to);
30
+ const result = await this.signAndExecuteTransaction({
31
+ transaction: tx,
32
+ options: {
33
+ showEffects: true,
34
+ showBalanceChanges: true
35
+ }
36
+ });
37
+ return typeof result === "string" ? result : result.Transaction.digest;
38
+ } catch (error) {
39
+ this.csl("Sui transferSUI", "red-500", "Transfer APT failed: %o", error);
40
+ throw error;
41
+ }
42
+ }
43
+ // Transfer token
44
+ async transferToken(contractAddress, to, amount) {
45
+ if (!this.account) {
46
+ throw new Error("Wallet not connected");
47
+ }
48
+ try {
49
+ const owner = this.account?.address?.toString();
50
+ if (!owner) {
51
+ throw new Error("Invalid sender address");
52
+ }
53
+ const amountBigInt = BigInt(amount);
54
+ const coinsResponse = await this.suiClient.listCoins({
55
+ owner,
56
+ coinType: contractAddress,
57
+ limit: 50
58
+ });
59
+ if (!coinsResponse.objects?.length) {
60
+ throw new Error("Insufficient token balance");
61
+ }
62
+ const [primaryCoin, ...restCoins] = coinsResponse.objects;
63
+ const tx = new Transaction();
64
+ const primaryInput = tx.object(primaryCoin.objectId);
65
+ if (restCoins.length) {
66
+ tx.mergeCoins(
67
+ primaryInput,
68
+ restCoins.map((coin) => tx.object(coin.objectId))
69
+ );
70
+ }
71
+ const [coinToSend] = tx.splitCoins(primaryInput, [amountBigInt]);
72
+ tx.transferObjects([coinToSend], to);
73
+ const result = await this.signAndExecuteTransaction({
74
+ transaction: tx,
75
+ options: {
76
+ showEffects: true,
77
+ showBalanceChanges: true
78
+ }
79
+ });
80
+ return typeof result === "string" ? result : result.Transaction.digest;
81
+ } catch (error) {
82
+ this.csl("Sui transferToken", "red-500", "Transfer token failed: %o", error);
83
+ throw error;
84
+ }
85
+ }
86
+ // Generic transfer method
87
+ async transfer(data) {
88
+ const { originAsset, depositAddress, amount } = data;
89
+ if (originAsset === "SUI" || originAsset === "sui" || originAsset === "native") {
90
+ return await this.transferSUI(depositAddress, amount);
91
+ }
92
+ const result = await this.transferToken(
93
+ originAsset,
94
+ depositAddress,
95
+ amount
96
+ );
97
+ return result;
98
+ }
99
+ async getSUIBalance(account) {
100
+ try {
101
+ const response = await this.suiClient.core.getBalance({
102
+ owner: account,
103
+ coinType: SUI_COIN_TYPE
104
+ });
105
+ return response.balance.balance || "0";
106
+ } catch (error) {
107
+ this.csl("Sui getSUIBalance", "red-500", "Get SUI balance failed: %o", error);
108
+ return "0";
109
+ }
110
+ }
111
+ async getTokenBalance(contractAddress, account) {
112
+ try {
113
+ const response = await this.suiClient.core.getBalance({
114
+ owner: account,
115
+ coinType: contractAddress
116
+ });
117
+ return response.balance.balance || "0";
118
+ } catch (error) {
119
+ this.csl("Sui getTokenBalance", "red-500", "Get token balance failed: %o", error);
120
+ return "0";
121
+ }
122
+ }
123
+ async getBalance(token, account) {
124
+ if (token.symbol === "SUI" || token.symbol === "sui" || token.symbol === "native") {
125
+ return await this.getSUIBalance(account);
126
+ }
127
+ return await this.getTokenBalance(token.contractAddress, account);
128
+ }
129
+ async balanceOf(token, account) {
130
+ return await this.getBalance(token, account);
131
+ }
132
+ async estimateTransferGas(data) {
133
+ if (!this.account) {
134
+ throw new Error("Wallet not connected");
135
+ }
136
+ const { fromToken, depositAddress, amount } = data;
137
+ const sender = this.account?.address?.toString();
138
+ if (!sender) {
139
+ throw new Error("Invalid sender address");
140
+ }
141
+ const tx = new Transaction();
142
+ const originAsset = fromToken?.contractAddress;
143
+ const isNative = originAsset === "SUI" || originAsset === "sui" || originAsset === "native";
144
+ if (isNative) {
145
+ const [coinToSend] = tx.splitCoins(tx.gas, [BigInt(amount)]);
146
+ tx.transferObjects([coinToSend], depositAddress);
147
+ } else {
148
+ const coinsResponse = await this.suiClient.listCoins({
149
+ owner: sender,
150
+ coinType: originAsset,
151
+ limit: 50
152
+ });
153
+ if (!coinsResponse.objects?.length) {
154
+ throw new Error("No token coins found for gas estimation");
155
+ }
156
+ const [primaryCoin, ...restCoins] = coinsResponse.objects;
157
+ const primaryInput = tx.object(primaryCoin.objectId);
158
+ if (restCoins.length) {
159
+ tx.mergeCoins(
160
+ primaryInput,
161
+ restCoins.map((coin) => tx.object(coin.objectId))
162
+ );
163
+ }
164
+ const [coinToSend] = tx.splitCoins(primaryInput, [BigInt(amount)]);
165
+ tx.transferObjects([coinToSend], depositAddress);
166
+ }
167
+ const ett = await this.estimateTransaction({
168
+ dry: false,
169
+ tx,
170
+ fromToken,
171
+ prices: {}
172
+ });
173
+ return {
174
+ gasLimit: ett.estimateSourceGasLimit,
175
+ gasPrice: 1n,
176
+ estimateGas: ett.estimateSourceGas
177
+ };
178
+ }
179
+ async getEstimateGas(params) {
180
+ const { gasLimit, price, nativeToken } = params;
181
+ const finalGasPrice = 1;
182
+ const estimateGas = BigInt(gasLimit) * BigInt(finalGasPrice);
183
+ const estimateGasAmount = Big(estimateGas.toString()).div(10 ** nativeToken.decimals);
184
+ const estimateGasUsd = Big(estimateGasAmount).times(price || 1);
185
+ return {
186
+ gasPrice: finalGasPrice,
187
+ usd: numberRemoveEndZero(Big(estimateGasUsd).toFixed(20)),
188
+ wei: estimateGas,
189
+ amount: numberRemoveEndZero(Big(estimateGasAmount).toFixed(nativeToken.decimals))
190
+ };
191
+ }
192
+ async estimateTransaction(params) {
193
+ const {
194
+ dry,
195
+ tx,
196
+ fromToken,
197
+ prices,
198
+ defaultGasLimit = DEFAULT_GAS_LIMIT
199
+ } = params;
200
+ const nativeTokenPrice = getPrice(prices, fromToken.nativeToken.symbol);
201
+ const result = {
202
+ estimateSourceGasLimit: DEFAULT_GAS_LIMIT,
203
+ estimateSourceGas: 0n,
204
+ estimateSourceGasUsd: "0"
205
+ };
206
+ const setDefaultGasLimit = async () => {
207
+ const { usd, wei } = await this.getEstimateGas({
208
+ gasLimit: DEFAULT_GAS_LIMIT,
209
+ price: nativeTokenPrice,
210
+ nativeToken: fromToken.nativeToken
211
+ });
212
+ result.estimateSourceGas = wei;
213
+ result.estimateSourceGasUsd = usd;
214
+ };
215
+ let finalGasLimit = defaultGasLimit;
216
+ if (dry) {
217
+ await setDefaultGasLimit();
218
+ return result;
219
+ }
220
+ let sender = this.account?.address;
221
+ if (!sender) {
222
+ sender = DefaultAddresses["sui"];
223
+ }
224
+ try {
225
+ tx.setSender(sender);
226
+ const txBytes = await tx.build({ client: this.suiClient });
227
+ const simulation2 = await this.suiClient.core.simulateTransaction({
228
+ transaction: txBytes,
229
+ checksEnabled: false,
230
+ include: {
231
+ effects: true
232
+ }
233
+ });
234
+ const simulationTx = simulation2.$kind === "Transaction" ? simulation2.Transaction : simulation2.FailedTransaction;
235
+ const gasUsed = simulationTx?.effects?.gasUsed;
236
+ finalGasLimit = BigInt(gasUsed?.computationCost || "0") + BigInt(gasUsed?.storageCost || "0") - BigInt(gasUsed?.storageRebate || "0");
237
+ finalGasLimit = finalGasLimit * 150n / 100n;
238
+ const { usd, wei } = await this.getEstimateGas({
239
+ gasLimit: finalGasLimit,
240
+ price: nativeTokenPrice,
241
+ nativeToken: fromToken.nativeToken
242
+ });
243
+ result.estimateSourceGasLimit = finalGasLimit;
244
+ result.estimateSourceGas = wei;
245
+ result.estimateSourceGasUsd = usd;
246
+ } catch (error) {
247
+ this.csl("Aptos estimateTransaction", "red-500", "simulation failed: %o", error);
248
+ await setDefaultGasLimit();
249
+ }
250
+ return result;
251
+ }
252
+ async checkTransactionStatus(signature) {
253
+ try {
254
+ const tx = await this.suiClient.core.waitForTransaction({
255
+ digest: signature
256
+ });
257
+ return tx.Transaction?.status?.success === true;
258
+ } catch (error) {
259
+ this.csl("Sui checkTransactionStatus", "red-500", "Check transaction status failed: %o", error);
260
+ return false;
261
+ }
262
+ }
263
+ async quoteOneClickProxy(params) {
264
+ const {
265
+ dry,
266
+ proxyAddress,
267
+ fromToken,
268
+ depositAddress,
269
+ amountWei,
270
+ prices
271
+ } = params;
272
+ const result = { fees: {} };
273
+ if (!depositAddress) {
274
+ throw new Error("depositAddress is required");
275
+ }
276
+ const tx = new Transaction();
277
+ const payCoin = coinWithBalance({
278
+ type: fromToken.contractAddress,
279
+ balance: amountWei,
280
+ useGasCoin: false
281
+ });
282
+ tx.moveCall({
283
+ target: `${proxyAddress}::proxy_transfer::proxy_transfer`,
284
+ typeArguments: [fromToken.contractAddress],
285
+ arguments: [payCoin, tx.pure.u64(amountWei), tx.pure.address(depositAddress)]
286
+ });
287
+ result.sendParam = { tx };
288
+ const ett = await this.estimateTransaction({
289
+ dry,
290
+ tx,
291
+ fromToken,
292
+ prices
293
+ });
294
+ result.fees.estimateGasUsd = ett.estimateSourceGasUsd;
295
+ result.estimateSourceGas = ett.estimateSourceGas;
296
+ result.totalEstimateSourceGas = ett.estimateSourceGas;
297
+ result.estimateSourceGasUsd = ett.estimateSourceGasUsd;
298
+ return result;
299
+ }
300
+ async sendTransaction(params) {
301
+ if (!this.account) {
302
+ throw new Error("Wallet not connected");
303
+ }
304
+ const { tx } = params;
305
+ try {
306
+ const sender = this.account?.address?.toString();
307
+ if (!sender) {
308
+ throw new Error("Invalid sender address");
309
+ }
310
+ const result = await this.signAndExecuteTransaction({
311
+ transaction: tx,
312
+ options: {
313
+ showEffects: true,
314
+ showBalanceChanges: true
315
+ }
316
+ });
317
+ return typeof result === "string" ? result : result.Transaction.digest;
318
+ } catch (error) {
319
+ this.csl("Sui sendTransaction", "red-500", "Send transaction failed: %o", error);
320
+ throw error;
321
+ }
322
+ }
323
+ async quote(type, params) {
324
+ switch (type) {
325
+ case Service.OneClick:
326
+ return await this.quoteOneClickProxy(params);
327
+ default:
328
+ throw new Error(`Unsupported quote type: ${type}`);
329
+ }
330
+ }
331
+ async send(type, params) {
332
+ switch (type) {
333
+ case SendType.SEND:
334
+ return await this.sendTransaction(params);
335
+ case SendType.TRANSFER:
336
+ return await this.transfer(params);
337
+ default:
338
+ throw new Error(`Unsupported send type: ${type}`);
339
+ }
340
+ }
341
+ };
342
+
343
+ export { SuiWallet, SuiWallet as default };
344
+ //# sourceMappingURL=index.mjs.map
345
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sui.ts"],"names":["simulation"],"mappings":"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","file":"index.mjs","sourcesContent":["import { coinWithBalance, Transaction } from \"@mysten/sui/transactions\";\nimport Big from \"big.js\";\nimport { SuiGrpcClient } from \"@mysten/sui/grpc\";\nimport {\n DefaultAddresses,\n getChainRpcUrl,\n Csl,\n OpenAPI,\n numberRemoveEndZero,\n SendType,\n Service,\n getPrice,\n} from '@stableflow/core';\n\nconst SUI_COIN_TYPE = \"0x2::sui::SUI\";\nconst DEFAULT_GAS_LIMIT = 3000000n;\n\nexport default class SuiWallet {\n private account: any | null;\n private signAndExecuteTransaction: any;\n private suiClient: SuiGrpcClient;\n private csl;\n\n constructor(options: { account: any | null; signAndExecuteTransaction: any; }) {\n this.signAndExecuteTransaction = options.signAndExecuteTransaction;\n this.account = options.account;\n this.suiClient = new SuiGrpcClient({\n network: \"mainnet\",\n baseUrl: getChainRpcUrl(\"sui\").rpcUrl,\n });\n\n const cs = new Csl(OpenAPI.DEBUG);\n this.csl = cs.log;\n }\n\n // Transfer SUI\n async transferSUI(to: string, amount: string): Promise<string> {\n if (!this.account) {\n throw new Error(\"Wallet not connected\");\n }\n\n try {\n const tx = new Transaction();\n\n // Convert amount to octas (1 SUI = 10^9)\n const amountInMist = BigInt(Math.floor(parseFloat(amount) * 10 ** 9));\n\n const [coinToSend] = tx.splitCoins(tx.gas, [amountInMist]);\n\n tx.transferObjects([coinToSend], to);\n\n // Sign and submit transaction\n const result = await this.signAndExecuteTransaction({\n transaction: tx,\n options: {\n showEffects: true,\n showBalanceChanges: true,\n },\n });\n\n return typeof result === \"string\" ? result : result.Transaction.digest;\n } catch (error) {\n this.csl(\"Sui transferSUI\", \"red-500\", \"Transfer APT failed: %o\", error);\n throw error;\n }\n }\n\n // Transfer token\n async transferToken(contractAddress: string, to: string, amount: string): Promise<string> {\n if (!this.account) {\n throw new Error(\"Wallet not connected\");\n }\n\n try {\n const owner = this.account?.address?.toString();\n if (!owner) {\n throw new Error(\"Invalid sender address\");\n }\n\n const amountBigInt = BigInt(amount);\n const coinsResponse = await this.suiClient.listCoins({\n owner,\n coinType: contractAddress,\n limit: 50,\n });\n\n if (!coinsResponse.objects?.length) {\n throw new Error(\"Insufficient token balance\");\n }\n\n const [primaryCoin, ...restCoins] = coinsResponse.objects;\n const tx = new Transaction();\n const primaryInput = tx.object(primaryCoin.objectId);\n\n if (restCoins.length) {\n tx.mergeCoins(\n primaryInput,\n restCoins.map((coin: any) => tx.object(coin.objectId)),\n );\n }\n\n const [coinToSend] = tx.splitCoins(primaryInput, [amountBigInt]);\n tx.transferObjects([coinToSend], to);\n\n const result = await this.signAndExecuteTransaction({\n transaction: tx,\n options: {\n showEffects: true,\n showBalanceChanges: true,\n },\n });\n\n return typeof result === \"string\" ? result : result.Transaction.digest;\n } catch (error) {\n this.csl(\"Sui transferToken\", \"red-500\", \"Transfer token failed: %o\", error);\n throw error;\n }\n }\n\n // Generic transfer method\n async transfer(data: {\n originAsset: string;\n depositAddress: string;\n amount: string;\n }): Promise<string> {\n const { originAsset, depositAddress, amount } = data;\n\n // Transfer SUI\n if (originAsset === \"SUI\" || originAsset === \"sui\" || originAsset === \"native\") {\n return await this.transferSUI(depositAddress, amount);\n }\n\n // Transfer token\n const result = await this.transferToken(\n originAsset,\n depositAddress,\n amount\n );\n return result;\n }\n\n async getSUIBalance(account: string) {\n try {\n const response = await this.suiClient.core.getBalance({\n owner: account,\n coinType: SUI_COIN_TYPE,\n });\n return response.balance.balance || \"0\";\n } catch (error) {\n this.csl(\"Sui getSUIBalance\", \"red-500\", \"Get SUI balance failed: %o\", error);\n return \"0\";\n }\n }\n\n async getTokenBalance(contractAddress: string, account: string) {\n try {\n const response = await this.suiClient.core.getBalance({\n owner: account,\n coinType: contractAddress,\n });\n return response.balance.balance || \"0\";\n } catch (error) {\n this.csl(\"Sui getTokenBalance\", \"red-500\", \"Get token balance failed: %o\", error);\n return \"0\";\n }\n }\n\n async getBalance(token: any, account: string) {\n if (token.symbol === \"SUI\" || token.symbol === \"sui\" || token.symbol === \"native\") {\n return await this.getSUIBalance(account);\n }\n return await this.getTokenBalance(token.contractAddress, account);\n }\n\n async balanceOf(token: any, account: string) {\n return await this.getBalance(token, account);\n }\n\n async estimateTransferGas(data: {\n fromToken: any;\n depositAddress: string;\n amount: string;\n }): Promise<{\n gasLimit: bigint;\n gasPrice: bigint;\n estimateGas: bigint;\n }> {\n if (!this.account) {\n throw new Error(\"Wallet not connected\");\n }\n\n const { fromToken, depositAddress, amount } = data;\n const sender = this.account?.address?.toString();\n if (!sender) {\n throw new Error(\"Invalid sender address\");\n }\n\n const tx = new Transaction();\n const originAsset = fromToken?.contractAddress;\n const isNative = originAsset === \"SUI\" || originAsset === \"sui\" || originAsset === \"native\";\n\n if (isNative) {\n const [coinToSend] = tx.splitCoins(tx.gas, [BigInt(amount)]);\n tx.transferObjects([coinToSend], depositAddress);\n } else {\n const coinsResponse = await this.suiClient.listCoins({\n owner: sender,\n coinType: originAsset,\n limit: 50,\n });\n\n if (!coinsResponse.objects?.length) {\n throw new Error(\"No token coins found for gas estimation\");\n }\n\n const [primaryCoin, ...restCoins] = coinsResponse.objects;\n const primaryInput = tx.object(primaryCoin.objectId);\n if (restCoins.length) {\n tx.mergeCoins(\n primaryInput,\n restCoins.map((coin: any) => tx.object(coin.objectId)),\n );\n }\n const [coinToSend] = tx.splitCoins(primaryInput, [BigInt(amount)]);\n tx.transferObjects([coinToSend], depositAddress);\n }\n\n const ett = await this.estimateTransaction({\n dry: false,\n tx,\n fromToken,\n prices: {},\n });\n\n return {\n gasLimit: ett.estimateSourceGasLimit,\n gasPrice: 1n,\n estimateGas: ett.estimateSourceGas,\n };\n }\n\n async getEstimateGas(params: any) {\n const { gasLimit, price, nativeToken } = params;\n\n const finalGasPrice = 1;\n // try {\n // const { referenceGasPrice } = await this.suiClient.getReferenceGasPrice();\n // finalGasPrice = referenceGasPrice || BigInt(\"600\");\n // } catch {\n // }\n\n const estimateGas = BigInt(gasLimit) * BigInt(finalGasPrice);\n const estimateGasAmount = Big(estimateGas.toString()).div(10 ** nativeToken.decimals);\n const estimateGasUsd = Big(estimateGasAmount).times(price || 1);\n\n return {\n gasPrice: finalGasPrice,\n usd: numberRemoveEndZero(Big(estimateGasUsd).toFixed(20)),\n wei: estimateGas,\n amount: numberRemoveEndZero(Big(estimateGasAmount).toFixed(nativeToken.decimals)),\n };\n }\n\n async estimateTransaction(params: any) {\n const {\n dry,\n tx,\n fromToken,\n prices,\n defaultGasLimit = DEFAULT_GAS_LIMIT,\n } = params;\n\n const nativeTokenPrice = getPrice(prices, fromToken.nativeToken.symbol);\n\n const result = {\n estimateSourceGasLimit: DEFAULT_GAS_LIMIT,\n estimateSourceGas: 0n,\n estimateSourceGasUsd: \"0\",\n };\n\n const setDefaultGasLimit = async () => {\n const { usd, wei } = await this.getEstimateGas({\n gasLimit: DEFAULT_GAS_LIMIT,\n price: nativeTokenPrice,\n nativeToken: fromToken.nativeToken,\n });\n result.estimateSourceGas = wei;\n result.estimateSourceGasUsd = usd;\n };\n\n let finalGasLimit = defaultGasLimit;\n\n if (dry) {\n await setDefaultGasLimit();\n return result;\n }\n\n let sender = this.account?.address;\n if (!sender) {\n sender = DefaultAddresses[\"sui\"];\n }\n let simulation: any;\n try {\n tx.setSender(sender);\n\n const txBytes = await tx.build({ client: this.suiClient });\n\n const simulation = await this.suiClient.core.simulateTransaction({\n transaction: txBytes,\n checksEnabled: false,\n include: {\n effects: true,\n },\n });\n\n const simulationTx = simulation.$kind === \"Transaction\" ? simulation.Transaction : simulation.FailedTransaction;\n const gasUsed = simulationTx?.effects?.gasUsed;\n finalGasLimit = BigInt(gasUsed?.computationCost || \"0\")\n + BigInt(gasUsed?.storageCost || \"0\")\n - BigInt(gasUsed?.storageRebate || \"0\");\n\n finalGasLimit = (finalGasLimit * 150n) / 100n; // Add 50% buffer\n\n const { usd, wei } = await this.getEstimateGas({\n gasLimit: finalGasLimit,\n price: nativeTokenPrice,\n nativeToken: fromToken.nativeToken,\n });\n\n result.estimateSourceGasLimit = finalGasLimit;\n result.estimateSourceGas = wei;\n result.estimateSourceGasUsd = usd;\n } catch (error) {\n this.csl(\"Aptos estimateTransaction\", \"red-500\", \"simulation failed: %o\", error);\n await setDefaultGasLimit();\n }\n\n return result;\n }\n\n async checkTransactionStatus(signature: string) {\n try {\n const tx = await this.suiClient.core.waitForTransaction({\n digest: signature,\n });\n return tx.Transaction?.status?.success === true;\n } catch (error) {\n this.csl(\"Sui checkTransactionStatus\", \"red-500\", \"Check transaction status failed: %o\", error);\n return false;\n }\n }\n\n async quoteOneClickProxy(params: any) {\n const {\n dry,\n proxyAddress,\n fromToken,\n depositAddress,\n amountWei,\n prices,\n } = params;\n\n const result: any = { fees: {} };\n\n if (!depositAddress) {\n throw new Error(\"depositAddress is required\");\n }\n\n const tx = new Transaction();\n\n const payCoin = coinWithBalance({\n type: fromToken.contractAddress,\n balance: amountWei,\n useGasCoin: false,\n });\n\n tx.moveCall({\n target: `${proxyAddress}::proxy_transfer::proxy_transfer`,\n typeArguments: [fromToken.contractAddress],\n arguments: [payCoin, tx.pure.u64(amountWei), tx.pure.address(depositAddress)],\n });\n\n result.sendParam = { tx };\n\n const ett = await this.estimateTransaction({\n dry,\n tx,\n fromToken,\n prices,\n });\n result.fees.estimateGasUsd = ett.estimateSourceGasUsd;\n result.estimateSourceGas = ett.estimateSourceGas;\n result.totalEstimateSourceGas = ett.estimateSourceGas;\n result.estimateSourceGasUsd = ett.estimateSourceGasUsd;\n\n return result;\n }\n\n async sendTransaction(params: any) {\n if (!this.account) {\n throw new Error(\"Wallet not connected\");\n }\n\n const { tx } = params;\n\n try {\n const sender = this.account?.address?.toString();\n if (!sender) {\n throw new Error(\"Invalid sender address\");\n }\n\n const result = await this.signAndExecuteTransaction({\n transaction: tx,\n options: {\n showEffects: true,\n showBalanceChanges: true,\n },\n });\n\n return typeof result === \"string\" ? result : result.Transaction.digest;\n } catch (error) {\n this.csl(\"Sui sendTransaction\", \"red-500\", \"Send transaction failed: %o\", error);\n throw error;\n }\n }\n\n async quote(type: Service, params: any) {\n switch (type) {\n case Service.OneClick:\n return await this.quoteOneClickProxy(params);\n default:\n throw new Error(`Unsupported quote type: ${type}`);\n }\n }\n\n async send(type: SendType, params: any) {\n switch (type) {\n case SendType.SEND:\n return await this.sendTransaction(params);\n case SendType.TRANSFER:\n return await this.transfer(params);\n default:\n throw new Error(`Unsupported send type: ${type}`);\n }\n }\n}\n\nexport { SuiWallet };\n"]}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@stableflow/wallet-sui",
3
+ "version": "0.0.0-experimental-5a8afd7389-20260703",
4
+ "description": "Sui wallet adapter for StableFlow SDK",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/stableflow-ai/stableflow-sdk.git",
9
+ "directory": "packages/wallet-sui"
10
+ },
11
+ "main": "./dist/index.js",
12
+ "module": "./dist/index.mjs",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.mjs",
18
+ "require": "./dist/index.js"
19
+ }
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "dependencies": {
25
+ "big.js": "^7.0.1",
26
+ "@stableflow/core": "0.0.0-experimental-5a8afd7389-20260703"
27
+ },
28
+ "peerDependencies": {
29
+ "@mysten/sui": "^2.16.2"
30
+ },
31
+ "devDependencies": {
32
+ "@types/big.js": "^6.2.2",
33
+ "tsup": "^8.5.1",
34
+ "typescript": "^5.9.3"
35
+ },
36
+ "scripts": {
37
+ "build": "tsup",
38
+ "clean": "rm -rf dist"
39
+ }
40
+ }