forked from block-vision/sui-go-sdk
/
write_transaction_api.go
371 lines (336 loc) · 12.5 KB
/
write_transaction_api.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
// Copyright (c) BlockVision, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package sui
import (
"context"
"github.com/yasir7ca/sui-go-sdk/common/httpconn"
"github.com/yasir7ca/sui-go-sdk/models"
)
type IWriteTransactionAPI interface {
SuiExecuteTransactionBlock(ctx context.Context, req models.SuiExecuteTransactionBlockRequest) (models.SuiTransactionBlockResponse, error)
MoveCall(ctx context.Context, req models.MoveCallRequest) (models.TxnMetaData, error)
MergeCoins(ctx context.Context, req models.MergeCoinsRequest) (models.TxnMetaData, error)
SplitCoin(ctx context.Context, req models.SplitCoinRequest) (models.TxnMetaData, error)
SplitCoinEqual(ctx context.Context, req models.SplitCoinEqualRequest) (models.TxnMetaData, error)
Publish(ctx context.Context, req models.PublishRequest) (models.TxnMetaData, error)
TransferObject(ctx context.Context, req models.TransferObjectRequest) (models.TxnMetaData, error)
TransferSui(ctx context.Context, req models.TransferSuiRequest) (models.TxnMetaData, error)
Pay(ctx context.Context, req models.PayRequest) (models.TxnMetaData, error)
PaySui(ctx context.Context, req models.PaySuiRequest) (models.TxnMetaData, error)
PayAllSui(ctx context.Context, req models.PayAllSuiRequest) (models.TxnMetaData, error)
RequestAddStake(ctx context.Context, req models.AddStakeRequest) (models.TxnMetaData, error)
RequestWithdrawStake(ctx context.Context, req models.WithdrawStakeRequest) (models.TxnMetaData, error)
BatchTransaction(ctx context.Context, req models.BatchTransactionRequest) (models.BatchTransactionResponse, error)
SignAndExecuteTransactionBlock(ctx context.Context, req models.SignAndExecuteTransactionBlockRequest) (models.SuiTransactionBlockResponse, error)
SignAndExecuteTransactionBlockWithKMS(ctx context.Context, req models.SignAndExecuteTransactionBlockRequestWithKMS) (models.SuiTransactionBlockResponse, error)
}
type suiWriteTransactionImpl struct {
conn *httpconn.HttpConn
}
// SuiExecuteTransactionBlock implements the method `sui_executeTransactionBlock`, executes a transaction using the transaction data and signature(s).
func (s *suiWriteTransactionImpl) SuiExecuteTransactionBlock(ctx context.Context, req models.SuiExecuteTransactionBlockRequest) (models.SuiTransactionBlockResponse, error) {
var rsp models.SuiTransactionBlockResponse
err := s.conn.CallContext(ctx, &rsp, httpconn.Operation{
Method: "sui_executeTransactionBlock",
Params: []interface{}{
req.TxBytes,
req.Signature,
req.Options,
req.RequestType,
},
})
if err != nil {
return rsp, err
}
return rsp, nil
}
// MoveCall implements the method `unsafe_moveCall`, creates an unsigned transaction to execute a Move call on the network, by calling the specified function in the module of a given package.
func (s *suiWriteTransactionImpl) MoveCall(ctx context.Context, req models.MoveCallRequest) (models.TxnMetaData, error) {
var rsp models.TxnMetaData
err := s.conn.CallContext(ctx, &rsp, httpconn.Operation{
Method: "unsafe_moveCall",
Params: []interface{}{
req.Signer,
req.PackageObjectId,
req.Module,
req.Function,
req.TypeArguments,
req.Arguments,
req.Gas,
req.GasBudget,
},
})
if err != nil {
return rsp, err
}
return rsp, nil
}
// MergeCoins implements the method `unsafe_mergeCoins`, creates an unsigned transaction to merge multiple coins into one coin.
func (s *suiWriteTransactionImpl) MergeCoins(ctx context.Context, req models.MergeCoinsRequest) (models.TxnMetaData, error) {
var rsp models.TxnMetaData
err := s.conn.CallContext(ctx, &rsp, httpconn.Operation{
Method: "unsafe_mergeCoins",
Params: []interface{}{
req.Signer,
req.PrimaryCoin,
req.CoinToMerge,
req.Gas,
req.GasBudget,
},
})
if err != nil {
return rsp, err
}
return rsp, nil
}
// SplitCoin implements the method `unsafe_splitCoin`, creates an unsigned transaction to split a coin object into multiple coins.
func (s *suiWriteTransactionImpl) SplitCoin(ctx context.Context, req models.SplitCoinRequest) (models.TxnMetaData, error) {
var rsp models.TxnMetaData
err := s.conn.CallContext(ctx, &rsp, httpconn.Operation{
Method: "unsafe_splitCoin",
Params: []interface{}{
req.Signer,
req.CoinObjectId,
req.SplitAmounts,
req.Gas,
req.GasBudget,
},
})
if err != nil {
return rsp, err
}
return rsp, nil
}
// SplitCoinEqual implements the method `unsafe_splitCoinEqual`, creates an unsigned transaction to split a coin object into multiple equal-size coins.
func (s *suiWriteTransactionImpl) SplitCoinEqual(ctx context.Context, req models.SplitCoinEqualRequest) (models.TxnMetaData, error) {
var rsp models.TxnMetaData
err := s.conn.CallContext(ctx, &rsp, httpconn.Operation{
Method: "unsafe_splitCoinEqual",
Params: []interface{}{
req.Signer,
req.CoinObjectId,
req.SplitCount,
req.Gas,
req.GasBudget,
},
})
if err != nil {
return rsp, err
}
return rsp, nil
}
// Publish implements the method `unsafe_publish`, creates an unsigned transaction to publish a Move package.
func (s *suiWriteTransactionImpl) Publish(ctx context.Context, req models.PublishRequest) (models.TxnMetaData, error) {
var rsp models.TxnMetaData
err := s.conn.CallContext(ctx, &rsp, httpconn.Operation{
Method: "unsafe_publish",
Params: []interface{}{
req.Sender,
req.CompiledModules,
req.Dependencies,
req.Gas,
req.GasBudget,
},
})
if err != nil {
return rsp, err
}
return rsp, nil
}
// TransferObject implements the method `unsafe_transferObject`, creates an unsigned transaction to transfer an object from one address to another. The object's type must allow public transfers.
func (s *suiWriteTransactionImpl) TransferObject(ctx context.Context, req models.TransferObjectRequest) (models.TxnMetaData, error) {
var rsp models.TxnMetaData
err := s.conn.CallContext(ctx, &rsp, httpconn.Operation{
Method: "unsafe_transferObject",
Params: []interface{}{
req.Signer,
req.ObjectId,
req.Gas,
req.GasBudget,
req.Recipient,
},
})
if err != nil {
return rsp, err
}
return rsp, nil
}
// TransferSui implements the method `unsafe_transferSui`, creates an unsigned transaction to send SUI coin object to a Sui address. The SUI object is also used as the gas object.
func (s *suiWriteTransactionImpl) TransferSui(ctx context.Context, req models.TransferSuiRequest) (models.TxnMetaData, error) {
var rsp models.TxnMetaData
err := s.conn.CallContext(ctx, &rsp, httpconn.Operation{
Method: "unsafe_transferSui",
Params: []interface{}{
req.Signer,
req.SuiObjectId,
req.GasBudget,
req.Recipient,
req.Amount,
},
})
if err != nil {
return rsp, err
}
return rsp, nil
}
// Pay implements the method `unsafe_pay`, send `Coin<T>` to a list of addresses, where `T` can be any coin type, following a list of amounts.
// The object specified in the `gas` field will be used to pay the gas fee for the transaction.
// The gas object can not appear in `input_coins`. If the gas object is not specified, the RPC server will auto-select one.
func (s *suiWriteTransactionImpl) Pay(ctx context.Context, req models.PayRequest) (models.TxnMetaData, error) {
var rsp models.TxnMetaData
err := s.conn.CallContext(ctx, &rsp, httpconn.Operation{
Method: "unsafe_pay",
Params: []interface{}{
req.Signer,
req.SuiObjectId,
req.Recipient,
req.Amount,
req.Gas,
req.GasBudget,
},
})
if err != nil {
return rsp, err
}
return rsp, nil
}
// PaySui implements the method `unsafe_paySui`, send SUI coins to a list of addresses, following a list of amounts.
// This is for SUI coin only and does not require a separate gas coin object.
// Specifically, what pay_sui does are:
// 1. debit each input_coin to create new coin following the order of amounts and assign it to the corresponding recipient.
// 2. accumulate all residual SUI from input coins left and deposit all SUI to the first input coin, then use the first input coin as the gas coin object.
// 3. the balance of the first input coin after tx is sum(input_coins) - sum(amounts) - actual_gas_cost
// 4. all other input coints other than the first one are deleted.
func (s *suiWriteTransactionImpl) PaySui(ctx context.Context, req models.PaySuiRequest) (models.TxnMetaData, error) {
var rsp models.TxnMetaData
err := s.conn.CallContext(ctx, &rsp, httpconn.Operation{
Method: "unsafe_paySui",
Params: []interface{}{
req.Signer,
req.SuiObjectId,
req.Recipient,
req.Amount,
req.GasBudget,
},
})
if err != nil {
return rsp, err
}
return rsp, nil
}
// PayAllSui implements the method `unsafe_payAllSui`, send all SUI coins to one recipient.
// This is for SUI coin only and does not require a separate gas coin object.
// Specifically, what pay_all_sui does are:
// 1. accumulate all SUI from input coins and deposit all SUI to the first input coin.
// 2. transfer the updated first coin to the recipient and also use this first coin as gas coin object.
// 3. the balance of the first input coin after tx is sum(input_coins) - actual_gas_cost.
// 4. all other input coins other than the first are deleted.
func (s *suiWriteTransactionImpl) PayAllSui(ctx context.Context, req models.PayAllSuiRequest) (models.TxnMetaData, error) {
var rsp models.TxnMetaData
err := s.conn.CallContext(ctx, &rsp, httpconn.Operation{
Method: "unsafe_payAllSui",
Params: []interface{}{
req.Signer,
req.SuiObjectId,
req.Recipient,
req.GasBudget,
},
})
if err != nil {
return rsp, err
}
return rsp, nil
}
// RequestAddStake implements the method `unsafe_requestAddStake`, add stake to a validator's staking pool using multiple coins and amount.
func (s *suiWriteTransactionImpl) RequestAddStake(ctx context.Context, req models.AddStakeRequest) (models.TxnMetaData, error) {
var rsp models.TxnMetaData
err := s.conn.CallContext(ctx, &rsp, httpconn.Operation{
Method: "unsafe_requestAddStake",
Params: []interface{}{
req.Signer,
req.Coins,
req.Amount,
req.Validator,
req.Gas,
req.GasBudget,
},
})
if err != nil {
return rsp, err
}
return rsp, nil
}
// RequestWithdrawStake implements the method `unsafe_requestWithdrawStake`, withdraw stake from a validator's staking pool.
func (s *suiWriteTransactionImpl) RequestWithdrawStake(ctx context.Context, req models.WithdrawStakeRequest) (models.TxnMetaData, error) {
var rsp models.TxnMetaData
err := s.conn.CallContext(ctx, &rsp, httpconn.Operation{
Method: "unsafe_requestWithdrawStake",
Params: []interface{}{
req.Signer,
req.StakedObjectId,
req.Gas,
req.GasBudget,
},
})
if err != nil {
return rsp, err
}
return rsp, nil
}
// BatchTransaction implements the method `unsafe_batchTransaction`, creates an unsigned batched transaction.
func (s *suiWriteTransactionImpl) BatchTransaction(ctx context.Context, req models.BatchTransactionRequest) (models.BatchTransactionResponse, error) {
var rsp models.BatchTransactionResponse
err := s.conn.CallContext(ctx, &rsp, httpconn.Operation{
Method: "unsafe_batchTransaction",
Params: []interface{}{
req.Signer,
req.RPCTransactionRequestParams,
req.Gas,
req.GasBudget,
req.SuiTransactionBlockBuilderMode,
},
})
if err != nil {
return rsp, err
}
return rsp, nil
}
// SignAndExecuteTransactionBlock sign a transaction block and submit to the Fullnode for execution.
func (s *suiWriteTransactionImpl) SignAndExecuteTransactionBlock(ctx context.Context, req models.SignAndExecuteTransactionBlockRequest) (models.SuiTransactionBlockResponse, error) {
var rsp models.SuiTransactionBlockResponse
signedTxn := req.TxnMetaData.SignSerializedSigWith(req.PriKey)
err := s.conn.CallContext(ctx, &rsp, httpconn.Operation{
Method: "sui_executeTransactionBlock",
Params: []interface{}{
signedTxn.TxBytes,
[]string{signedTxn.Signature},
req.Options,
req.RequestType,
},
})
if err != nil {
return rsp, err
}
return rsp, nil
}
// SignAndExecuteTransactionBlock sign a transaction block and submit to the Fullnode for execution.
func (s *suiWriteTransactionImpl) SignAndExecuteTransactionBlockWithKMS(ctx context.Context, req models.SignAndExecuteTransactionBlockRequestWithKMS) (models.SuiTransactionBlockResponse, error) {
var rsp models.SuiTransactionBlockResponse
signature, err_kms := req.TxnMetaData.SignSerializedSigWithKMS(req.KeyId, req.Kms, req.PublicKey)
if err_kms != nil {
return rsp, nil // returnn proper error here
}
err := s.conn.CallContext(ctx, &rsp, httpconn.Operation{
Method: "sui_executeTransactionBlock",
Params: []interface{}{
req.TxnMetaData.TxBytes,
[]string{signature},
req.Options,
req.RequestType,
},
})
if err != nil {
return rsp, err
}
return rsp, nil
}