package withdrawals
import (
"context"
"crypto/ecdsa"
"math/big"
"strings"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
)
var chainID = big.NewInt(2184)
func SignNativeTransfer(ctx context.Context, client *ethclient.Client, key *ecdsa.PrivateKey, to common.Address, amount *big.Int) ([]byte, common.Hash, error) {
from := crypto.PubkeyToAddress(key.PublicKey)
nonce, err := client.PendingNonceAt(ctx, from)
if err != nil {
return nil, common.Hash{}, err
}
tip, err := client.SuggestGasTipCap(ctx)
if err != nil {
return nil, common.Hash{}, err
}
feeCap, err := client.SuggestGasPrice(ctx)
if err != nil {
return nil, common.Hash{}, err
}
tx := types.NewTx(&types.DynamicFeeTx{
ChainID: chainID,
Nonce: nonce,
GasTipCap: tip,
GasFeeCap: new(big.Int).Mul(feeCap, big.NewInt(2)),
Gas: 21_000,
To: &to,
Value: amount,
})
signed, err := types.SignTx(tx, types.LatestSignerForChainID(chainID), key)
if err != nil {
return nil, common.Hash{}, err
}
raw, err := signed.MarshalBinary()
if err != nil {
return nil, common.Hash{}, err
}
return raw, signed.Hash(), nil
}
func SignERC20Transfer(ctx context.Context, client *ethclient.Client, key *ecdsa.PrivateKey, token common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) {
erc20ABI, err := abi.JSON(strings.NewReader(`[{"name":"transfer","type":"function","inputs":[{"name":"to","type":"address"},{"name":"amount","type":"uint256"}],"outputs":[{"type":"bool"}]}]`))
if err != nil {
return nil, err
}
data, err := erc20ABI.Pack("transfer", recipient, amount)
if err != nil {
return nil, err
}
from := crypto.PubkeyToAddress(key.PublicKey)
nonce, err := client.PendingNonceAt(ctx, from)
if err != nil {
return nil, err
}
tip, err := client.SuggestGasTipCap(ctx)
if err != nil {
return nil, err
}
feeCap, err := client.SuggestGasPrice(ctx)
if err != nil {
return nil, err
}
tx := types.NewTx(&types.DynamicFeeTx{
ChainID: chainID,
Nonce: nonce,
GasTipCap: tip,
GasFeeCap: new(big.Int).Mul(feeCap, big.NewInt(2)),
Gas: 80_000,
To: &token,
Value: big.NewInt(0),
Data: data,
})
return types.SignTx(tx, types.LatestSignerForChainID(chainID), key)
}
func Broadcast(ctx context.Context, client *ethclient.Client, signed *types.Transaction) error {
return client.SendTransaction(ctx, signed)
}