@@ -3,6 +3,11 @@ package bindings
3
3
import (
4
4
"context"
5
5
"fmt"
6
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
7
+ "github.com/ethereum/go-ethereum/core/types"
8
+ "github.com/pkg/errors"
9
+ "github.com/unpackdev/solgo/clients"
10
+ "go.uber.org/zap"
6
11
"math/big"
7
12
8
13
"github.com/ethereum/go-ethereum/common"
@@ -212,6 +217,121 @@ func (t *Token) GetOptionsByNetwork(network utils.Network) *BindOptions {
212
217
return nil
213
218
}
214
219
220
+ func (t * Token ) Transfer (ctx context.Context , network utils.Network , simulatorType utils.SimulatorType , client * clients.Client , opts * bind.TransactOpts , to common.Address , amount * big.Int , atBlock * big.Int ) (* types.Transaction , * types.Receipt , error ) {
221
+ binding , err := t .GetBinding (utils .Ethereum , Erc20 )
222
+ if err != nil {
223
+ return nil , nil , err
224
+ }
225
+ bindingAbi := binding .GetABI ()
226
+
227
+ method , exists := bindingAbi .Methods ["transfer" ]
228
+ if ! exists {
229
+ return nil , nil , errors .New ("transfer method not found" )
230
+ }
231
+
232
+ select {
233
+ case <- ctx .Done ():
234
+ return nil , nil , ctx .Err ()
235
+ default :
236
+ input , err := bindingAbi .Pack (method .Name , to , amount )
237
+ if err != nil {
238
+ return nil , nil , err
239
+ }
240
+
241
+ tx , err := t .Manager .SendTransaction (opts , t .network , simulatorType , client , & binding .Address , input )
242
+ if err != nil {
243
+ return nil , nil , fmt .Errorf ("failed to send transfer transaction: %w" , err )
244
+ }
245
+
246
+ receipt , err := t .Manager .WaitForReceipt (t .ctx , network , simulatorType , client , tx .Hash ())
247
+ if err != nil {
248
+ return nil , nil , fmt .Errorf ("failed to get transfer transaction receipt: %w" , err )
249
+ }
250
+
251
+ return tx , receipt , nil
252
+ }
253
+ }
254
+
255
+ func (t * Token ) Approve (ctx context.Context , network utils.Network , simulatorType utils.SimulatorType , client * clients.Client , opts * bind.TransactOpts , from common.Address , spender common.Address , amount * big.Int , atBlock * big.Int ) (* types.Transaction , * types.Receipt , error ) {
256
+ binding , err := t .GetBinding (utils .Ethereum , Erc20 )
257
+ if err != nil {
258
+ return nil , nil , err
259
+ }
260
+ bindingAbi := binding .GetABI ()
261
+
262
+ method , exists := bindingAbi .Methods ["approve" ]
263
+ if ! exists {
264
+ return nil , nil , errors .New ("approve method not found" )
265
+ }
266
+
267
+ input , err := bindingAbi .Pack (method .Name , spender , amount )
268
+ if err != nil {
269
+ return nil , nil , err
270
+ }
271
+
272
+ select {
273
+ case <- ctx .Done ():
274
+ return nil , nil , ctx .Err ()
275
+ default :
276
+ tx , err := t .Manager .SendTransaction (opts , t .network , simulatorType , client , & from , input )
277
+ if err != nil {
278
+ return nil , nil , fmt .Errorf ("failed to send approve transaction: %w" , err )
279
+ }
280
+
281
+ receipt , err := t .Manager .WaitForReceipt (t .ctx , network , simulatorType , client , tx .Hash ())
282
+ if err != nil {
283
+ return nil , nil , fmt .Errorf ("failed to get approve transaction receipt: %w" , err )
284
+ }
285
+
286
+ zap .L ().Debug (
287
+ "Approve transaction sent and receipt received" ,
288
+ zap .String ("tx_hash" , tx .Hash ().Hex ()),
289
+ zap .String ("tx_from" , spender .Hex ()),
290
+ zap .String ("tx_to" , tx .To ().Hex ()),
291
+ zap .String ("tx_nonce" , fmt .Sprintf ("%d" , tx .Nonce ())),
292
+ zap .String ("tx_gas_price" , tx .GasPrice ().String ()),
293
+ zap .String ("tx_gas" , fmt .Sprintf ("%d" , tx .Gas ())),
294
+ )
295
+
296
+ return tx , receipt , nil
297
+ }
298
+ }
299
+
300
+ func (t * Token ) TransferFrom (ctx context.Context , network utils.Network , simulatorType utils.SimulatorType , client * clients.Client , opts * bind.TransactOpts , from , to common.Address , amount * big.Int , atBlock * big.Int ) (* types.Transaction , * types.Receipt , error ) {
301
+ binding , err := t .GetBinding (utils .Ethereum , Erc20 )
302
+ if err != nil {
303
+ return nil , nil , err
304
+ }
305
+ bindingAbi := binding .GetABI ()
306
+
307
+ method , exists := bindingAbi .Methods ["transferFrom" ]
308
+ if ! exists {
309
+ return nil , nil , errors .New ("transfer method not found" )
310
+ }
311
+
312
+ input , err := bindingAbi .Pack (method .Name , from , to , amount )
313
+ if err != nil {
314
+ return nil , nil , err
315
+ }
316
+
317
+ select {
318
+ case <- ctx .Done ():
319
+ return nil , nil , ctx .Err ()
320
+ default :
321
+ tx , err := t .Manager .SendTransaction (opts , t .network , simulatorType , client , & binding .Address , input )
322
+ if err != nil {
323
+ return nil , nil , fmt .Errorf ("failed to send transfer transaction: %w" , err )
324
+ }
325
+
326
+ receipt , err := t .Manager .WaitForReceipt (t .ctx , network , simulatorType , client , tx .Hash ())
327
+ if err != nil {
328
+ return nil , nil , fmt .Errorf ("failed to get transfer transaction receipt: %w" , err )
329
+ }
330
+
331
+ return tx , receipt , nil
332
+ }
333
+ }
334
+
215
335
// DefaultTokenBindOptions generates a default set of BindOptions for ERC20 and ERC20Ownable tokens. It presets
216
336
// configurations such as networks, network IDs, types, contract addresses, and ABIs based on standard
217
337
// implementations. This function simplifies the setup process for common token types.
0 commit comments