From 3c032789cd00ff5583c270dcb86d488d83a46963 Mon Sep 17 00:00:00 2001 From: Daniel Lima Date: Thu, 28 Nov 2024 12:24:20 -0300 Subject: [PATCH] Feat: CCTP bridger --- bindings/TokenMessenger/TokenMessenger.go | 5860 +++++++++++++++++++++ cmd/arbitrum/aribtrum.go | 12 - cmd/cctp/cctp.go | 150 + cmd/cctp/ethereum.go | 71 + cmd/cmd.go | 4 +- go.mod | 2 +- go.sum | 2 + 7 files changed, 6087 insertions(+), 14 deletions(-) create mode 100644 bindings/TokenMessenger/TokenMessenger.go create mode 100644 cmd/cctp/cctp.go create mode 100644 cmd/cctp/ethereum.go diff --git a/bindings/TokenMessenger/TokenMessenger.go b/bindings/TokenMessenger/TokenMessenger.go new file mode 100644 index 0000000..39ab656 --- /dev/null +++ b/bindings/TokenMessenger/TokenMessenger.go @@ -0,0 +1,5860 @@ +// This file was generated by seer: https://github.com/G7DAO/seer. +// seer version: 0.3.15 +// seer command: seer evm generate --package TokenMessenger --cli --foundry ../../circlefin/evm-cctp-contracts/out/TokenMessenger.sol/TokenMessenger.json --struct TokenMessenger --output bindings/TokenMessenger/TokenMessenger.go +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package TokenMessenger + +import ( + "bytes" + "crypto/rand" + "errors" + "math/big" + "net/http" + "strings" + + "context" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/signer/core/apitypes" + + // Reference imports to suppress errors if they are not otherwise used. + "encoding/hex" + "encoding/json" + "fmt" + "os" + "time" + + "github.com/G7DAO/seer/bindings/CreateCall" + "github.com/G7DAO/seer/bindings/GnosisSafe" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/spf13/cobra" + "golang.org/x/term" + + // TokenMessengerMetaData contains all meta data concerning the TokenMessenger contract. + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/crypto" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var TokenMessengerMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_messageTransmitter\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_messageBodyVersion\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"acceptOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addLocalMinter\",\"inputs\":[{\"name\":\"newLocalMinter\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"addRemoteTokenMessenger\",\"inputs\":[{\"name\":\"domain\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"tokenMessenger\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"depositForBurn\",\"inputs\":[{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"destinationDomain\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"mintRecipient\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"burnToken\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"_nonce\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"depositForBurnWithCaller\",\"inputs\":[{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"destinationDomain\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"mintRecipient\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"burnToken\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destinationCaller\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"nonce\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"handleReceiveMessage\",\"inputs\":[{\"name\":\"remoteDomain\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"sender\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"messageBody\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"localMessageTransmitter\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIMessageTransmitter\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"localMinter\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractITokenMinter\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"messageBodyVersion\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pendingOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"remoteTokenMessengers\",\"inputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"removeLocalMinter\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"removeRemoteTokenMessenger\",\"inputs\":[{\"name\":\"domain\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"replaceDepositForBurn\",\"inputs\":[{\"name\":\"originalMessage\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"originalAttestation\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"newDestinationCaller\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"newMintRecipient\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"rescueERC20\",\"inputs\":[{\"name\":\"tokenContract\",\"type\":\"address\",\"internalType\":\"contractIERC20\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"rescuer\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateRescuer\",\"inputs\":[{\"name\":\"newRescuer\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"DepositForBurn\",\"inputs\":[{\"name\":\"nonce\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"burnToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"depositor\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"mintRecipient\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"destinationDomain\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"},{\"name\":\"destinationTokenMessenger\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"},{\"name\":\"destinationCaller\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"LocalMinterAdded\",\"inputs\":[{\"name\":\"localMinter\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"LocalMinterRemoved\",\"inputs\":[{\"name\":\"localMinter\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MintAndWithdraw\",\"inputs\":[{\"name\":\"mintRecipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"mintToken\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferStarted\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RemoteTokenMessengerAdded\",\"inputs\":[{\"name\":\"domain\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"},{\"name\":\"tokenMessenger\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RemoteTokenMessengerRemoved\",\"inputs\":[{\"name\":\"domain\",\"type\":\"uint32\",\"indexed\":false,\"internalType\":\"uint32\"},{\"name\":\"tokenMessenger\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RescuerChanged\",\"inputs\":[{\"name\":\"newRescuer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]", + Bin: "0x60c06040523480156200001157600080fd5b506040516200366238038062003662833981810160405260408110156200003757600080fd5b508051602090910151620000546200004e620000d9565b620000dd565b6001600160a01b038216620000b0576040805162461bcd60e51b815260206004820152601a60248201527f4d6573736167655472616e736d6974746572206e6f7420736574000000000000604482015290519081900360640190fd5b60609190911b6001600160601b03191660805260e01b6001600160e01b03191660a05262000157565b3390565b600180546001600160a01b0319169055620001048162000107602090811b6200177c17901c565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60805160601c60a05160e01c6134b9620001a960003980610819528061114e528061133f5280611fda5250806108455280610c4c52806121fc5280612252528061293f5280612a1652506134b96000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c806391f17888116100cd578063da87e44811610081578063f2fde38b11610066578063f2fde38b146104a7578063f79fd08e146104da578063f856ddb6146104fd57610151565b8063da87e44814610476578063e30c39781461049f57610151565b80639cdbb181116100b25780639cdbb1811461040a578063b2118a8d1461042b578063cb75c11c1461046e57610151565b806391f178881461036c57806396abeb701461037457610151565b80636fd3504e116101245780638197beb9116101095780638197beb9146102fc57806382a5e6651461032f5780638da5cb5b1461036457610151565b80636fd3504e1461028c57806379ba5097146102f457610151565b806329a78e33146101565780632ab60045146102205780632c1219211461025357806338a6318314610284575b600080fd5b61021e6004803603608081101561016c57600080fd5b81019060208101813564010000000081111561018757600080fd5b82018360208201111561019957600080fd5b803590602001918460018302840111640100000000831117156101bb57600080fd5b9193909290916020810190356401000000008111156101d957600080fd5b8201836020820111156101eb57600080fd5b8035906020019184600183028401116401000000008311171561020d57600080fd5b91935091508035906020013561054e565b005b61021e6004803603602081101561023657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610b67565b61025b610c4a565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b61025b610c6e565b6102d7600480360360808110156102a257600080fd5b50803590602081013563ffffffff16906040810135906060013573ffffffffffffffffffffffffffffffffffffffff16610c8a565b6040805167ffffffffffffffff9092168252519081900360200190f35b61021e610ca4565b61021e6004803603602081101561031257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610d47565b6103526004803603602081101561034557600080fd5b503563ffffffff16610ecf565b60408051918252519081900360200190f35b61025b610ee1565b61021e610efd565b6103f66004803603606081101561038a57600080fd5b63ffffffff823516916020810135918101906060810160408201356401000000008111156103b757600080fd5b8201836020820111156103c957600080fd5b803590602001918460018302840111640100000000831117156103eb57600080fd5b509092509050610ffe565b604080519115158252519081900360200190f35b61041261133d565b6040805163ffffffff9092168252519081900360200190f35b61021e6004803603606081101561044157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135611361565b61025b6113f7565b61021e6004803603604081101561048c57600080fd5b5063ffffffff8135169060200135611413565b61025b61155f565b61021e600480360360208110156104bd57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661157b565b61021e600480360360208110156104f057600080fd5b503563ffffffff16611613565b6102d7600480360360a081101561051357600080fd5b5080359063ffffffff6020820135169060408101359073ffffffffffffffffffffffffffffffffffffffff60608201351690608001356116f7565b6000610594600088888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506117f19050565b90506105c17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008216611817565b60006105ee7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316611955565b905061061b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000082166119cc565b60006106487fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316611b09565b905073__$8c977731748aa4504deed57239565df533$__635ced058e826040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561069957600080fd5b505af41580156106ad573d6000803e3d6000fd5b505050506040513d60208110156106c357600080fd5b505173ffffffffffffffffffffffffffffffffffffffff16331461074857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f496e76616c69642073656e64657220666f72206d657373616765000000000000604482015290519081900360640190fd5b836107b457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4d696e7420726563697069656e74206d757374206265206e6f6e7a65726f0000604482015290519081900360640190fd5b60006107e17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008416611b3a565b905060006108107fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008516611b6b565b905060006108417f000000000000000000000000000000000000000000000000000000000000000084898588611b9c565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b857b7748d8d8d8d868e6040518763ffffffff1660e01b81526004018080602001806020018060200185815260200184810384528a8a82818152602001925080828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101858103845288815260200190508888808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018681038452885181528851602091820193918a019250908190849084905b8381101561096757818101518382015260200161094f565b50505050905090810190601f1680156109945780820380516001836020036101000a031916815260200191505b509950505050505050505050600060405180830381600087803b1580156109ba57600080fd5b505af11580156109ce573d6000803e3d6000fd5b505050503373ffffffffffffffffffffffffffffffffffffffff1673__$8c977731748aa4504deed57239565df533$__635ced058e856040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610a3857600080fd5b505af4158015610a4c573d6000803e3d6000fd5b505050506040513d6020811015610a6257600080fd5b505173ffffffffffffffffffffffffffffffffffffffff16610aa57fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008916611bff565b67ffffffffffffffff167f2fa9ca894982930190727e75500a97d8dc500233a5065e0f3126c48fbe0343c0858b610afd7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008d16611c30565b610b287fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008e16611c61565b60408051948552602085019390935263ffffffff909116838301526060830152608082018e9052519081900360a00190a4505050505050505050505050565b610b6f611c92565b73ffffffffffffffffffffffffffffffffffffffff8116610bdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613335602a913960400191505060405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517fe475e580d85111348e40d8ca33cfdd74c30fe1655c2d8537a13abc10065ffa5a90600090a250565b7f000000000000000000000000000000000000000000000000000000000000000081565b60025473ffffffffffffffffffffffffffffffffffffffff1690565b6000610c998585858585611d3c565b90505b949350505050565b6000610cae6121c3565b90508073ffffffffffffffffffffffffffffffffffffffff16610ccf61155f565b73ffffffffffffffffffffffffffffffffffffffff1614610d3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602981526020018061330c6029913960400191505060405180910390fd5b610d44816121c7565b50565b610d4f611c92565b73ffffffffffffffffffffffffffffffffffffffff8116610dd157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f5a65726f2061646472657373206e6f7420616c6c6f7765640000000000000000604482015290519081900360640190fd5b60035473ffffffffffffffffffffffffffffffffffffffff1615610e5657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4c6f63616c206d696e74657220697320616c7265616479207365742e00000000604482015290519081900360640190fd5b6003805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116811790915560408051918252517f109bb3e70cbf1931e295b49e75c67013b85ff80d64e6f1d321f37157b90c38309181900360200190a150565b60046020526000908152604090205481565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b610f05611c92565b60035473ffffffffffffffffffffffffffffffffffffffff1680610f8a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4e6f206c6f63616c206d696e746572206973207365742e000000000000000000604482015290519081900360640190fd5b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040805173ffffffffffffffffffffffffffffffffffffffff8316815290517f2db49fbf671271826a27b02ebc496209c85fffffb4bccc67430d2a0f22b4d1ac9181900360200190a150565b60006110086121f8565b61107357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f496e76616c6964206d657373616765207472616e736d69747465720000000000604482015290519081900360640190fd5b848461107f8282612279565b6110d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061335f6021913960400191505060405180910390fd5b600061111a600087878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506117f19050565b90506111477fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000082166119cc565b63ffffffff7f0000000000000000000000000000000000000000000000000000000000000000166111997fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000083166122a5565b63ffffffff161461120b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f496e76616c6964206d65737361676520626f64792076657273696f6e00000000604482015290519081900360640190fd5b60006112387fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000083166122d5565b905060006112677fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008416611b3a565b905060006112967fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008516611b6b565b905060006112a2612306565b905061132b818d8573__$8c977731748aa4504deed57239565df533$__635ced058e896040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156112f957600080fd5b505af415801561130d573d6000803e3d6000fd5b505050506040513d602081101561132357600080fd5b5051866123aa565b5060019b9a5050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60025473ffffffffffffffffffffffffffffffffffffffff1633146113d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806133c76024913960400191505060405180910390fd5b6113f273ffffffffffffffffffffffffffffffffffffffff841683836124c3565b505050565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b61141b611c92565b8061148757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f62797465733332283029206e6f7420616c6c6f77656400000000000000000000604482015290519081900360640190fd5b63ffffffff82166000908152600460205260409020541561150957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f546f6b656e4d657373656e67657220616c726561647920736574000000000000604482015290519081900360640190fd5b63ffffffff82166000818152600460209081526040918290208490558151928352820183905280517f4bba2b08298cf59661b4895e384cc2ac3962ce2d71f1b7c11bca52e1169f95999281900390910190a15050565b60015473ffffffffffffffffffffffffffffffffffffffff1690565b611583611c92565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556115ce610ee1565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b61161b611c92565b63ffffffff811660009081526004602052604090205461169c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4e6f20546f6b656e4d657373656e676572207365740000000000000000000000604482015290519081900360640190fd5b63ffffffff8116600081815260046020908152604080832080549390558051938452908301829052805191927f3dcea012093dbca2bb8ed7fd2b2ff90305ab70bddda8bbb94d4152735a98f0b1929081900390910190a15050565b60008161176557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f496e76616c69642064657374696e6174696f6e2063616c6c6572000000000000604482015290519081900360640190fd5b6117728686868686611d3c565b9695505050505050565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b81516000906020840161180c64ffffffffff85168284612550565b925050505b92915050565b6118427fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000082166125af565b6118ad57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4d616c666f726d6564206d657373616765000000000000000000000000000000604482015290519081900360640190fd5b60746118da7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000083166125ec565b6bffffffffffffffffffffffff161015610d4457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f496e76616c6964206d6573736167653a20746f6f2073686f7274000000000000604482015290519081900360640190fd5b60006119c46074806119887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000086166125ec565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000861692916bffffffffffffffffffffffff9103166000612600565b90505b919050565b6119f77fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000082166125af565b611a6257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4d616c666f726d6564206d657373616765000000000000000000000000000000604482015290519081900360640190fd5b6084611a8f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000083166125ec565b6bffffffffffffffffffffffff1614610d4457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c6964206d657373616765206c656e67746800000000000000000000604482015290519081900360640190fd5b60006119c47fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000831660646020612686565b60006119c47fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000831660046020612686565b60006119c47fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000831660446020612831565b6040805160e09690961b7fffffffff000000000000000000000000000000000000000000000000000000001660208701526024860194909452604485019290925260648401526084808401919091528151808403909101815260a4909201905290565b60006119c47fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316600c6008612831565b60006119c47fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000831660086004612831565b60006119c47fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000831660346020612686565b611c9a6121c3565b73ffffffffffffffffffffffffffffffffffffffff16611cb8610ee1565b73ffffffffffffffffffffffffffffffffffffffff1614611d3a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b565b6000808611611dac57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f416d6f756e74206d757374206265206e6f6e7a65726f00000000000000000000604482015290519081900360640190fd5b83611e1857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f4d696e7420726563697069656e74206d757374206265206e6f6e7a65726f0000604482015290519081900360640190fd5b6000611e2386612852565b90506000611e2f612306565b604080517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff8084166024830152604482018c905291519293508792918316916323b872dd916064808201926020929091908290030181600087803b158015611eb357600080fd5b505af1158015611ec7573d6000803e3d6000fd5b505050506040513d6020811015611edd57600080fd5b5051611f4a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5472616e73666572206f7065726174696f6e206661696c656400000000000000604482015290519081900360640190fd5b8173ffffffffffffffffffffffffffffffffffffffff16639dc29fac878b6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015611fbb57600080fd5b505af1158015611fcf573d6000803e3d6000fd5b5050505060006121297f000000000000000000000000000000000000000000000000000000000000000073__$8c977731748aa4504deed57239565df533$__6382c947b78a6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561205e57600080fd5b505af4158015612072573d6000803e3d6000fd5b505050506040513d602081101561208857600080fd5b5051604080517f82c947b700000000000000000000000000000000000000000000000000000000815233600482015290518c918f9173__$8c977731748aa4504deed57239565df533$__916382c947b7916024808301926020929190829003018186803b1580156120f857600080fd5b505af415801561210c573d6000803e3d6000fd5b505050506040513d602081101561212257600080fd5b5051611b9c565b905060006121398a8689856128d4565b604080518d8152602081018c905263ffffffff8d168183015260608101889052608081018a90529051919250339173ffffffffffffffffffffffffffffffffffffffff8b169167ffffffffffffffff8516917f2fa9ca894982930190727e75500a97d8dc500233a5065e0f3126c48fbe0343c09181900360a00190a49a9950505050505050505050565b3390565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055610d448161177c565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161580159061227457503373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016145b905090565b6000811580159061229e575063ffffffff831660009081526004602052604090205482145b9392505050565b60006119c47fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000008316826004612831565b60006119c47fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000831660246020612686565b60035460009073ffffffffffffffffffffffffffffffffffffffff1661238d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4c6f63616c206d696e746572206973206e6f7420736574000000000000000000604482015290519081900360640190fd5b5060035473ffffffffffffffffffffffffffffffffffffffff1690565b604080517fd54de06f00000000000000000000000000000000000000000000000000000000815263ffffffff861660048201526024810185905273ffffffffffffffffffffffffffffffffffffffff848116604483015260648201849052915187926000929084169163d54de06f9160848082019260209290919082900301818787803b15801561243a57600080fd5b505af115801561244e573d6000803e3d6000fd5b505050506040513d602081101561246457600080fd5b505160408051858152905191925073ffffffffffffffffffffffffffffffffffffffff80841692908716917f1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6919081900360200190a350505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526113f2908490612b07565b60008061255d8484612bdf565b905060405181111561256d575060005b8061259b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000091505061229e565b6125a6858585612c51565b95945050505050565b60006125ba82612c64565b64ffffffffff1664ffffffffff14156125d5575060006119c7565b60006125e083612c6a565b60405110199392505050565b60181c6bffffffffffffffffffffffff1690565b60008061260c86612c94565b6bffffffffffffffffffffffff16905061262586612c6a565b612639856126338489612bdf565b90612bdf565b1115612668577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000915050610c9c565b6126728186612bdf565b90506117728364ffffffffff168286612550565b600060ff82166126985750600061229e565b6126a1846125ec565b6bffffffffffffffffffffffff166126bc8460ff8516612bdf565b111561279b576126fd6126ce85612c94565b6bffffffffffffffffffffffff166126e5866125ec565b6bffffffffffffffffffffffff16858560ff16612ca8565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612760578181015183820152602001612748565b50505050905090810190601f16801561278d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60208260ff1611156127f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a8152602001806133eb603a913960400191505060405180910390fd5b60088202600061280786612c94565b6bffffffffffffffffffffffff169050600061282283612e03565b91909501511695945050505050565b60008160200360080260ff16612848858585612686565b901c949350505050565b63ffffffff8116600090815260046020526040812054806119c457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4e6f20546f6b656e4d657373656e67657220666f7220646f6d61696e00000000604482015290519081900360640190fd5b600082612a14576040517f0ba469bc00000000000000000000000000000000000000000000000000000000815263ffffffff8616600482019081526024820186905260606044830190815284516064840152845173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001693630ba469bc938a938a93899360840190602085019080838360005b8381101561299357818101518382015260200161297b565b50505050905090810190601f1680156129c05780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156129e157600080fd5b505af11580156129f5573d6000803e3d6000fd5b505050506040513d6020811015612a0b57600080fd5b50519050610c9c565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f7259a75868686866040518563ffffffff1660e01b8152600401808563ffffffff16815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612ab8578181015183820152602001612aa0565b50505050905090810190601f168015612ae55780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b1580156129e157600080fd5b6000612b69826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612e4c9092919063ffffffff16565b8051909150156113f257808060200190516020811015612b8857600080fd5b50516113f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613425602a913960400191505060405180910390fd5b8181018281101561181157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4f766572666c6f7720647572696e67206164646974696f6e2e00000000000000604482015290519081900360640190fd5b606092831b9190911790911b1760181b90565b60d81c90565b6000612c75826125ec565b612c7e83612c94565b016bffffffffffffffffffffffff169050919050565b60781c6bffffffffffffffffffffffff1690565b60606000612cb586612e5b565b9150506000612cc386612e5b565b9150506000612cd186612e5b565b9150506000612cdf86612e5b565b91505083838383604051602001808061344f603591397fffffffffffff000000000000000000000000000000000000000000000000000060d087811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b84015286901b16604a82015260500160216133a682397fffffffffffff000000000000000000000000000000000000000000000000000060d094851b811660218301527f2077697468206c656e677468203078000000000000000000000000000000000060278301529290931b9091166036830152507f2e00000000000000000000000000000000000000000000000000000000000000603c82015260408051601d818403018152603d90920190529b9a5050505050505050505050565b7f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9091011d90565b6060610c9c8484600085612f2f565b600080601f5b600f8160ff161115612ec35760ff600882021684901c612e80816130e9565b61ffff16841793508160ff16601014612e9b57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612e61565b50600f5b60ff8160ff161015612f295760ff600882021684901c612ee6816130e9565b61ffff16831792508160ff16600014612f0157601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612ec7565b50915091565b606082471015612f8a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806133806026913960400191505060405180910390fd5b612f9385613119565b612ffe57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b6020831061306757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161302a565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146130c9576040519150601f19603f3d011682016040523d82523d6000602084013e6130ce565b606091505b50915091506130de82828661311f565b979650505050505050565b60006130fb60048360ff16901c61319f565b60ff161760081b62ffff00166131108261319f565b60ff1617919050565b3b151590565b6060831561312e57508161229e565b82511561313e5782518084602001fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201818152845160248401528451859391928392604401919085019080838360008315612760578181015183820152602001612748565b600060f08083179060ff821614156131bb5760309150506119c7565b8060ff1660f114156131d15760319150506119c7565b8060ff1660f214156131e75760329150506119c7565b8060ff1660f314156131fd5760339150506119c7565b8060ff1660f414156132135760349150506119c7565b8060ff1660f514156132295760359150506119c7565b8060ff1660f6141561323f5760369150506119c7565b8060ff1660f714156132555760379150506119c7565b8060ff1660f8141561326b5760389150506119c7565b8060ff1660f914156132815760399150506119c7565b8060ff1660fa14156132975760619150506119c7565b8060ff1660fb14156132ad5760629150506119c7565b8060ff1660fc14156132c35760639150506119c7565b8060ff1660fd14156132d95760649150506119c7565b8060ff1660fe14156132ef5760659150506119c7565b8060ff1660ff14156133055760669150506119c7565b5091905056fe4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206e6577206f776e6572526573637561626c653a206e6577207265736375657220697320746865207a65726f206164647265737352656d6f746520546f6b656e4d657373656e67657220756e737570706f72746564416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c2e20417474656d7074656420746f20696e646578206174206f6666736574203078526573637561626c653a2063616c6c6572206973206e6f7420746865207265736375657254797065644d656d566965772f696e646578202d20417474656d7074656420746f20696e646578206d6f7265207468616e2033322062797465735361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656454797065644d656d566965772f696e646578202d204f76657272616e2074686520766965772e20536c696365206973206174203078a26469706673582212206b689f34f4e15f499706461beeb293d1cec2381023fbd21a46dcbc1856ad238864736f6c63430007060033", +} + +// TokenMessengerABI is the input ABI used to generate the binding from. +// Deprecated: Use TokenMessengerMetaData.ABI instead. +var TokenMessengerABI = TokenMessengerMetaData.ABI + +// TokenMessengerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TokenMessengerMetaData.Bin instead. +var TokenMessengerBin = TokenMessengerMetaData.Bin + +// DeployTokenMessenger deploys a new Ethereum contract, binding an instance of TokenMessenger to it. +func DeployTokenMessenger(auth *bind.TransactOpts, backend bind.ContractBackend, _messageTransmitter common.Address, _messageBodyVersion uint32) (common.Address, *types.Transaction, *TokenMessenger, error) { + parsed, err := TokenMessengerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TokenMessengerBin), backend, _messageTransmitter, _messageBodyVersion) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &TokenMessenger{TokenMessengerCaller: TokenMessengerCaller{contract: contract}, TokenMessengerTransactor: TokenMessengerTransactor{contract: contract}, TokenMessengerFilterer: TokenMessengerFilterer{contract: contract}}, nil +} + +// TokenMessenger is an auto generated Go binding around an Ethereum contract. +type TokenMessenger struct { + TokenMessengerCaller // Read-only binding to the contract + TokenMessengerTransactor // Write-only binding to the contract + TokenMessengerFilterer // Log filterer for contract events +} + +// TokenMessengerCaller is an auto generated read-only Go binding around an Ethereum contract. +type TokenMessengerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TokenMessengerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TokenMessengerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TokenMessengerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TokenMessengerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TokenMessengerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TokenMessengerSession struct { + Contract *TokenMessenger // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TokenMessengerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TokenMessengerCallerSession struct { + Contract *TokenMessengerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TokenMessengerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TokenMessengerTransactorSession struct { + Contract *TokenMessengerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TokenMessengerRaw is an auto generated low-level Go binding around an Ethereum contract. +type TokenMessengerRaw struct { + Contract *TokenMessenger // Generic contract binding to access the raw methods on +} + +// TokenMessengerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TokenMessengerCallerRaw struct { + Contract *TokenMessengerCaller // Generic read-only contract binding to access the raw methods on +} + +// TokenMessengerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TokenMessengerTransactorRaw struct { + Contract *TokenMessengerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewTokenMessenger creates a new instance of TokenMessenger, bound to a specific deployed contract. +func NewTokenMessenger(address common.Address, backend bind.ContractBackend) (*TokenMessenger, error) { + contract, err := bindTokenMessenger(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TokenMessenger{TokenMessengerCaller: TokenMessengerCaller{contract: contract}, TokenMessengerTransactor: TokenMessengerTransactor{contract: contract}, TokenMessengerFilterer: TokenMessengerFilterer{contract: contract}}, nil +} + +// NewTokenMessengerCaller creates a new read-only instance of TokenMessenger, bound to a specific deployed contract. +func NewTokenMessengerCaller(address common.Address, caller bind.ContractCaller) (*TokenMessengerCaller, error) { + contract, err := bindTokenMessenger(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TokenMessengerCaller{contract: contract}, nil +} + +// NewTokenMessengerTransactor creates a new write-only instance of TokenMessenger, bound to a specific deployed contract. +func NewTokenMessengerTransactor(address common.Address, transactor bind.ContractTransactor) (*TokenMessengerTransactor, error) { + contract, err := bindTokenMessenger(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TokenMessengerTransactor{contract: contract}, nil +} + +// NewTokenMessengerFilterer creates a new log filterer instance of TokenMessenger, bound to a specific deployed contract. +func NewTokenMessengerFilterer(address common.Address, filterer bind.ContractFilterer) (*TokenMessengerFilterer, error) { + contract, err := bindTokenMessenger(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TokenMessengerFilterer{contract: contract}, nil +} + +// bindTokenMessenger binds a generic wrapper to an already deployed contract. +func bindTokenMessenger(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TokenMessengerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TokenMessenger *TokenMessengerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TokenMessenger.Contract.TokenMessengerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TokenMessenger *TokenMessengerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenMessenger.Contract.TokenMessengerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TokenMessenger *TokenMessengerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TokenMessenger.Contract.TokenMessengerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TokenMessenger *TokenMessengerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TokenMessenger.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TokenMessenger *TokenMessengerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenMessenger.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TokenMessenger *TokenMessengerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TokenMessenger.Contract.contract.Transact(opts, method, params...) +} + +// LocalMessageTransmitter is a free data retrieval call binding the contract method 0x2c121921. +// +// Solidity: function localMessageTransmitter() view returns(address) +func (_TokenMessenger *TokenMessengerCaller) LocalMessageTransmitter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenMessenger.contract.Call(opts, &out, "localMessageTransmitter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// LocalMessageTransmitter is a free data retrieval call binding the contract method 0x2c121921. +// +// Solidity: function localMessageTransmitter() view returns(address) +func (_TokenMessenger *TokenMessengerSession) LocalMessageTransmitter() (common.Address, error) { + return _TokenMessenger.Contract.LocalMessageTransmitter(&_TokenMessenger.CallOpts) +} + +// LocalMessageTransmitter is a free data retrieval call binding the contract method 0x2c121921. +// +// Solidity: function localMessageTransmitter() view returns(address) +func (_TokenMessenger *TokenMessengerCallerSession) LocalMessageTransmitter() (common.Address, error) { + return _TokenMessenger.Contract.LocalMessageTransmitter(&_TokenMessenger.CallOpts) +} + +// LocalMinter is a free data retrieval call binding the contract method 0xcb75c11c. +// +// Solidity: function localMinter() view returns(address) +func (_TokenMessenger *TokenMessengerCaller) LocalMinter(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenMessenger.contract.Call(opts, &out, "localMinter") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// LocalMinter is a free data retrieval call binding the contract method 0xcb75c11c. +// +// Solidity: function localMinter() view returns(address) +func (_TokenMessenger *TokenMessengerSession) LocalMinter() (common.Address, error) { + return _TokenMessenger.Contract.LocalMinter(&_TokenMessenger.CallOpts) +} + +// LocalMinter is a free data retrieval call binding the contract method 0xcb75c11c. +// +// Solidity: function localMinter() view returns(address) +func (_TokenMessenger *TokenMessengerCallerSession) LocalMinter() (common.Address, error) { + return _TokenMessenger.Contract.LocalMinter(&_TokenMessenger.CallOpts) +} + +// MessageBodyVersion is a free data retrieval call binding the contract method 0x9cdbb181. +// +// Solidity: function messageBodyVersion() view returns(uint32) +func (_TokenMessenger *TokenMessengerCaller) MessageBodyVersion(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _TokenMessenger.contract.Call(opts, &out, "messageBodyVersion") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// MessageBodyVersion is a free data retrieval call binding the contract method 0x9cdbb181. +// +// Solidity: function messageBodyVersion() view returns(uint32) +func (_TokenMessenger *TokenMessengerSession) MessageBodyVersion() (uint32, error) { + return _TokenMessenger.Contract.MessageBodyVersion(&_TokenMessenger.CallOpts) +} + +// MessageBodyVersion is a free data retrieval call binding the contract method 0x9cdbb181. +// +// Solidity: function messageBodyVersion() view returns(uint32) +func (_TokenMessenger *TokenMessengerCallerSession) MessageBodyVersion() (uint32, error) { + return _TokenMessenger.Contract.MessageBodyVersion(&_TokenMessenger.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TokenMessenger *TokenMessengerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenMessenger.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TokenMessenger *TokenMessengerSession) Owner() (common.Address, error) { + return _TokenMessenger.Contract.Owner(&_TokenMessenger.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_TokenMessenger *TokenMessengerCallerSession) Owner() (common.Address, error) { + return _TokenMessenger.Contract.Owner(&_TokenMessenger.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_TokenMessenger *TokenMessengerCaller) PendingOwner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenMessenger.contract.Call(opts, &out, "pendingOwner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_TokenMessenger *TokenMessengerSession) PendingOwner() (common.Address, error) { + return _TokenMessenger.Contract.PendingOwner(&_TokenMessenger.CallOpts) +} + +// PendingOwner is a free data retrieval call binding the contract method 0xe30c3978. +// +// Solidity: function pendingOwner() view returns(address) +func (_TokenMessenger *TokenMessengerCallerSession) PendingOwner() (common.Address, error) { + return _TokenMessenger.Contract.PendingOwner(&_TokenMessenger.CallOpts) +} + +// RemoteTokenMessengers is a free data retrieval call binding the contract method 0x82a5e665. +// +// Solidity: function remoteTokenMessengers(uint32 ) view returns(bytes32) +func (_TokenMessenger *TokenMessengerCaller) RemoteTokenMessengers(opts *bind.CallOpts, arg0 uint32) ([32]byte, error) { + var out []interface{} + err := _TokenMessenger.contract.Call(opts, &out, "remoteTokenMessengers", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// RemoteTokenMessengers is a free data retrieval call binding the contract method 0x82a5e665. +// +// Solidity: function remoteTokenMessengers(uint32 ) view returns(bytes32) +func (_TokenMessenger *TokenMessengerSession) RemoteTokenMessengers(arg0 uint32) ([32]byte, error) { + return _TokenMessenger.Contract.RemoteTokenMessengers(&_TokenMessenger.CallOpts, arg0) +} + +// RemoteTokenMessengers is a free data retrieval call binding the contract method 0x82a5e665. +// +// Solidity: function remoteTokenMessengers(uint32 ) view returns(bytes32) +func (_TokenMessenger *TokenMessengerCallerSession) RemoteTokenMessengers(arg0 uint32) ([32]byte, error) { + return _TokenMessenger.Contract.RemoteTokenMessengers(&_TokenMessenger.CallOpts, arg0) +} + +// Rescuer is a free data retrieval call binding the contract method 0x38a63183. +// +// Solidity: function rescuer() view returns(address) +func (_TokenMessenger *TokenMessengerCaller) Rescuer(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _TokenMessenger.contract.Call(opts, &out, "rescuer") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Rescuer is a free data retrieval call binding the contract method 0x38a63183. +// +// Solidity: function rescuer() view returns(address) +func (_TokenMessenger *TokenMessengerSession) Rescuer() (common.Address, error) { + return _TokenMessenger.Contract.Rescuer(&_TokenMessenger.CallOpts) +} + +// Rescuer is a free data retrieval call binding the contract method 0x38a63183. +// +// Solidity: function rescuer() view returns(address) +func (_TokenMessenger *TokenMessengerCallerSession) Rescuer() (common.Address, error) { + return _TokenMessenger.Contract.Rescuer(&_TokenMessenger.CallOpts) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_TokenMessenger *TokenMessengerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenMessenger.contract.Transact(opts, "acceptOwnership") +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_TokenMessenger *TokenMessengerSession) AcceptOwnership() (*types.Transaction, error) { + return _TokenMessenger.Contract.AcceptOwnership(&_TokenMessenger.TransactOpts) +} + +// AcceptOwnership is a paid mutator transaction binding the contract method 0x79ba5097. +// +// Solidity: function acceptOwnership() returns() +func (_TokenMessenger *TokenMessengerTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _TokenMessenger.Contract.AcceptOwnership(&_TokenMessenger.TransactOpts) +} + +// AddLocalMinter is a paid mutator transaction binding the contract method 0x8197beb9. +// +// Solidity: function addLocalMinter(address newLocalMinter) returns() +func (_TokenMessenger *TokenMessengerTransactor) AddLocalMinter(opts *bind.TransactOpts, newLocalMinter common.Address) (*types.Transaction, error) { + return _TokenMessenger.contract.Transact(opts, "addLocalMinter", newLocalMinter) +} + +// AddLocalMinter is a paid mutator transaction binding the contract method 0x8197beb9. +// +// Solidity: function addLocalMinter(address newLocalMinter) returns() +func (_TokenMessenger *TokenMessengerSession) AddLocalMinter(newLocalMinter common.Address) (*types.Transaction, error) { + return _TokenMessenger.Contract.AddLocalMinter(&_TokenMessenger.TransactOpts, newLocalMinter) +} + +// AddLocalMinter is a paid mutator transaction binding the contract method 0x8197beb9. +// +// Solidity: function addLocalMinter(address newLocalMinter) returns() +func (_TokenMessenger *TokenMessengerTransactorSession) AddLocalMinter(newLocalMinter common.Address) (*types.Transaction, error) { + return _TokenMessenger.Contract.AddLocalMinter(&_TokenMessenger.TransactOpts, newLocalMinter) +} + +// AddRemoteTokenMessenger is a paid mutator transaction binding the contract method 0xda87e448. +// +// Solidity: function addRemoteTokenMessenger(uint32 domain, bytes32 tokenMessenger) returns() +func (_TokenMessenger *TokenMessengerTransactor) AddRemoteTokenMessenger(opts *bind.TransactOpts, domain uint32, tokenMessenger [32]byte) (*types.Transaction, error) { + return _TokenMessenger.contract.Transact(opts, "addRemoteTokenMessenger", domain, tokenMessenger) +} + +// AddRemoteTokenMessenger is a paid mutator transaction binding the contract method 0xda87e448. +// +// Solidity: function addRemoteTokenMessenger(uint32 domain, bytes32 tokenMessenger) returns() +func (_TokenMessenger *TokenMessengerSession) AddRemoteTokenMessenger(domain uint32, tokenMessenger [32]byte) (*types.Transaction, error) { + return _TokenMessenger.Contract.AddRemoteTokenMessenger(&_TokenMessenger.TransactOpts, domain, tokenMessenger) +} + +// AddRemoteTokenMessenger is a paid mutator transaction binding the contract method 0xda87e448. +// +// Solidity: function addRemoteTokenMessenger(uint32 domain, bytes32 tokenMessenger) returns() +func (_TokenMessenger *TokenMessengerTransactorSession) AddRemoteTokenMessenger(domain uint32, tokenMessenger [32]byte) (*types.Transaction, error) { + return _TokenMessenger.Contract.AddRemoteTokenMessenger(&_TokenMessenger.TransactOpts, domain, tokenMessenger) +} + +// DepositForBurn is a paid mutator transaction binding the contract method 0x6fd3504e. +// +// Solidity: function depositForBurn(uint256 amount, uint32 destinationDomain, bytes32 mintRecipient, address burnToken) returns(uint64 _nonce) +func (_TokenMessenger *TokenMessengerTransactor) DepositForBurn(opts *bind.TransactOpts, amount *big.Int, destinationDomain uint32, mintRecipient [32]byte, burnToken common.Address) (*types.Transaction, error) { + return _TokenMessenger.contract.Transact(opts, "depositForBurn", amount, destinationDomain, mintRecipient, burnToken) +} + +// DepositForBurn is a paid mutator transaction binding the contract method 0x6fd3504e. +// +// Solidity: function depositForBurn(uint256 amount, uint32 destinationDomain, bytes32 mintRecipient, address burnToken) returns(uint64 _nonce) +func (_TokenMessenger *TokenMessengerSession) DepositForBurn(amount *big.Int, destinationDomain uint32, mintRecipient [32]byte, burnToken common.Address) (*types.Transaction, error) { + return _TokenMessenger.Contract.DepositForBurn(&_TokenMessenger.TransactOpts, amount, destinationDomain, mintRecipient, burnToken) +} + +// DepositForBurn is a paid mutator transaction binding the contract method 0x6fd3504e. +// +// Solidity: function depositForBurn(uint256 amount, uint32 destinationDomain, bytes32 mintRecipient, address burnToken) returns(uint64 _nonce) +func (_TokenMessenger *TokenMessengerTransactorSession) DepositForBurn(amount *big.Int, destinationDomain uint32, mintRecipient [32]byte, burnToken common.Address) (*types.Transaction, error) { + return _TokenMessenger.Contract.DepositForBurn(&_TokenMessenger.TransactOpts, amount, destinationDomain, mintRecipient, burnToken) +} + +// DepositForBurnWithCaller is a paid mutator transaction binding the contract method 0xf856ddb6. +// +// Solidity: function depositForBurnWithCaller(uint256 amount, uint32 destinationDomain, bytes32 mintRecipient, address burnToken, bytes32 destinationCaller) returns(uint64 nonce) +func (_TokenMessenger *TokenMessengerTransactor) DepositForBurnWithCaller(opts *bind.TransactOpts, amount *big.Int, destinationDomain uint32, mintRecipient [32]byte, burnToken common.Address, destinationCaller [32]byte) (*types.Transaction, error) { + return _TokenMessenger.contract.Transact(opts, "depositForBurnWithCaller", amount, destinationDomain, mintRecipient, burnToken, destinationCaller) +} + +// DepositForBurnWithCaller is a paid mutator transaction binding the contract method 0xf856ddb6. +// +// Solidity: function depositForBurnWithCaller(uint256 amount, uint32 destinationDomain, bytes32 mintRecipient, address burnToken, bytes32 destinationCaller) returns(uint64 nonce) +func (_TokenMessenger *TokenMessengerSession) DepositForBurnWithCaller(amount *big.Int, destinationDomain uint32, mintRecipient [32]byte, burnToken common.Address, destinationCaller [32]byte) (*types.Transaction, error) { + return _TokenMessenger.Contract.DepositForBurnWithCaller(&_TokenMessenger.TransactOpts, amount, destinationDomain, mintRecipient, burnToken, destinationCaller) +} + +// DepositForBurnWithCaller is a paid mutator transaction binding the contract method 0xf856ddb6. +// +// Solidity: function depositForBurnWithCaller(uint256 amount, uint32 destinationDomain, bytes32 mintRecipient, address burnToken, bytes32 destinationCaller) returns(uint64 nonce) +func (_TokenMessenger *TokenMessengerTransactorSession) DepositForBurnWithCaller(amount *big.Int, destinationDomain uint32, mintRecipient [32]byte, burnToken common.Address, destinationCaller [32]byte) (*types.Transaction, error) { + return _TokenMessenger.Contract.DepositForBurnWithCaller(&_TokenMessenger.TransactOpts, amount, destinationDomain, mintRecipient, burnToken, destinationCaller) +} + +// HandleReceiveMessage is a paid mutator transaction binding the contract method 0x96abeb70. +// +// Solidity: function handleReceiveMessage(uint32 remoteDomain, bytes32 sender, bytes messageBody) returns(bool) +func (_TokenMessenger *TokenMessengerTransactor) HandleReceiveMessage(opts *bind.TransactOpts, remoteDomain uint32, sender [32]byte, messageBody []byte) (*types.Transaction, error) { + return _TokenMessenger.contract.Transact(opts, "handleReceiveMessage", remoteDomain, sender, messageBody) +} + +// HandleReceiveMessage is a paid mutator transaction binding the contract method 0x96abeb70. +// +// Solidity: function handleReceiveMessage(uint32 remoteDomain, bytes32 sender, bytes messageBody) returns(bool) +func (_TokenMessenger *TokenMessengerSession) HandleReceiveMessage(remoteDomain uint32, sender [32]byte, messageBody []byte) (*types.Transaction, error) { + return _TokenMessenger.Contract.HandleReceiveMessage(&_TokenMessenger.TransactOpts, remoteDomain, sender, messageBody) +} + +// HandleReceiveMessage is a paid mutator transaction binding the contract method 0x96abeb70. +// +// Solidity: function handleReceiveMessage(uint32 remoteDomain, bytes32 sender, bytes messageBody) returns(bool) +func (_TokenMessenger *TokenMessengerTransactorSession) HandleReceiveMessage(remoteDomain uint32, sender [32]byte, messageBody []byte) (*types.Transaction, error) { + return _TokenMessenger.Contract.HandleReceiveMessage(&_TokenMessenger.TransactOpts, remoteDomain, sender, messageBody) +} + +// RemoveLocalMinter is a paid mutator transaction binding the contract method 0x91f17888. +// +// Solidity: function removeLocalMinter() returns() +func (_TokenMessenger *TokenMessengerTransactor) RemoveLocalMinter(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TokenMessenger.contract.Transact(opts, "removeLocalMinter") +} + +// RemoveLocalMinter is a paid mutator transaction binding the contract method 0x91f17888. +// +// Solidity: function removeLocalMinter() returns() +func (_TokenMessenger *TokenMessengerSession) RemoveLocalMinter() (*types.Transaction, error) { + return _TokenMessenger.Contract.RemoveLocalMinter(&_TokenMessenger.TransactOpts) +} + +// RemoveLocalMinter is a paid mutator transaction binding the contract method 0x91f17888. +// +// Solidity: function removeLocalMinter() returns() +func (_TokenMessenger *TokenMessengerTransactorSession) RemoveLocalMinter() (*types.Transaction, error) { + return _TokenMessenger.Contract.RemoveLocalMinter(&_TokenMessenger.TransactOpts) +} + +// RemoveRemoteTokenMessenger is a paid mutator transaction binding the contract method 0xf79fd08e. +// +// Solidity: function removeRemoteTokenMessenger(uint32 domain) returns() +func (_TokenMessenger *TokenMessengerTransactor) RemoveRemoteTokenMessenger(opts *bind.TransactOpts, domain uint32) (*types.Transaction, error) { + return _TokenMessenger.contract.Transact(opts, "removeRemoteTokenMessenger", domain) +} + +// RemoveRemoteTokenMessenger is a paid mutator transaction binding the contract method 0xf79fd08e. +// +// Solidity: function removeRemoteTokenMessenger(uint32 domain) returns() +func (_TokenMessenger *TokenMessengerSession) RemoveRemoteTokenMessenger(domain uint32) (*types.Transaction, error) { + return _TokenMessenger.Contract.RemoveRemoteTokenMessenger(&_TokenMessenger.TransactOpts, domain) +} + +// RemoveRemoteTokenMessenger is a paid mutator transaction binding the contract method 0xf79fd08e. +// +// Solidity: function removeRemoteTokenMessenger(uint32 domain) returns() +func (_TokenMessenger *TokenMessengerTransactorSession) RemoveRemoteTokenMessenger(domain uint32) (*types.Transaction, error) { + return _TokenMessenger.Contract.RemoveRemoteTokenMessenger(&_TokenMessenger.TransactOpts, domain) +} + +// ReplaceDepositForBurn is a paid mutator transaction binding the contract method 0x29a78e33. +// +// Solidity: function replaceDepositForBurn(bytes originalMessage, bytes originalAttestation, bytes32 newDestinationCaller, bytes32 newMintRecipient) returns() +func (_TokenMessenger *TokenMessengerTransactor) ReplaceDepositForBurn(opts *bind.TransactOpts, originalMessage []byte, originalAttestation []byte, newDestinationCaller [32]byte, newMintRecipient [32]byte) (*types.Transaction, error) { + return _TokenMessenger.contract.Transact(opts, "replaceDepositForBurn", originalMessage, originalAttestation, newDestinationCaller, newMintRecipient) +} + +// ReplaceDepositForBurn is a paid mutator transaction binding the contract method 0x29a78e33. +// +// Solidity: function replaceDepositForBurn(bytes originalMessage, bytes originalAttestation, bytes32 newDestinationCaller, bytes32 newMintRecipient) returns() +func (_TokenMessenger *TokenMessengerSession) ReplaceDepositForBurn(originalMessage []byte, originalAttestation []byte, newDestinationCaller [32]byte, newMintRecipient [32]byte) (*types.Transaction, error) { + return _TokenMessenger.Contract.ReplaceDepositForBurn(&_TokenMessenger.TransactOpts, originalMessage, originalAttestation, newDestinationCaller, newMintRecipient) +} + +// ReplaceDepositForBurn is a paid mutator transaction binding the contract method 0x29a78e33. +// +// Solidity: function replaceDepositForBurn(bytes originalMessage, bytes originalAttestation, bytes32 newDestinationCaller, bytes32 newMintRecipient) returns() +func (_TokenMessenger *TokenMessengerTransactorSession) ReplaceDepositForBurn(originalMessage []byte, originalAttestation []byte, newDestinationCaller [32]byte, newMintRecipient [32]byte) (*types.Transaction, error) { + return _TokenMessenger.Contract.ReplaceDepositForBurn(&_TokenMessenger.TransactOpts, originalMessage, originalAttestation, newDestinationCaller, newMintRecipient) +} + +// RescueERC20 is a paid mutator transaction binding the contract method 0xb2118a8d. +// +// Solidity: function rescueERC20(address tokenContract, address to, uint256 amount) returns() +func (_TokenMessenger *TokenMessengerTransactor) RescueERC20(opts *bind.TransactOpts, tokenContract common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _TokenMessenger.contract.Transact(opts, "rescueERC20", tokenContract, to, amount) +} + +// RescueERC20 is a paid mutator transaction binding the contract method 0xb2118a8d. +// +// Solidity: function rescueERC20(address tokenContract, address to, uint256 amount) returns() +func (_TokenMessenger *TokenMessengerSession) RescueERC20(tokenContract common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _TokenMessenger.Contract.RescueERC20(&_TokenMessenger.TransactOpts, tokenContract, to, amount) +} + +// RescueERC20 is a paid mutator transaction binding the contract method 0xb2118a8d. +// +// Solidity: function rescueERC20(address tokenContract, address to, uint256 amount) returns() +func (_TokenMessenger *TokenMessengerTransactorSession) RescueERC20(tokenContract common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _TokenMessenger.Contract.RescueERC20(&_TokenMessenger.TransactOpts, tokenContract, to, amount) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TokenMessenger *TokenMessengerTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _TokenMessenger.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TokenMessenger *TokenMessengerSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _TokenMessenger.Contract.TransferOwnership(&_TokenMessenger.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_TokenMessenger *TokenMessengerTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _TokenMessenger.Contract.TransferOwnership(&_TokenMessenger.TransactOpts, newOwner) +} + +// UpdateRescuer is a paid mutator transaction binding the contract method 0x2ab60045. +// +// Solidity: function updateRescuer(address newRescuer) returns() +func (_TokenMessenger *TokenMessengerTransactor) UpdateRescuer(opts *bind.TransactOpts, newRescuer common.Address) (*types.Transaction, error) { + return _TokenMessenger.contract.Transact(opts, "updateRescuer", newRescuer) +} + +// UpdateRescuer is a paid mutator transaction binding the contract method 0x2ab60045. +// +// Solidity: function updateRescuer(address newRescuer) returns() +func (_TokenMessenger *TokenMessengerSession) UpdateRescuer(newRescuer common.Address) (*types.Transaction, error) { + return _TokenMessenger.Contract.UpdateRescuer(&_TokenMessenger.TransactOpts, newRescuer) +} + +// UpdateRescuer is a paid mutator transaction binding the contract method 0x2ab60045. +// +// Solidity: function updateRescuer(address newRescuer) returns() +func (_TokenMessenger *TokenMessengerTransactorSession) UpdateRescuer(newRescuer common.Address) (*types.Transaction, error) { + return _TokenMessenger.Contract.UpdateRescuer(&_TokenMessenger.TransactOpts, newRescuer) +} + +// TokenMessengerDepositForBurnIterator is returned from FilterDepositForBurn and is used to iterate over the raw logs and unpacked data for DepositForBurn events raised by the TokenMessenger contract. +type TokenMessengerDepositForBurnIterator struct { + Event *TokenMessengerDepositForBurn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenMessengerDepositForBurnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenMessengerDepositForBurn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenMessengerDepositForBurn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenMessengerDepositForBurnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenMessengerDepositForBurnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenMessengerDepositForBurn represents a DepositForBurn event raised by the TokenMessenger contract. +type TokenMessengerDepositForBurn struct { + Nonce uint64 + BurnToken common.Address + Amount *big.Int + Depositor common.Address + MintRecipient [32]byte + DestinationDomain uint32 + DestinationTokenMessenger [32]byte + DestinationCaller [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDepositForBurn is a free log retrieval operation binding the contract event 0x2fa9ca894982930190727e75500a97d8dc500233a5065e0f3126c48fbe0343c0. +// +// Solidity: event DepositForBurn(uint64 indexed nonce, address indexed burnToken, uint256 amount, address indexed depositor, bytes32 mintRecipient, uint32 destinationDomain, bytes32 destinationTokenMessenger, bytes32 destinationCaller) +func (_TokenMessenger *TokenMessengerFilterer) FilterDepositForBurn(opts *bind.FilterOpts, nonce []uint64, burnToken []common.Address, depositor []common.Address) (*TokenMessengerDepositForBurnIterator, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var burnTokenRule []interface{} + for _, burnTokenItem := range burnToken { + burnTokenRule = append(burnTokenRule, burnTokenItem) + } + + var depositorRule []interface{} + for _, depositorItem := range depositor { + depositorRule = append(depositorRule, depositorItem) + } + + logs, sub, err := _TokenMessenger.contract.FilterLogs(opts, "DepositForBurn", nonceRule, burnTokenRule, depositorRule) + if err != nil { + return nil, err + } + return &TokenMessengerDepositForBurnIterator{contract: _TokenMessenger.contract, event: "DepositForBurn", logs: logs, sub: sub}, nil +} + +// WatchDepositForBurn is a free log subscription operation binding the contract event 0x2fa9ca894982930190727e75500a97d8dc500233a5065e0f3126c48fbe0343c0. +// +// Solidity: event DepositForBurn(uint64 indexed nonce, address indexed burnToken, uint256 amount, address indexed depositor, bytes32 mintRecipient, uint32 destinationDomain, bytes32 destinationTokenMessenger, bytes32 destinationCaller) +func (_TokenMessenger *TokenMessengerFilterer) WatchDepositForBurn(opts *bind.WatchOpts, sink chan<- *TokenMessengerDepositForBurn, nonce []uint64, burnToken []common.Address, depositor []common.Address) (event.Subscription, error) { + + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var burnTokenRule []interface{} + for _, burnTokenItem := range burnToken { + burnTokenRule = append(burnTokenRule, burnTokenItem) + } + + var depositorRule []interface{} + for _, depositorItem := range depositor { + depositorRule = append(depositorRule, depositorItem) + } + + logs, sub, err := _TokenMessenger.contract.WatchLogs(opts, "DepositForBurn", nonceRule, burnTokenRule, depositorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenMessengerDepositForBurn) + if err := _TokenMessenger.contract.UnpackLog(event, "DepositForBurn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDepositForBurn is a log parse operation binding the contract event 0x2fa9ca894982930190727e75500a97d8dc500233a5065e0f3126c48fbe0343c0. +// +// Solidity: event DepositForBurn(uint64 indexed nonce, address indexed burnToken, uint256 amount, address indexed depositor, bytes32 mintRecipient, uint32 destinationDomain, bytes32 destinationTokenMessenger, bytes32 destinationCaller) +func (_TokenMessenger *TokenMessengerFilterer) ParseDepositForBurn(log types.Log) (*TokenMessengerDepositForBurn, error) { + event := new(TokenMessengerDepositForBurn) + if err := _TokenMessenger.contract.UnpackLog(event, "DepositForBurn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenMessengerLocalMinterAddedIterator is returned from FilterLocalMinterAdded and is used to iterate over the raw logs and unpacked data for LocalMinterAdded events raised by the TokenMessenger contract. +type TokenMessengerLocalMinterAddedIterator struct { + Event *TokenMessengerLocalMinterAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenMessengerLocalMinterAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenMessengerLocalMinterAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenMessengerLocalMinterAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenMessengerLocalMinterAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenMessengerLocalMinterAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenMessengerLocalMinterAdded represents a LocalMinterAdded event raised by the TokenMessenger contract. +type TokenMessengerLocalMinterAdded struct { + LocalMinter common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterLocalMinterAdded is a free log retrieval operation binding the contract event 0x109bb3e70cbf1931e295b49e75c67013b85ff80d64e6f1d321f37157b90c3830. +// +// Solidity: event LocalMinterAdded(address localMinter) +func (_TokenMessenger *TokenMessengerFilterer) FilterLocalMinterAdded(opts *bind.FilterOpts) (*TokenMessengerLocalMinterAddedIterator, error) { + + logs, sub, err := _TokenMessenger.contract.FilterLogs(opts, "LocalMinterAdded") + if err != nil { + return nil, err + } + return &TokenMessengerLocalMinterAddedIterator{contract: _TokenMessenger.contract, event: "LocalMinterAdded", logs: logs, sub: sub}, nil +} + +// WatchLocalMinterAdded is a free log subscription operation binding the contract event 0x109bb3e70cbf1931e295b49e75c67013b85ff80d64e6f1d321f37157b90c3830. +// +// Solidity: event LocalMinterAdded(address localMinter) +func (_TokenMessenger *TokenMessengerFilterer) WatchLocalMinterAdded(opts *bind.WatchOpts, sink chan<- *TokenMessengerLocalMinterAdded) (event.Subscription, error) { + + logs, sub, err := _TokenMessenger.contract.WatchLogs(opts, "LocalMinterAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenMessengerLocalMinterAdded) + if err := _TokenMessenger.contract.UnpackLog(event, "LocalMinterAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseLocalMinterAdded is a log parse operation binding the contract event 0x109bb3e70cbf1931e295b49e75c67013b85ff80d64e6f1d321f37157b90c3830. +// +// Solidity: event LocalMinterAdded(address localMinter) +func (_TokenMessenger *TokenMessengerFilterer) ParseLocalMinterAdded(log types.Log) (*TokenMessengerLocalMinterAdded, error) { + event := new(TokenMessengerLocalMinterAdded) + if err := _TokenMessenger.contract.UnpackLog(event, "LocalMinterAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenMessengerLocalMinterRemovedIterator is returned from FilterLocalMinterRemoved and is used to iterate over the raw logs and unpacked data for LocalMinterRemoved events raised by the TokenMessenger contract. +type TokenMessengerLocalMinterRemovedIterator struct { + Event *TokenMessengerLocalMinterRemoved // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenMessengerLocalMinterRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenMessengerLocalMinterRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenMessengerLocalMinterRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenMessengerLocalMinterRemovedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenMessengerLocalMinterRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenMessengerLocalMinterRemoved represents a LocalMinterRemoved event raised by the TokenMessenger contract. +type TokenMessengerLocalMinterRemoved struct { + LocalMinter common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterLocalMinterRemoved is a free log retrieval operation binding the contract event 0x2db49fbf671271826a27b02ebc496209c85fffffb4bccc67430d2a0f22b4d1ac. +// +// Solidity: event LocalMinterRemoved(address localMinter) +func (_TokenMessenger *TokenMessengerFilterer) FilterLocalMinterRemoved(opts *bind.FilterOpts) (*TokenMessengerLocalMinterRemovedIterator, error) { + + logs, sub, err := _TokenMessenger.contract.FilterLogs(opts, "LocalMinterRemoved") + if err != nil { + return nil, err + } + return &TokenMessengerLocalMinterRemovedIterator{contract: _TokenMessenger.contract, event: "LocalMinterRemoved", logs: logs, sub: sub}, nil +} + +// WatchLocalMinterRemoved is a free log subscription operation binding the contract event 0x2db49fbf671271826a27b02ebc496209c85fffffb4bccc67430d2a0f22b4d1ac. +// +// Solidity: event LocalMinterRemoved(address localMinter) +func (_TokenMessenger *TokenMessengerFilterer) WatchLocalMinterRemoved(opts *bind.WatchOpts, sink chan<- *TokenMessengerLocalMinterRemoved) (event.Subscription, error) { + + logs, sub, err := _TokenMessenger.contract.WatchLogs(opts, "LocalMinterRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenMessengerLocalMinterRemoved) + if err := _TokenMessenger.contract.UnpackLog(event, "LocalMinterRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseLocalMinterRemoved is a log parse operation binding the contract event 0x2db49fbf671271826a27b02ebc496209c85fffffb4bccc67430d2a0f22b4d1ac. +// +// Solidity: event LocalMinterRemoved(address localMinter) +func (_TokenMessenger *TokenMessengerFilterer) ParseLocalMinterRemoved(log types.Log) (*TokenMessengerLocalMinterRemoved, error) { + event := new(TokenMessengerLocalMinterRemoved) + if err := _TokenMessenger.contract.UnpackLog(event, "LocalMinterRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenMessengerMintAndWithdrawIterator is returned from FilterMintAndWithdraw and is used to iterate over the raw logs and unpacked data for MintAndWithdraw events raised by the TokenMessenger contract. +type TokenMessengerMintAndWithdrawIterator struct { + Event *TokenMessengerMintAndWithdraw // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenMessengerMintAndWithdrawIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenMessengerMintAndWithdraw) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenMessengerMintAndWithdraw) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenMessengerMintAndWithdrawIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenMessengerMintAndWithdrawIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenMessengerMintAndWithdraw represents a MintAndWithdraw event raised by the TokenMessenger contract. +type TokenMessengerMintAndWithdraw struct { + MintRecipient common.Address + Amount *big.Int + MintToken common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMintAndWithdraw is a free log retrieval operation binding the contract event 0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6. +// +// Solidity: event MintAndWithdraw(address indexed mintRecipient, uint256 amount, address indexed mintToken) +func (_TokenMessenger *TokenMessengerFilterer) FilterMintAndWithdraw(opts *bind.FilterOpts, mintRecipient []common.Address, mintToken []common.Address) (*TokenMessengerMintAndWithdrawIterator, error) { + + var mintRecipientRule []interface{} + for _, mintRecipientItem := range mintRecipient { + mintRecipientRule = append(mintRecipientRule, mintRecipientItem) + } + + var mintTokenRule []interface{} + for _, mintTokenItem := range mintToken { + mintTokenRule = append(mintTokenRule, mintTokenItem) + } + + logs, sub, err := _TokenMessenger.contract.FilterLogs(opts, "MintAndWithdraw", mintRecipientRule, mintTokenRule) + if err != nil { + return nil, err + } + return &TokenMessengerMintAndWithdrawIterator{contract: _TokenMessenger.contract, event: "MintAndWithdraw", logs: logs, sub: sub}, nil +} + +// WatchMintAndWithdraw is a free log subscription operation binding the contract event 0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6. +// +// Solidity: event MintAndWithdraw(address indexed mintRecipient, uint256 amount, address indexed mintToken) +func (_TokenMessenger *TokenMessengerFilterer) WatchMintAndWithdraw(opts *bind.WatchOpts, sink chan<- *TokenMessengerMintAndWithdraw, mintRecipient []common.Address, mintToken []common.Address) (event.Subscription, error) { + + var mintRecipientRule []interface{} + for _, mintRecipientItem := range mintRecipient { + mintRecipientRule = append(mintRecipientRule, mintRecipientItem) + } + + var mintTokenRule []interface{} + for _, mintTokenItem := range mintToken { + mintTokenRule = append(mintTokenRule, mintTokenItem) + } + + logs, sub, err := _TokenMessenger.contract.WatchLogs(opts, "MintAndWithdraw", mintRecipientRule, mintTokenRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenMessengerMintAndWithdraw) + if err := _TokenMessenger.contract.UnpackLog(event, "MintAndWithdraw", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseMintAndWithdraw is a log parse operation binding the contract event 0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6. +// +// Solidity: event MintAndWithdraw(address indexed mintRecipient, uint256 amount, address indexed mintToken) +func (_TokenMessenger *TokenMessengerFilterer) ParseMintAndWithdraw(log types.Log) (*TokenMessengerMintAndWithdraw, error) { + event := new(TokenMessengerMintAndWithdraw) + if err := _TokenMessenger.contract.UnpackLog(event, "MintAndWithdraw", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenMessengerOwnershipTransferStartedIterator is returned from FilterOwnershipTransferStarted and is used to iterate over the raw logs and unpacked data for OwnershipTransferStarted events raised by the TokenMessenger contract. +type TokenMessengerOwnershipTransferStartedIterator struct { + Event *TokenMessengerOwnershipTransferStarted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenMessengerOwnershipTransferStartedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenMessengerOwnershipTransferStarted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenMessengerOwnershipTransferStarted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenMessengerOwnershipTransferStartedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenMessengerOwnershipTransferStartedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenMessengerOwnershipTransferStarted represents a OwnershipTransferStarted event raised by the TokenMessenger contract. +type TokenMessengerOwnershipTransferStarted struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferStarted is a free log retrieval operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_TokenMessenger *TokenMessengerFilterer) FilterOwnershipTransferStarted(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*TokenMessengerOwnershipTransferStartedIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TokenMessenger.contract.FilterLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &TokenMessengerOwnershipTransferStartedIterator{contract: _TokenMessenger.contract, event: "OwnershipTransferStarted", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferStarted is a free log subscription operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_TokenMessenger *TokenMessengerFilterer) WatchOwnershipTransferStarted(opts *bind.WatchOpts, sink chan<- *TokenMessengerOwnershipTransferStarted, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TokenMessenger.contract.WatchLogs(opts, "OwnershipTransferStarted", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenMessengerOwnershipTransferStarted) + if err := _TokenMessenger.contract.UnpackLog(event, "OwnershipTransferStarted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferStarted is a log parse operation binding the contract event 0x38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e22700. +// +// Solidity: event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner) +func (_TokenMessenger *TokenMessengerFilterer) ParseOwnershipTransferStarted(log types.Log) (*TokenMessengerOwnershipTransferStarted, error) { + event := new(TokenMessengerOwnershipTransferStarted) + if err := _TokenMessenger.contract.UnpackLog(event, "OwnershipTransferStarted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenMessengerOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the TokenMessenger contract. +type TokenMessengerOwnershipTransferredIterator struct { + Event *TokenMessengerOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenMessengerOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenMessengerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenMessengerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenMessengerOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenMessengerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenMessengerOwnershipTransferred represents a OwnershipTransferred event raised by the TokenMessenger contract. +type TokenMessengerOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TokenMessenger *TokenMessengerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*TokenMessengerOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TokenMessenger.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &TokenMessengerOwnershipTransferredIterator{contract: _TokenMessenger.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TokenMessenger *TokenMessengerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *TokenMessengerOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _TokenMessenger.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenMessengerOwnershipTransferred) + if err := _TokenMessenger.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_TokenMessenger *TokenMessengerFilterer) ParseOwnershipTransferred(log types.Log) (*TokenMessengerOwnershipTransferred, error) { + event := new(TokenMessengerOwnershipTransferred) + if err := _TokenMessenger.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenMessengerRemoteTokenMessengerAddedIterator is returned from FilterRemoteTokenMessengerAdded and is used to iterate over the raw logs and unpacked data for RemoteTokenMessengerAdded events raised by the TokenMessenger contract. +type TokenMessengerRemoteTokenMessengerAddedIterator struct { + Event *TokenMessengerRemoteTokenMessengerAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenMessengerRemoteTokenMessengerAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenMessengerRemoteTokenMessengerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenMessengerRemoteTokenMessengerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenMessengerRemoteTokenMessengerAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenMessengerRemoteTokenMessengerAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenMessengerRemoteTokenMessengerAdded represents a RemoteTokenMessengerAdded event raised by the TokenMessenger contract. +type TokenMessengerRemoteTokenMessengerAdded struct { + Domain uint32 + TokenMessenger [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRemoteTokenMessengerAdded is a free log retrieval operation binding the contract event 0x4bba2b08298cf59661b4895e384cc2ac3962ce2d71f1b7c11bca52e1169f9599. +// +// Solidity: event RemoteTokenMessengerAdded(uint32 domain, bytes32 tokenMessenger) +func (_TokenMessenger *TokenMessengerFilterer) FilterRemoteTokenMessengerAdded(opts *bind.FilterOpts) (*TokenMessengerRemoteTokenMessengerAddedIterator, error) { + + logs, sub, err := _TokenMessenger.contract.FilterLogs(opts, "RemoteTokenMessengerAdded") + if err != nil { + return nil, err + } + return &TokenMessengerRemoteTokenMessengerAddedIterator{contract: _TokenMessenger.contract, event: "RemoteTokenMessengerAdded", logs: logs, sub: sub}, nil +} + +// WatchRemoteTokenMessengerAdded is a free log subscription operation binding the contract event 0x4bba2b08298cf59661b4895e384cc2ac3962ce2d71f1b7c11bca52e1169f9599. +// +// Solidity: event RemoteTokenMessengerAdded(uint32 domain, bytes32 tokenMessenger) +func (_TokenMessenger *TokenMessengerFilterer) WatchRemoteTokenMessengerAdded(opts *bind.WatchOpts, sink chan<- *TokenMessengerRemoteTokenMessengerAdded) (event.Subscription, error) { + + logs, sub, err := _TokenMessenger.contract.WatchLogs(opts, "RemoteTokenMessengerAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenMessengerRemoteTokenMessengerAdded) + if err := _TokenMessenger.contract.UnpackLog(event, "RemoteTokenMessengerAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseRemoteTokenMessengerAdded is a log parse operation binding the contract event 0x4bba2b08298cf59661b4895e384cc2ac3962ce2d71f1b7c11bca52e1169f9599. +// +// Solidity: event RemoteTokenMessengerAdded(uint32 domain, bytes32 tokenMessenger) +func (_TokenMessenger *TokenMessengerFilterer) ParseRemoteTokenMessengerAdded(log types.Log) (*TokenMessengerRemoteTokenMessengerAdded, error) { + event := new(TokenMessengerRemoteTokenMessengerAdded) + if err := _TokenMessenger.contract.UnpackLog(event, "RemoteTokenMessengerAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenMessengerRemoteTokenMessengerRemovedIterator is returned from FilterRemoteTokenMessengerRemoved and is used to iterate over the raw logs and unpacked data for RemoteTokenMessengerRemoved events raised by the TokenMessenger contract. +type TokenMessengerRemoteTokenMessengerRemovedIterator struct { + Event *TokenMessengerRemoteTokenMessengerRemoved // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenMessengerRemoteTokenMessengerRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenMessengerRemoteTokenMessengerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenMessengerRemoteTokenMessengerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenMessengerRemoteTokenMessengerRemovedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenMessengerRemoteTokenMessengerRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenMessengerRemoteTokenMessengerRemoved represents a RemoteTokenMessengerRemoved event raised by the TokenMessenger contract. +type TokenMessengerRemoteTokenMessengerRemoved struct { + Domain uint32 + TokenMessenger [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRemoteTokenMessengerRemoved is a free log retrieval operation binding the contract event 0x3dcea012093dbca2bb8ed7fd2b2ff90305ab70bddda8bbb94d4152735a98f0b1. +// +// Solidity: event RemoteTokenMessengerRemoved(uint32 domain, bytes32 tokenMessenger) +func (_TokenMessenger *TokenMessengerFilterer) FilterRemoteTokenMessengerRemoved(opts *bind.FilterOpts) (*TokenMessengerRemoteTokenMessengerRemovedIterator, error) { + + logs, sub, err := _TokenMessenger.contract.FilterLogs(opts, "RemoteTokenMessengerRemoved") + if err != nil { + return nil, err + } + return &TokenMessengerRemoteTokenMessengerRemovedIterator{contract: _TokenMessenger.contract, event: "RemoteTokenMessengerRemoved", logs: logs, sub: sub}, nil +} + +// WatchRemoteTokenMessengerRemoved is a free log subscription operation binding the contract event 0x3dcea012093dbca2bb8ed7fd2b2ff90305ab70bddda8bbb94d4152735a98f0b1. +// +// Solidity: event RemoteTokenMessengerRemoved(uint32 domain, bytes32 tokenMessenger) +func (_TokenMessenger *TokenMessengerFilterer) WatchRemoteTokenMessengerRemoved(opts *bind.WatchOpts, sink chan<- *TokenMessengerRemoteTokenMessengerRemoved) (event.Subscription, error) { + + logs, sub, err := _TokenMessenger.contract.WatchLogs(opts, "RemoteTokenMessengerRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenMessengerRemoteTokenMessengerRemoved) + if err := _TokenMessenger.contract.UnpackLog(event, "RemoteTokenMessengerRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseRemoteTokenMessengerRemoved is a log parse operation binding the contract event 0x3dcea012093dbca2bb8ed7fd2b2ff90305ab70bddda8bbb94d4152735a98f0b1. +// +// Solidity: event RemoteTokenMessengerRemoved(uint32 domain, bytes32 tokenMessenger) +func (_TokenMessenger *TokenMessengerFilterer) ParseRemoteTokenMessengerRemoved(log types.Log) (*TokenMessengerRemoteTokenMessengerRemoved, error) { + event := new(TokenMessengerRemoteTokenMessengerRemoved) + if err := _TokenMessenger.contract.UnpackLog(event, "RemoteTokenMessengerRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenMessengerRescuerChangedIterator is returned from FilterRescuerChanged and is used to iterate over the raw logs and unpacked data for RescuerChanged events raised by the TokenMessenger contract. +type TokenMessengerRescuerChangedIterator struct { + Event *TokenMessengerRescuerChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenMessengerRescuerChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenMessengerRescuerChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenMessengerRescuerChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenMessengerRescuerChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenMessengerRescuerChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenMessengerRescuerChanged represents a RescuerChanged event raised by the TokenMessenger contract. +type TokenMessengerRescuerChanged struct { + NewRescuer common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRescuerChanged is a free log retrieval operation binding the contract event 0xe475e580d85111348e40d8ca33cfdd74c30fe1655c2d8537a13abc10065ffa5a. +// +// Solidity: event RescuerChanged(address indexed newRescuer) +func (_TokenMessenger *TokenMessengerFilterer) FilterRescuerChanged(opts *bind.FilterOpts, newRescuer []common.Address) (*TokenMessengerRescuerChangedIterator, error) { + + var newRescuerRule []interface{} + for _, newRescuerItem := range newRescuer { + newRescuerRule = append(newRescuerRule, newRescuerItem) + } + + logs, sub, err := _TokenMessenger.contract.FilterLogs(opts, "RescuerChanged", newRescuerRule) + if err != nil { + return nil, err + } + return &TokenMessengerRescuerChangedIterator{contract: _TokenMessenger.contract, event: "RescuerChanged", logs: logs, sub: sub}, nil +} + +// WatchRescuerChanged is a free log subscription operation binding the contract event 0xe475e580d85111348e40d8ca33cfdd74c30fe1655c2d8537a13abc10065ffa5a. +// +// Solidity: event RescuerChanged(address indexed newRescuer) +func (_TokenMessenger *TokenMessengerFilterer) WatchRescuerChanged(opts *bind.WatchOpts, sink chan<- *TokenMessengerRescuerChanged, newRescuer []common.Address) (event.Subscription, error) { + + var newRescuerRule []interface{} + for _, newRescuerItem := range newRescuer { + newRescuerRule = append(newRescuerRule, newRescuerItem) + } + + logs, sub, err := _TokenMessenger.contract.WatchLogs(opts, "RescuerChanged", newRescuerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenMessengerRescuerChanged) + if err := _TokenMessenger.contract.UnpackLog(event, "RescuerChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseRescuerChanged is a log parse operation binding the contract event 0xe475e580d85111348e40d8ca33cfdd74c30fe1655c2d8537a13abc10065ffa5a. +// +// Solidity: event RescuerChanged(address indexed newRescuer) +func (_TokenMessenger *TokenMessengerFilterer) ParseRescuerChanged(log types.Log) (*TokenMessengerRescuerChanged, error) { + event := new(TokenMessengerRescuerChanged) + if err := _TokenMessenger.contract.UnpackLog(event, "RescuerChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func CreateTokenMessengerDeploymentCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc string + var gasLimit uint64 + var simulate bool + var timeout uint + var safeAddress, safeApi, safeCreateCall, safeSaltRaw, safeNonceRaw string + var safeOperationType uint8 + var salt [32]byte + var predictAddress bool + var safeNonce *big.Int + var calldata bool + + var messageTransmitter common.Address + var messageTransmitterRaw string + var messageBodyVersion uint32 + + cmd := &cobra.Command{ + Use: "deploy", + Short: "Deploy a new TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + + if !calldata { + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if safeCreateCall == "" { + fmt.Println("--safe-create-call not specified, using default (0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4)") + safeCreateCall = "0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4" + } + if !common.IsHexAddress(safeCreateCall) { + return fmt.Errorf("--safe-create-call is not a valid Ethereum address") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + + if safeSaltRaw == "" { + fmt.Println("--safe-salt not specified, generating random salt") + _, err := rand.Read(salt[:]) + if err != nil { + return fmt.Errorf("failed to generate random salt: %v", err) + } + // prompt user to accept random salt + fmt.Println("Generated salt:", common.Bytes2Hex(salt[:])) + fmt.Println("Please check the salt and confirm (y/n)") + var confirm string + fmt.Scanln(&confirm) + if confirm != "y" && confirm != "Y" && confirm != "\n" && confirm != "" { + return fmt.Errorf("salt not accepted, please specify a valid salt") + } + } else { + copy(salt[:], safeSaltRaw) + } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } + } + + if messageTransmitterRaw == "" { + return fmt.Errorf("--message-transmitter argument not specified") + } else if !common.IsHexAddress(messageTransmitterRaw) { + return fmt.Errorf("--message-transmitter argument is not a valid Ethereum address") + } + messageTransmitter = common.HexToAddress(messageTransmitterRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + // Generate deploy bytecode with constructor arguments + deployCalldata, err := generateTokenMessengerDeployBytecode( + messageTransmitter, + messageBodyVersion, + ) + if err != nil { + return fmt.Errorf("failed to generate deploy bytecode: %v", err) + } + + if calldata { + deployCalldataHex := hex.EncodeToString(deployCalldata) + cmd.Println(deployCalldataHex) + return nil + } + + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + if safeAddress != "" { + // Create Safe proposal for deployment + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + + if predictAddress { + fmt.Println("Predicting deployment address...") + from := common.HexToAddress(safeAddress) + if safeOperationType == 0 { + from = common.HexToAddress(safeCreateCall) + } + deploymentAddress, err := PredictDeploymentAddressSafe(from, salt, deployCalldata) + if err != nil { + return fmt.Errorf("failed to predict deployment address: %v", err) + } + fmt.Println("Predicted deployment address:", deploymentAddress.Hex()) + return nil + } else { + fmt.Println("Creating Safe proposal...") + err = DeployWithSafe(client, key, common.HexToAddress(safeAddress), common.HexToAddress(safeCreateCall), value, safeApi, deployCalldata, SafeOperationType(safeOperationType), salt, safeNonce) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + } + + return nil + } + + address, deploymentTransaction, _, deploymentErr := DeployTokenMessenger( + transactionOpts, + client, + messageTransmitter, + messageBodyVersion, + ) + if deploymentErr != nil { + return deploymentErr + } + + cmd.Printf("Transaction hash: %s\nContract address: %s\n", deploymentTransaction.Hash().Hex(), address.Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + Data: deploymentTransaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := deploymentTransaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().StringVar(&safeCreateCall, "safe-create-call", "", "Address of the CreateCall contract (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 1, "Safe operation type: 0 (Call) or 1 (DelegateCall) - default is 1") + cmd.Flags().StringVar(&safeSaltRaw, "safe-salt", "", "Salt to use for the Safe transaction") + cmd.Flags().BoolVar(&predictAddress, "safe-predict-address", false, "Predict the deployment address (only works for Safe transactions)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") + cmd.Flags().BoolVar(&calldata, "calldata", false, "Set this flag if want to return the calldata instead of sending the transaction") + + cmd.Flags().StringVar(&messageTransmitterRaw, "message-transmitter", "", "message-transmitter argument (common.Address)") + cmd.Flags().Uint32Var(&messageBodyVersion, "message-body-version", 0, "message-body-version argument") + + return cmd +} + +func generateTokenMessengerDeployBytecode( + messageTransmitter common.Address, + messageBodyVersion uint32, +) ([]byte, error) { + abiPacked, err := TokenMessengerMetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to get ABI: %v", err) + } + + constructorArguments, err := abiPacked.Pack("", + messageTransmitter, + messageBodyVersion, + ) + if err != nil { + return nil, fmt.Errorf("failed to pack constructor arguments: %v", err) + } + + deployBytecode := append(common.FromHex(TokenMessengerMetaData.Bin), constructorArguments...) + return deployBytecode, nil +} + +func CreateLocalMessageTransmitterCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 common.Address + + cmd := &cobra.Command{ + Use: "local-message-transmitter", + Short: "Call the LocalMessageTransmitter view method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := TokenMessengerCallerSession{ + Contract: &contract.TokenMessengerCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.LocalMessageTransmitter() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.Hex()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateLocalMinterCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 common.Address + + cmd := &cobra.Command{ + Use: "local-minter", + Short: "Call the LocalMinter view method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := TokenMessengerCallerSession{ + Contract: &contract.TokenMessengerCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.LocalMinter() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.Hex()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateMessageBodyVersionCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 uint32 + + cmd := &cobra.Command{ + Use: "message-body-version", + Short: "Call the MessageBodyVersion view method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := TokenMessengerCallerSession{ + Contract: &contract.TokenMessengerCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.MessageBodyVersion() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %d\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateOwnerCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 common.Address + + cmd := &cobra.Command{ + Use: "owner", + Short: "Call the Owner view method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := TokenMessengerCallerSession{ + Contract: &contract.TokenMessengerCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.Owner() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.Hex()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreatePendingOwnerCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 common.Address + + cmd := &cobra.Command{ + Use: "pending-owner", + Short: "Call the PendingOwner view method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := TokenMessengerCallerSession{ + Contract: &contract.TokenMessengerCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.PendingOwner() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.Hex()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} +func CreateRemoteTokenMessengersCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var arg0 uint32 + + var capture0 [32]byte + + cmd := &cobra.Command{ + Use: "remote-token-messengers", + Short: "Call the RemoteTokenMessengers view method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := TokenMessengerCallerSession{ + Contract: &contract.TokenMessengerCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.RemoteTokenMessengers( + arg0, + ) + if callErr != nil { + return callErr + } + + cmd.Printf("0: %v\n", capture0) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + cmd.Flags().Uint32Var(&arg0, "arg-0", 0, "arg-0 argument") + + return cmd +} +func CreateRescuerCommand() *cobra.Command { + var contractAddressRaw, rpc string + var contractAddress common.Address + var timeout uint + + var blockNumberRaw, fromAddressRaw string + var pending bool + + var capture0 common.Address + + cmd := &cobra.Command{ + Use: "rescuer", + Short: "Call the Rescuer view method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + callOpts := bind.CallOpts{} + SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) + + session := TokenMessengerCallerSession{ + Contract: &contract.TokenMessengerCaller, + CallOpts: callOpts, + } + + var callErr error + capture0, callErr = session.Rescuer() + if callErr != nil { + return callErr + } + + cmd.Printf("0: %s\n", capture0.Hex()) + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") + cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") + + return cmd +} + +func CreateAcceptOwnershipCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 + var safeNonce *big.Int + var calldata bool + + cmd := &cobra.Command{ + Use: "accept-ownership", + Short: "Execute the AcceptOwnership method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if !calldata { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + abi, err := TokenMessengerMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "acceptOwnership" + if safeFunction != "" { + methodName = safeFunction + } + + txCalldata, err := abi.Pack( + methodName, + ) + + if err != nil { + return err + } + + if calldata { + txCalldataHex := hex.EncodeToString(txCalldata) + cmd.Println(txCalldataHex) + return nil + } + + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := TokenMessengerTransactorSession{ + Contract: &contract.TokenMessengerTransactor, + TransactOpts: *transactionOpts, + } + + if safeAddress != "" { + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, txCalldata, value, safeApi, SafeOperationType(safeOperationType), safeNonce) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.AcceptOwnership() + if err != nil { + return err + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().StringVar(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") + cmd.Flags().BoolVar(&calldata, "calldata", false, "Set this flag if want to return the calldata instead of sending the transaction") + + return cmd +} +func CreateAddLocalMinterCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 + var safeNonce *big.Int + var calldata bool + + var newLocalMinter common.Address + var newLocalMinterRaw string + + cmd := &cobra.Command{ + Use: "add-local-minter", + Short: "Execute the AddLocalMinter method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if !calldata { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } + } + + if newLocalMinterRaw == "" { + return fmt.Errorf("--new-local-minter argument not specified") + } else if !common.IsHexAddress(newLocalMinterRaw) { + return fmt.Errorf("--new-local-minter argument is not a valid Ethereum address") + } + newLocalMinter = common.HexToAddress(newLocalMinterRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + abi, err := TokenMessengerMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "addLocalMinter" + if safeFunction != "" { + methodName = safeFunction + } + + txCalldata, err := abi.Pack( + methodName, + newLocalMinter, + ) + + if err != nil { + return err + } + + if calldata { + txCalldataHex := hex.EncodeToString(txCalldata) + cmd.Println(txCalldataHex) + return nil + } + + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := TokenMessengerTransactorSession{ + Contract: &contract.TokenMessengerTransactor, + TransactOpts: *transactionOpts, + } + + if safeAddress != "" { + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, txCalldata, value, safeApi, SafeOperationType(safeOperationType), safeNonce) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.AddLocalMinter( + + newLocalMinter, + ) + if err != nil { + return err + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().StringVar(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") + cmd.Flags().BoolVar(&calldata, "calldata", false, "Set this flag if want to return the calldata instead of sending the transaction") + + cmd.Flags().StringVar(&newLocalMinterRaw, "new-local-minter", "", "new-local-minter argument (common.Address)") + + return cmd +} +func CreateAddRemoteTokenMessengerCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 + var safeNonce *big.Int + var calldata bool + + var domain uint32 + + var tokenMessenger [32]byte + var tokenMessengerRaw string + + cmd := &cobra.Command{ + Use: "add-remote-token-messenger", + Short: "Execute the AddRemoteTokenMessenger method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if !calldata { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } + } + + var tokenMessengerIntermediate []byte + + var tokenMessengerIntermediateHexDecodeErr error + tokenMessengerIntermediate, tokenMessengerIntermediateHexDecodeErr = hex.DecodeString(tokenMessengerRaw) + if tokenMessengerIntermediateHexDecodeErr != nil { + return tokenMessengerIntermediateHexDecodeErr + } + + copy(tokenMessenger[:], tokenMessengerIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + abi, err := TokenMessengerMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "addRemoteTokenMessenger" + if safeFunction != "" { + methodName = safeFunction + } + + txCalldata, err := abi.Pack( + methodName, + domain, + tokenMessenger, + ) + + if err != nil { + return err + } + + if calldata { + txCalldataHex := hex.EncodeToString(txCalldata) + cmd.Println(txCalldataHex) + return nil + } + + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := TokenMessengerTransactorSession{ + Contract: &contract.TokenMessengerTransactor, + TransactOpts: *transactionOpts, + } + + if safeAddress != "" { + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, txCalldata, value, safeApi, SafeOperationType(safeOperationType), safeNonce) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.AddRemoteTokenMessenger( + + domain, + tokenMessenger, + ) + if err != nil { + return err + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().StringVar(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") + cmd.Flags().BoolVar(&calldata, "calldata", false, "Set this flag if want to return the calldata instead of sending the transaction") + + cmd.Flags().Uint32Var(&domain, "domain", 0, "domain argument") + cmd.Flags().StringVar(&tokenMessengerRaw, "token-messenger", "", "token-messenger argument ([32]byte)") + + return cmd +} +func CreateDepositForBurnCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 + var safeNonce *big.Int + var calldata bool + + var amount *big.Int + var amountRaw string + var destinationDomain uint32 + + var mintRecipient [32]byte + var mintRecipientRaw string + var burnToken common.Address + var burnTokenRaw string + + cmd := &cobra.Command{ + Use: "deposit-for-burn", + Short: "Execute the DepositForBurn method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if !calldata { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } + } + + if amountRaw == "" { + return fmt.Errorf("--amount argument not specified") + } + amount = new(big.Int) + amount.SetString(amountRaw, 0) + + var mintRecipientIntermediate []byte + + var mintRecipientIntermediateHexDecodeErr error + mintRecipientIntermediate, mintRecipientIntermediateHexDecodeErr = hex.DecodeString(mintRecipientRaw) + if mintRecipientIntermediateHexDecodeErr != nil { + return mintRecipientIntermediateHexDecodeErr + } + + copy(mintRecipient[:], mintRecipientIntermediate) + + if burnTokenRaw == "" { + return fmt.Errorf("--burn-token argument not specified") + } else if !common.IsHexAddress(burnTokenRaw) { + return fmt.Errorf("--burn-token argument is not a valid Ethereum address") + } + burnToken = common.HexToAddress(burnTokenRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + abi, err := TokenMessengerMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "depositForBurn" + if safeFunction != "" { + methodName = safeFunction + } + + txCalldata, err := abi.Pack( + methodName, + amount, + destinationDomain, + mintRecipient, + burnToken, + ) + + if err != nil { + return err + } + + if calldata { + txCalldataHex := hex.EncodeToString(txCalldata) + cmd.Println(txCalldataHex) + return nil + } + + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := TokenMessengerTransactorSession{ + Contract: &contract.TokenMessengerTransactor, + TransactOpts: *transactionOpts, + } + + if safeAddress != "" { + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, txCalldata, value, safeApi, SafeOperationType(safeOperationType), safeNonce) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.DepositForBurn( + + amount, + destinationDomain, + mintRecipient, + burnToken, + ) + if err != nil { + return err + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().StringVar(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") + cmd.Flags().BoolVar(&calldata, "calldata", false, "Set this flag if want to return the calldata instead of sending the transaction") + + cmd.Flags().StringVar(&amountRaw, "amount", "", "amount argument") + cmd.Flags().Uint32Var(&destinationDomain, "destination-domain", 0, "destination-domain argument") + cmd.Flags().StringVar(&mintRecipientRaw, "mint-recipient", "", "mint-recipient argument ([32]byte)") + cmd.Flags().StringVar(&burnTokenRaw, "burn-token", "", "burn-token argument (common.Address)") + + return cmd +} +func CreateDepositForBurnWithCallerCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 + var safeNonce *big.Int + var calldata bool + + var amount *big.Int + var amountRaw string + var destinationDomain uint32 + + var mintRecipient [32]byte + var mintRecipientRaw string + var burnToken common.Address + var burnTokenRaw string + var destinationCaller [32]byte + var destinationCallerRaw string + + cmd := &cobra.Command{ + Use: "deposit-for-burn-with-caller", + Short: "Execute the DepositForBurnWithCaller method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if !calldata { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } + } + + if amountRaw == "" { + return fmt.Errorf("--amount argument not specified") + } + amount = new(big.Int) + amount.SetString(amountRaw, 0) + + var mintRecipientIntermediate []byte + + var mintRecipientIntermediateHexDecodeErr error + mintRecipientIntermediate, mintRecipientIntermediateHexDecodeErr = hex.DecodeString(mintRecipientRaw) + if mintRecipientIntermediateHexDecodeErr != nil { + return mintRecipientIntermediateHexDecodeErr + } + + copy(mintRecipient[:], mintRecipientIntermediate) + + if burnTokenRaw == "" { + return fmt.Errorf("--burn-token argument not specified") + } else if !common.IsHexAddress(burnTokenRaw) { + return fmt.Errorf("--burn-token argument is not a valid Ethereum address") + } + burnToken = common.HexToAddress(burnTokenRaw) + + var destinationCallerIntermediate []byte + + var destinationCallerIntermediateHexDecodeErr error + destinationCallerIntermediate, destinationCallerIntermediateHexDecodeErr = hex.DecodeString(destinationCallerRaw) + if destinationCallerIntermediateHexDecodeErr != nil { + return destinationCallerIntermediateHexDecodeErr + } + + copy(destinationCaller[:], destinationCallerIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + abi, err := TokenMessengerMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "depositForBurnWithCaller" + if safeFunction != "" { + methodName = safeFunction + } + + txCalldata, err := abi.Pack( + methodName, + amount, + destinationDomain, + mintRecipient, + burnToken, + destinationCaller, + ) + + if err != nil { + return err + } + + if calldata { + txCalldataHex := hex.EncodeToString(txCalldata) + cmd.Println(txCalldataHex) + return nil + } + + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := TokenMessengerTransactorSession{ + Contract: &contract.TokenMessengerTransactor, + TransactOpts: *transactionOpts, + } + + if safeAddress != "" { + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, txCalldata, value, safeApi, SafeOperationType(safeOperationType), safeNonce) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.DepositForBurnWithCaller( + + amount, + destinationDomain, + mintRecipient, + burnToken, + destinationCaller, + ) + if err != nil { + return err + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().StringVar(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") + cmd.Flags().BoolVar(&calldata, "calldata", false, "Set this flag if want to return the calldata instead of sending the transaction") + + cmd.Flags().StringVar(&amountRaw, "amount", "", "amount argument") + cmd.Flags().Uint32Var(&destinationDomain, "destination-domain", 0, "destination-domain argument") + cmd.Flags().StringVar(&mintRecipientRaw, "mint-recipient", "", "mint-recipient argument ([32]byte)") + cmd.Flags().StringVar(&burnTokenRaw, "burn-token", "", "burn-token argument (common.Address)") + cmd.Flags().StringVar(&destinationCallerRaw, "destination-caller", "", "destination-caller argument ([32]byte)") + + return cmd +} +func CreateHandleReceiveMessageCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 + var safeNonce *big.Int + var calldata bool + + var remoteDomain uint32 + + var sender [32]byte + var senderRaw string + var messageBody []byte + var messageBodyRaw string + + cmd := &cobra.Command{ + Use: "handle-receive-message", + Short: "Execute the HandleReceiveMessage method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if !calldata { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } + } + + var senderIntermediate []byte + + var senderIntermediateHexDecodeErr error + senderIntermediate, senderIntermediateHexDecodeErr = hex.DecodeString(senderRaw) + if senderIntermediateHexDecodeErr != nil { + return senderIntermediateHexDecodeErr + } + + copy(sender[:], senderIntermediate) + + var messageBodyIntermediate []byte + + var messageBodyIntermediateHexDecodeErr error + messageBodyIntermediate, messageBodyIntermediateHexDecodeErr = hex.DecodeString(messageBodyRaw) + if messageBodyIntermediateHexDecodeErr != nil { + return messageBodyIntermediateHexDecodeErr + } + + copy(messageBody[:], messageBodyIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + abi, err := TokenMessengerMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "handleReceiveMessage" + if safeFunction != "" { + methodName = safeFunction + } + + txCalldata, err := abi.Pack( + methodName, + remoteDomain, + sender, + messageBody, + ) + + if err != nil { + return err + } + + if calldata { + txCalldataHex := hex.EncodeToString(txCalldata) + cmd.Println(txCalldataHex) + return nil + } + + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := TokenMessengerTransactorSession{ + Contract: &contract.TokenMessengerTransactor, + TransactOpts: *transactionOpts, + } + + if safeAddress != "" { + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, txCalldata, value, safeApi, SafeOperationType(safeOperationType), safeNonce) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.HandleReceiveMessage( + + remoteDomain, + sender, + messageBody, + ) + if err != nil { + return err + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().StringVar(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") + cmd.Flags().BoolVar(&calldata, "calldata", false, "Set this flag if want to return the calldata instead of sending the transaction") + + cmd.Flags().Uint32Var(&remoteDomain, "remote-domain", 0, "remote-domain argument") + cmd.Flags().StringVar(&senderRaw, "sender", "", "sender argument ([32]byte)") + cmd.Flags().StringVar(&messageBodyRaw, "message-body", "", "message-body argument ([]byte)") + + return cmd +} +func CreateRemoveLocalMinterCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 + var safeNonce *big.Int + var calldata bool + + cmd := &cobra.Command{ + Use: "remove-local-minter", + Short: "Execute the RemoveLocalMinter method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if !calldata { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + abi, err := TokenMessengerMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "removeLocalMinter" + if safeFunction != "" { + methodName = safeFunction + } + + txCalldata, err := abi.Pack( + methodName, + ) + + if err != nil { + return err + } + + if calldata { + txCalldataHex := hex.EncodeToString(txCalldata) + cmd.Println(txCalldataHex) + return nil + } + + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := TokenMessengerTransactorSession{ + Contract: &contract.TokenMessengerTransactor, + TransactOpts: *transactionOpts, + } + + if safeAddress != "" { + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, txCalldata, value, safeApi, SafeOperationType(safeOperationType), safeNonce) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.RemoveLocalMinter() + if err != nil { + return err + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().StringVar(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") + cmd.Flags().BoolVar(&calldata, "calldata", false, "Set this flag if want to return the calldata instead of sending the transaction") + + return cmd +} +func CreateRemoveRemoteTokenMessengerCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 + var safeNonce *big.Int + var calldata bool + + var domain uint32 + + cmd := &cobra.Command{ + Use: "remove-remote-token-messenger", + Short: "Execute the RemoveRemoteTokenMessenger method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if !calldata { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + abi, err := TokenMessengerMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "removeRemoteTokenMessenger" + if safeFunction != "" { + methodName = safeFunction + } + + txCalldata, err := abi.Pack( + methodName, + domain, + ) + + if err != nil { + return err + } + + if calldata { + txCalldataHex := hex.EncodeToString(txCalldata) + cmd.Println(txCalldataHex) + return nil + } + + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := TokenMessengerTransactorSession{ + Contract: &contract.TokenMessengerTransactor, + TransactOpts: *transactionOpts, + } + + if safeAddress != "" { + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, txCalldata, value, safeApi, SafeOperationType(safeOperationType), safeNonce) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.RemoveRemoteTokenMessenger( + + domain, + ) + if err != nil { + return err + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().StringVar(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") + cmd.Flags().BoolVar(&calldata, "calldata", false, "Set this flag if want to return the calldata instead of sending the transaction") + + cmd.Flags().Uint32Var(&domain, "domain", 0, "domain argument") + + return cmd +} +func CreateReplaceDepositForBurnCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 + var safeNonce *big.Int + var calldata bool + + var originalMessage []byte + var originalMessageRaw string + var originalAttestation []byte + var originalAttestationRaw string + var newDestinationCaller [32]byte + var newDestinationCallerRaw string + var newMintRecipient [32]byte + var newMintRecipientRaw string + + cmd := &cobra.Command{ + Use: "replace-deposit-for-burn", + Short: "Execute the ReplaceDepositForBurn method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if !calldata { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } + } + + var originalMessageIntermediate []byte + + var originalMessageIntermediateHexDecodeErr error + originalMessageIntermediate, originalMessageIntermediateHexDecodeErr = hex.DecodeString(originalMessageRaw) + if originalMessageIntermediateHexDecodeErr != nil { + return originalMessageIntermediateHexDecodeErr + } + + copy(originalMessage[:], originalMessageIntermediate) + + var originalAttestationIntermediate []byte + + var originalAttestationIntermediateHexDecodeErr error + originalAttestationIntermediate, originalAttestationIntermediateHexDecodeErr = hex.DecodeString(originalAttestationRaw) + if originalAttestationIntermediateHexDecodeErr != nil { + return originalAttestationIntermediateHexDecodeErr + } + + copy(originalAttestation[:], originalAttestationIntermediate) + + var newDestinationCallerIntermediate []byte + + var newDestinationCallerIntermediateHexDecodeErr error + newDestinationCallerIntermediate, newDestinationCallerIntermediateHexDecodeErr = hex.DecodeString(newDestinationCallerRaw) + if newDestinationCallerIntermediateHexDecodeErr != nil { + return newDestinationCallerIntermediateHexDecodeErr + } + + copy(newDestinationCaller[:], newDestinationCallerIntermediate) + + var newMintRecipientIntermediate []byte + + var newMintRecipientIntermediateHexDecodeErr error + newMintRecipientIntermediate, newMintRecipientIntermediateHexDecodeErr = hex.DecodeString(newMintRecipientRaw) + if newMintRecipientIntermediateHexDecodeErr != nil { + return newMintRecipientIntermediateHexDecodeErr + } + + copy(newMintRecipient[:], newMintRecipientIntermediate) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + abi, err := TokenMessengerMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "replaceDepositForBurn" + if safeFunction != "" { + methodName = safeFunction + } + + txCalldata, err := abi.Pack( + methodName, + originalMessage, + originalAttestation, + newDestinationCaller, + newMintRecipient, + ) + + if err != nil { + return err + } + + if calldata { + txCalldataHex := hex.EncodeToString(txCalldata) + cmd.Println(txCalldataHex) + return nil + } + + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := TokenMessengerTransactorSession{ + Contract: &contract.TokenMessengerTransactor, + TransactOpts: *transactionOpts, + } + + if safeAddress != "" { + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, txCalldata, value, safeApi, SafeOperationType(safeOperationType), safeNonce) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.ReplaceDepositForBurn( + + originalMessage, + originalAttestation, + newDestinationCaller, + newMintRecipient, + ) + if err != nil { + return err + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().StringVar(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") + cmd.Flags().BoolVar(&calldata, "calldata", false, "Set this flag if want to return the calldata instead of sending the transaction") + + cmd.Flags().StringVar(&originalMessageRaw, "original-message", "", "original-message argument ([]byte)") + cmd.Flags().StringVar(&originalAttestationRaw, "original-attestation", "", "original-attestation argument ([]byte)") + cmd.Flags().StringVar(&newDestinationCallerRaw, "new-destination-caller", "", "new-destination-caller argument ([32]byte)") + cmd.Flags().StringVar(&newMintRecipientRaw, "new-mint-recipient", "", "new-mint-recipient argument ([32]byte)") + + return cmd +} +func CreateRescueErc20Command() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 + var safeNonce *big.Int + var calldata bool + + var tokenContract common.Address + var tokenContractRaw string + var to0 common.Address + var to0Raw string + var amount *big.Int + var amountRaw string + + cmd := &cobra.Command{ + Use: "rescue-erc-20", + Short: "Execute the RescueERC20 method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if !calldata { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } + } + + if tokenContractRaw == "" { + return fmt.Errorf("--token-contract argument not specified") + } else if !common.IsHexAddress(tokenContractRaw) { + return fmt.Errorf("--token-contract argument is not a valid Ethereum address") + } + tokenContract = common.HexToAddress(tokenContractRaw) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) + + if amountRaw == "" { + return fmt.Errorf("--amount argument not specified") + } + amount = new(big.Int) + amount.SetString(amountRaw, 0) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + abi, err := TokenMessengerMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "rescueErc20" + if safeFunction != "" { + methodName = safeFunction + } + + txCalldata, err := abi.Pack( + methodName, + tokenContract, + to0, + amount, + ) + + if err != nil { + return err + } + + if calldata { + txCalldataHex := hex.EncodeToString(txCalldata) + cmd.Println(txCalldataHex) + return nil + } + + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := TokenMessengerTransactorSession{ + Contract: &contract.TokenMessengerTransactor, + TransactOpts: *transactionOpts, + } + + if safeAddress != "" { + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, txCalldata, value, safeApi, SafeOperationType(safeOperationType), safeNonce) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.RescueERC20( + + tokenContract, + to0, + amount, + ) + if err != nil { + return err + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().StringVar(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") + cmd.Flags().BoolVar(&calldata, "calldata", false, "Set this flag if want to return the calldata instead of sending the transaction") + + cmd.Flags().StringVar(&tokenContractRaw, "token-contract", "", "token-contract argument (common.Address)") + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument (common.Address)") + cmd.Flags().StringVar(&amountRaw, "amount", "", "amount argument") + + return cmd +} +func CreateTransferOwnershipCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 + var safeNonce *big.Int + var calldata bool + + var newOwner common.Address + var newOwnerRaw string + + cmd := &cobra.Command{ + Use: "transfer-ownership", + Short: "Execute the TransferOwnership method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if !calldata { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } + } + + if newOwnerRaw == "" { + return fmt.Errorf("--new-owner argument not specified") + } else if !common.IsHexAddress(newOwnerRaw) { + return fmt.Errorf("--new-owner argument is not a valid Ethereum address") + } + newOwner = common.HexToAddress(newOwnerRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + abi, err := TokenMessengerMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "transferOwnership" + if safeFunction != "" { + methodName = safeFunction + } + + txCalldata, err := abi.Pack( + methodName, + newOwner, + ) + + if err != nil { + return err + } + + if calldata { + txCalldataHex := hex.EncodeToString(txCalldata) + cmd.Println(txCalldataHex) + return nil + } + + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := TokenMessengerTransactorSession{ + Contract: &contract.TokenMessengerTransactor, + TransactOpts: *transactionOpts, + } + + if safeAddress != "" { + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, txCalldata, value, safeApi, SafeOperationType(safeOperationType), safeNonce) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.TransferOwnership( + + newOwner, + ) + if err != nil { + return err + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().StringVar(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") + cmd.Flags().BoolVar(&calldata, "calldata", false, "Set this flag if want to return the calldata instead of sending the transaction") + + cmd.Flags().StringVar(&newOwnerRaw, "new-owner", "", "new-owner argument (common.Address)") + + return cmd +} +func CreateUpdateRescuerCommand() *cobra.Command { + var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw, safeFunction, safeNonceRaw string + var gasLimit uint64 + var simulate bool + var timeout uint + var contractAddress common.Address + var safeAddress, safeApi string + var safeOperationType uint8 + var safeNonce *big.Int + var calldata bool + + var newRescuer common.Address + var newRescuerRaw string + + cmd := &cobra.Command{ + Use: "update-rescuer", + Short: "Execute the UpdateRescuer method on a TokenMessenger contract", + PreRunE: func(cmd *cobra.Command, args []string) error { + if !calldata { + if contractAddressRaw == "" { + return fmt.Errorf("--contract not specified") + } else if !common.IsHexAddress(contractAddressRaw) { + return fmt.Errorf("--contract is not a valid Ethereum address") + } + contractAddress = common.HexToAddress(contractAddressRaw) + + if keyfile == "" { + return fmt.Errorf("--keystore not specified (this should be a path to an Ethereum account keystore file)") + } + + if rpc == "" { + return fmt.Errorf("--rpc not specified (this should be a URL to an Ethereum JSONRPC API)") + } + } + + if safeAddress != "" { + if !common.IsHexAddress(safeAddress) { + return fmt.Errorf("--safe is not a valid Ethereum address") + } + if safeApi == "" { + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + safeApi = fmt.Sprintf("https://safe-client.safe.global/v1/chains/%s/transactions/%s/propose", chainID.String(), safeAddress) + fmt.Println("--safe-api not specified, using default (", safeApi, ")") + } + + if SafeOperationType(safeOperationType).String() == "Unknown" { + return fmt.Errorf("--safe-operation must be 0 (Call) or 1 (DelegateCall)") + } + + if safeNonceRaw == "" { + fmt.Println("--safe-nonce not specified, fetching nonce from Safe contract") + } else { + safeNonce = new(big.Int) + _, ok := safeNonce.SetString(safeNonceRaw, 0) + if !ok { + return fmt.Errorf("--safe-nonce is not a valid big integer") + } + } + } + + if newRescuerRaw == "" { + return fmt.Errorf("--new-rescuer argument not specified") + } else if !common.IsHexAddress(newRescuerRaw) { + return fmt.Errorf("--new-rescuer argument is not a valid Ethereum address") + } + newRescuer = common.HexToAddress(newRescuerRaw) + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + abi, err := TokenMessengerMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + // Generate transaction data (override method name if safe function is specified) + methodName := "updateRescuer" + if safeFunction != "" { + methodName = safeFunction + } + + txCalldata, err := abi.Pack( + methodName, + newRescuer, + ) + + if err != nil { + return err + } + + if calldata { + txCalldataHex := hex.EncodeToString(txCalldata) + cmd.Println(txCalldataHex) + return nil + } + + client, clientErr := NewClient(rpc) + if clientErr != nil { + return clientErr + } + + key, keyErr := KeyFromFile(keyfile, password) + if keyErr != nil { + return keyErr + } + + chainIDCtx, cancelChainIDCtx := NewChainContext(timeout) + defer cancelChainIDCtx() + chainID, chainIDErr := client.ChainID(chainIDCtx) + if chainIDErr != nil { + return chainIDErr + } + + transactionOpts, transactionOptsErr := bind.NewKeyedTransactorWithChainID(key.PrivateKey, chainID) + if transactionOptsErr != nil { + return transactionOptsErr + } + + SetTransactionParametersFromArgs(transactionOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, gasLimit, simulate) + + contract, contractErr := NewTokenMessenger(contractAddress, client) + if contractErr != nil { + return contractErr + } + + session := TokenMessengerTransactorSession{ + Contract: &contract.TokenMessengerTransactor, + TransactOpts: *transactionOpts, + } + + if safeAddress != "" { + // Create Safe proposal for transaction + value := transactionOpts.Value + if value == nil { + value = big.NewInt(0) + } + + err = CreateSafeProposal(client, key, common.HexToAddress(safeAddress), contractAddress, txCalldata, value, safeApi, SafeOperationType(safeOperationType), safeNonce) + if err != nil { + return fmt.Errorf("failed to create Safe proposal: %v", err) + } + + return nil + } + + transaction, err := session.UpdateRescuer( + + newRescuer, + ) + if err != nil { + return err + } + + cmd.Printf("Transaction hash: %s\n", transaction.Hash().Hex()) + if transactionOpts.NoSend { + estimationMessage := ethereum.CallMsg{ + From: transactionOpts.From, + To: &contractAddress, + Data: transaction.Data(), + } + + gasEstimationCtx, cancelGasEstimationCtx := NewChainContext(timeout) + defer cancelGasEstimationCtx() + + gasEstimate, gasEstimateErr := client.EstimateGas(gasEstimationCtx, estimationMessage) + if gasEstimateErr != nil { + return gasEstimateErr + } + + transactionBinary, transactionBinaryErr := transaction.MarshalBinary() + if transactionBinaryErr != nil { + return transactionBinaryErr + } + transactionBinaryHex := hex.EncodeToString(transactionBinary) + + cmd.Printf("Transaction: %s\nEstimated gas: %d\n", transactionBinaryHex, gasEstimate) + } else { + cmd.Println("Transaction submitted") + } + + return nil + }, + } + + cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") + cmd.Flags().StringVar(&keyfile, "keyfile", "", "Path to the keystore file to use for the transaction") + cmd.Flags().StringVar(&password, "password", "", "Password to use to unlock the keystore (if not specified, you will be prompted for the password when the command executes)") + cmd.Flags().StringVar(&nonce, "nonce", "", "Nonce to use for the transaction") + cmd.Flags().StringVar(&value, "value", "", "Value to send with the transaction") + cmd.Flags().StringVar(&gasPrice, "gas-price", "", "Gas price to use for the transaction") + cmd.Flags().StringVar(&maxFeePerGas, "max-fee-per-gas", "", "Maximum fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().StringVar(&maxPriorityFeePerGas, "max-priority-fee-per-gas", "", "Maximum priority fee per gas to use for the (EIP-1559) transaction") + cmd.Flags().Uint64Var(&gasLimit, "gas-limit", 0, "Gas limit for the transaction") + cmd.Flags().BoolVar(&simulate, "simulate", false, "Simulate the transaction without sending it") + cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") + cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") + cmd.Flags().StringVar(&safeAddress, "safe", "", "Address of the Safe contract") + cmd.Flags().StringVar(&safeApi, "safe-api", "", "Safe API for the Safe Transaction Service (optional)") + cmd.Flags().Uint8Var(&safeOperationType, "safe-operation", 0, "Safe operation type: 0 (Call) or 1 (DelegateCall)") + cmd.Flags().StringVar(&safeFunction, "safe-function", "", "Safe function overrider to use for the transaction (optional)") + cmd.Flags().StringVar(&safeNonceRaw, "safe-nonce", "", "Safe nonce overrider for the transaction (optional)") + cmd.Flags().BoolVar(&calldata, "calldata", false, "Set this flag if want to return the calldata instead of sending the transaction") + + cmd.Flags().StringVar(&newRescuerRaw, "new-rescuer", "", "new-rescuer argument (common.Address)") + + return cmd +} + +var ErrNoRPCURL error = errors.New("no RPC URL provided -- please pass an RPC URL from the command line or set the TOKEN_MESSENGER_RPC_URL environment variable") + +// Generates an Ethereum client to the JSONRPC API at the given URL. If rpcURL is empty, then it +// attempts to read the RPC URL from the TOKEN_MESSENGER_RPC_URL environment variable. If that is empty, +// too, then it returns an error. +func NewClient(rpcURL string) (*ethclient.Client, error) { + if rpcURL == "" { + rpcURL = os.Getenv("TOKEN_MESSENGER_RPC_URL") + } + + if rpcURL == "" { + return nil, ErrNoRPCURL + } + + client, err := ethclient.Dial(rpcURL) + return client, err +} + +// Creates a new context to be used when interacting with the chain client. +func NewChainContext(timeout uint) (context.Context, context.CancelFunc) { + baseCtx := context.Background() + parsedTimeout := time.Duration(timeout) * time.Second + ctx, cancel := context.WithTimeout(baseCtx, parsedTimeout) + return ctx, cancel +} + +// Unlocks a key from a keystore (byte contents of a keystore file) with the given password. +func UnlockKeystore(keystoreData []byte, password string) (*keystore.Key, error) { + key, err := keystore.DecryptKey(keystoreData, password) + return key, err +} + +// Loads a key from file, prompting the user for the password if it is not provided as a function argument. +func KeyFromFile(keystoreFile string, password string) (*keystore.Key, error) { + var emptyKey *keystore.Key + keystoreContent, readErr := os.ReadFile(keystoreFile) + if readErr != nil { + return emptyKey, readErr + } + + // If password is "", prompt user for password. + if password == "" { + fmt.Printf("Please provide a password for keystore (%s): ", keystoreFile) + passwordRaw, inputErr := term.ReadPassword(int(os.Stdin.Fd())) + if inputErr != nil { + return emptyKey, fmt.Errorf("error reading password: %s", inputErr.Error()) + } + fmt.Print("\n") + password = string(passwordRaw) + } + + key, err := UnlockKeystore(keystoreContent, password) + return key, err +} + +// This method is used to set the parameters on a view call from command line arguments (represented mostly as +// strings). +func SetCallParametersFromArgs(opts *bind.CallOpts, pending bool, fromAddress, blockNumber string) { + if pending { + opts.Pending = true + } + + if fromAddress != "" { + opts.From = common.HexToAddress(fromAddress) + } + + if blockNumber != "" { + opts.BlockNumber = new(big.Int) + opts.BlockNumber.SetString(blockNumber, 0) + } +} + +// This method is used to set the parameters on a transaction from command line arguments (represented mostly as +// strings). +func SetTransactionParametersFromArgs(opts *bind.TransactOpts, nonce, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas string, gasLimit uint64, noSend bool) { + if nonce != "" { + opts.Nonce = new(big.Int) + opts.Nonce.SetString(nonce, 0) + } + + if value != "" { + opts.Value = new(big.Int) + opts.Value.SetString(value, 0) + } + + if gasPrice != "" { + opts.GasPrice = new(big.Int) + opts.GasPrice.SetString(gasPrice, 0) + } + + if maxFeePerGas != "" { + opts.GasFeeCap = new(big.Int) + opts.GasFeeCap.SetString(maxFeePerGas, 0) + } + + if maxPriorityFeePerGas != "" { + opts.GasTipCap = new(big.Int) + opts.GasTipCap.SetString(maxPriorityFeePerGas, 0) + } + + if gasLimit != 0 { + opts.GasLimit = gasLimit + } + + opts.NoSend = noSend +} + +func CreateTokenMessengerCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "token-messenger", + Short: "Interact with the TokenMessenger contract", + Run: func(cmd *cobra.Command, args []string) { + cmd.Help() + }, + } + + cmd.SetOut(os.Stdout) + + DeployGroup := &cobra.Group{ + ID: "deploy", Title: "Commands which deploy contracts", + } + cmd.AddGroup(DeployGroup) + ViewGroup := &cobra.Group{ + ID: "view", Title: "Commands which view contract state", + } + TransactGroup := &cobra.Group{ + ID: "transact", Title: "Commands which submit transactions", + } + cmd.AddGroup(ViewGroup, TransactGroup) + + cmdDeployTokenMessenger := CreateTokenMessengerDeploymentCommand() + cmdDeployTokenMessenger.GroupID = DeployGroup.ID + cmd.AddCommand(cmdDeployTokenMessenger) + + cmdViewLocalMessageTransmitter := CreateLocalMessageTransmitterCommand() + cmdViewLocalMessageTransmitter.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewLocalMessageTransmitter) + cmdViewLocalMinter := CreateLocalMinterCommand() + cmdViewLocalMinter.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewLocalMinter) + cmdViewMessageBodyVersion := CreateMessageBodyVersionCommand() + cmdViewMessageBodyVersion.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewMessageBodyVersion) + cmdViewOwner := CreateOwnerCommand() + cmdViewOwner.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewOwner) + cmdViewPendingOwner := CreatePendingOwnerCommand() + cmdViewPendingOwner.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewPendingOwner) + cmdViewRemoteTokenMessengers := CreateRemoteTokenMessengersCommand() + cmdViewRemoteTokenMessengers.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewRemoteTokenMessengers) + cmdViewRescuer := CreateRescuerCommand() + cmdViewRescuer.GroupID = ViewGroup.ID + cmd.AddCommand(cmdViewRescuer) + + cmdTransactAcceptOwnership := CreateAcceptOwnershipCommand() + cmdTransactAcceptOwnership.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactAcceptOwnership) + cmdTransactAddLocalMinter := CreateAddLocalMinterCommand() + cmdTransactAddLocalMinter.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactAddLocalMinter) + cmdTransactAddRemoteTokenMessenger := CreateAddRemoteTokenMessengerCommand() + cmdTransactAddRemoteTokenMessenger.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactAddRemoteTokenMessenger) + cmdTransactDepositForBurn := CreateDepositForBurnCommand() + cmdTransactDepositForBurn.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactDepositForBurn) + cmdTransactDepositForBurnWithCaller := CreateDepositForBurnWithCallerCommand() + cmdTransactDepositForBurnWithCaller.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactDepositForBurnWithCaller) + cmdTransactHandleReceiveMessage := CreateHandleReceiveMessageCommand() + cmdTransactHandleReceiveMessage.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactHandleReceiveMessage) + cmdTransactRemoveLocalMinter := CreateRemoveLocalMinterCommand() + cmdTransactRemoveLocalMinter.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactRemoveLocalMinter) + cmdTransactRemoveRemoteTokenMessenger := CreateRemoveRemoteTokenMessengerCommand() + cmdTransactRemoveRemoteTokenMessenger.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactRemoveRemoteTokenMessenger) + cmdTransactReplaceDepositForBurn := CreateReplaceDepositForBurnCommand() + cmdTransactReplaceDepositForBurn.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactReplaceDepositForBurn) + cmdTransactRescueERC20 := CreateRescueErc20Command() + cmdTransactRescueERC20.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactRescueERC20) + cmdTransactTransferOwnership := CreateTransferOwnershipCommand() + cmdTransactTransferOwnership.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactTransferOwnership) + cmdTransactUpdateRescuer := CreateUpdateRescuerCommand() + cmdTransactUpdateRescuer.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactUpdateRescuer) + + return cmd +} + +// SafeOperationType represents the type of operation for a Safe transaction +type SafeOperationType uint8 + +const ( + Call SafeOperationType = 0 + DelegateCall SafeOperationType = 1 +) + +// String returns the string representation of the SafeOperationType +func (o SafeOperationType) String() string { + switch o { + case Call: + return "Call" + case DelegateCall: + return "DelegateCall" + default: + return "Unknown" + } +} + +// SafeTransactionData represents the data for a Safe transaction +type SafeTransactionData struct { + To string `json:"to"` + Value string `json:"value"` + Data string `json:"data"` + Operation SafeOperationType `json:"operation"` + SafeTxGas uint64 `json:"safeTxGas"` + BaseGas uint64 `json:"baseGas"` + GasPrice string `json:"gasPrice"` + GasToken string `json:"gasToken"` + RefundReceiver string `json:"refundReceiver"` + Nonce *big.Int `json:"nonce"` + SafeTxHash string `json:"safeTxHash"` + Sender string `json:"sender"` + Signature string `json:"signature"` + Origin string `json:"origin"` +} + +const ( + NativeTokenAddress = "0x0000000000000000000000000000000000000000" +) + +func DeployWithSafe(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, factoryAddress common.Address, value *big.Int, safeApi string, deployBytecode []byte, safeOperationType SafeOperationType, salt [32]byte, safeNonce *big.Int) error { + abi, err := CreateCall.CreateCallMetaData.GetAbi() + if err != nil { + return fmt.Errorf("failed to get ABI: %v", err) + } + + safeCreateCallTxData, err := abi.Pack("performCreate2", value, deployBytecode, salt) + if err != nil { + return fmt.Errorf("failed to pack performCreate2 transaction: %v", err) + } + + return CreateSafeProposal(client, key, safeAddress, factoryAddress, safeCreateCallTxData, value, safeApi, SafeOperationType(safeOperationType), safeNonce) +} + +func PredictDeploymentAddressSafe(from common.Address, salt [32]byte, deployBytecode []byte) (common.Address, error) { + // Calculate the hash of the init code (deployment bytecode) + initCodeHash := crypto.Keccak256(deployBytecode) + + // Calculate the CREATE2 address + deployedAddress := crypto.CreateAddress2(from, salt, initCodeHash) + + return deployedAddress, nil +} + +func CreateSafeProposal(client *ethclient.Client, key *keystore.Key, safeAddress common.Address, to common.Address, data []byte, value *big.Int, safeApi string, safeOperationType SafeOperationType, safeNonce *big.Int) error { + chainID, err := client.ChainID(context.Background()) + if err != nil { + return fmt.Errorf("failed to get chain ID: %v", err) + } + + // Create a new instance of the GnosisSafe contract + safeInstance, err := GnosisSafe.NewGnosisSafe(safeAddress, client) + if err != nil { + return fmt.Errorf("failed to create GnosisSafe instance: %v", err) + } + + nonce := safeNonce + if safeNonce == nil { + // Fetch the current nonce from the Safe contract + fetchedNonce, err := safeInstance.Nonce(&bind.CallOpts{}) + if err != nil { + return fmt.Errorf("failed to fetch nonce from Safe contract: %v", err) + } + nonce = fetchedNonce + } else { + nonce = safeNonce + } + + safeTransactionData := SafeTransactionData{ + To: to.Hex(), + Value: value.String(), + Data: common.Bytes2Hex(data), + Operation: safeOperationType, + SafeTxGas: 0, + BaseGas: 0, + GasPrice: "0", + GasToken: NativeTokenAddress, + RefundReceiver: NativeTokenAddress, + Nonce: nonce, + } + + // Calculate SafeTxHash + safeTxHash, err := CalculateSafeTxHash(safeAddress, safeTransactionData, chainID) + if err != nil { + return fmt.Errorf("failed to calculate SafeTxHash: %v", err) + } + + // Sign the SafeTxHash + signature, err := crypto.Sign(safeTxHash.Bytes(), key.PrivateKey) + if err != nil { + return fmt.Errorf("failed to sign SafeTxHash: %v", err) + } + + // Adjust V value for Ethereum's replay protection + signature[64] += 27 + + // Convert signature to hex + senderSignature := "0x" + common.Bytes2Hex(signature) + + // Prepare the request body + requestBody := map[string]interface{}{ + "to": safeTransactionData.To, + "value": safeTransactionData.Value, + "data": "0x" + safeTransactionData.Data, + "operation": int(safeTransactionData.Operation), + "safeTxGas": fmt.Sprintf("%d", safeTransactionData.SafeTxGas), + "baseGas": fmt.Sprintf("%d", safeTransactionData.BaseGas), + "gasPrice": safeTransactionData.GasPrice, + "gasToken": safeTransactionData.GasToken, + "refundReceiver": safeTransactionData.RefundReceiver, + "nonce": fmt.Sprintf("%d", safeTransactionData.Nonce), + "safeTxHash": safeTxHash.Hex(), + "sender": key.Address.Hex(), + "signature": senderSignature, + "origin": fmt.Sprintf("{\"url\":\"%s\",\"name\":\"TokenSender Deployment\"}", safeApi), + } + + // Marshal the request body to JSON + jsonBody, err := json.Marshal(requestBody) + if err != nil { + return fmt.Errorf("failed to marshal request body: %v", err) + } + + // Send the request to the Safe Transaction Service + req, err := http.NewRequest("POST", safeApi, bytes.NewBuffer(jsonBody)) + if err != nil { + return fmt.Errorf("failed to create request: %v", err) + } + + req.Header.Set("Content-Type", "application/json") + + httpClient := &http.Client{} + resp, err := httpClient.Do(req) + if err != nil { + return fmt.Errorf("failed to send request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated { + return fmt.Errorf("unexpected status code: %d", resp.StatusCode) + } + + fmt.Println("Safe proposal created successfully") + return nil +} + +func CalculateSafeTxHash(safeAddress common.Address, txData SafeTransactionData, chainID *big.Int) (common.Hash, error) { + domainSeparator := apitypes.TypedDataDomain{ + ChainId: (*math.HexOrDecimal256)(chainID), + VerifyingContract: safeAddress.Hex(), + } + + typedData := apitypes.TypedData{ + Types: apitypes.Types{ + "EIP712Domain": []apitypes.Type{ + {Name: "chainId", Type: "uint256"}, + {Name: "verifyingContract", Type: "address"}, + }, + "SafeTx": []apitypes.Type{ + {Name: "to", Type: "address"}, + {Name: "value", Type: "uint256"}, + {Name: "data", Type: "bytes"}, + {Name: "operation", Type: "uint8"}, + {Name: "safeTxGas", Type: "uint256"}, + {Name: "baseGas", Type: "uint256"}, + {Name: "gasPrice", Type: "uint256"}, + {Name: "gasToken", Type: "address"}, + {Name: "refundReceiver", Type: "address"}, + {Name: "nonce", Type: "uint256"}, + }, + }, + Domain: domainSeparator, + PrimaryType: "SafeTx", + Message: apitypes.TypedDataMessage{ + "to": txData.To, + "value": txData.Value, + "data": "0x" + txData.Data, + "operation": fmt.Sprintf("%d", txData.Operation), + "safeTxGas": fmt.Sprintf("%d", txData.SafeTxGas), + "baseGas": fmt.Sprintf("%d", txData.BaseGas), + "gasPrice": txData.GasPrice, + "gasToken": txData.GasToken, + "refundReceiver": txData.RefundReceiver, + "nonce": fmt.Sprintf("%d", txData.Nonce), + }, + } + + typedDataHash, _, err := apitypes.TypedDataAndHash(typedData) + if err != nil { + return common.Hash{}, fmt.Errorf("failed to hash typed data: %v", err) + } + + return common.BytesToHash(typedDataHash), nil +} diff --git a/cmd/arbitrum/aribtrum.go b/cmd/arbitrum/aribtrum.go index 8f77c8e..54e180e 100644 --- a/cmd/arbitrum/aribtrum.go +++ b/cmd/arbitrum/aribtrum.go @@ -12,18 +12,6 @@ import ( "github.com/spf13/cobra" ) -func CreateBifrostCommand() *cobra.Command { - bifrostCmd := &cobra.Command{ - Use: "bifrost", - Short: "Bifrost CLI", - Long: `Bifrost CLI`, - } - - bifrostCmd.AddCommand(CreateArbitrumCommand()) - - return bifrostCmd -} - func CreateArbitrumCommand() *cobra.Command { var keyFile, password, l1Rpc, l2Rpc, inboxRaw, toRaw, l2CallValueRaw, l2CalldataRaw, safeAddressRaw, safeApi, safeNonceRaw string var inboxAddress, to, safeAddress common.Address diff --git a/cmd/cctp/cctp.go b/cmd/cctp/cctp.go new file mode 100644 index 0000000..2347adb --- /dev/null +++ b/cmd/cctp/cctp.go @@ -0,0 +1,150 @@ +package cctp + +import ( + "errors" + "fmt" + "math/big" + + "github.com/G7DAO/bifrost/bindings/TokenMessenger" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/spf13/cobra" +) + +type ChainDomain uint32 + +const ( + ChainDomainEthereum = 0 + ChainDomainArbitrum = 3 +) + +// String returns the string representation of the ChainDomain +func (o ChainDomain) String() string { + switch o { + case ChainDomainEthereum: + return "Ethereum" + case ChainDomainArbitrum: + return "Arbitrum" + default: + return "Unknown" + } +} + +func cctpBridge(key *keystore.Key, client *ethclient.Client, recipient common.Address, domain uint32, amount *big.Int, token common.Address, contractAddress common.Address) error { + mintRecipient, err := ParseMintRecipientFrom20BytesTo32Bytes(recipient) + if err != nil { + return err + } + + abi, err := TokenMessenger.TokenMessengerMetaData.GetAbi() + if err != nil { + return err + } + + packed, err := abi.Pack("depositForBurn", amount, domain, mintRecipient, token) + if err != nil { + return err + } + + tx, err := SendTransaction(client, key, packed, contractAddress.Hex(), big.NewInt(0)) + if err != nil { + return err + } + + fmt.Println("Transaction hash:", tx.Hash().Hex()) + return nil +} + +// CCTP uses 32 bytes addresses, while EVEM uses 20 bytes addresses +// const mintRecipient = utils.hexlify(utils.zeroPad(recipient, 32)) as Address +func ParseMintRecipientFrom20BytesTo32Bytes(recipient common.Address) ([32]byte, error) { + var mintRecipient [32]byte + + // Validate input length + if len(recipient) != 20 { + return mintRecipient, fmt.Errorf("invalid recipient length: expected 20 bytes, got %d", len(recipient)) + } + + // Copy the 20 bytes to the end of the 32-byte array, leaving the first 12 bytes as zeros + // This is equivalent to zero-padding on the left + copy(mintRecipient[32-20:], recipient.Bytes()) + + return mintRecipient, nil +} + +func CreateCctpCommand() *cobra.Command { + var keyFile, password, rpc, recipientRaw, amountRaw, tokenRaw, contractRaw string + var domain uint32 + var token, recipient, contract common.Address + var amount *big.Int + + cctpCmd := &cobra.Command{ + Use: "cctp", + Short: "Bifrost for CCTP cross-chain messaging protocol", + Long: `Bifrost for CCTP cross-chain messaging protocol`, + + PreRunE: func(cmd *cobra.Command, args []string) error { + + if !common.IsHexAddress(recipientRaw) { + return errors.New("invalid recipient address") + } + recipient = common.HexToAddress(recipientRaw) + + if ChainDomain(domain).String() == "Unknown" { + return errors.New("invalid domain") + } + + if amountRaw == "" { + return errors.New("amount is required") + } else { + var ok bool + amount, ok = new(big.Int).SetString(amountRaw, 10) + if !ok { + return errors.New("invalid amount") + } + } + if tokenRaw == "" { + return errors.New("token is required") + } else { + token = common.HexToAddress(tokenRaw) + } + if contractRaw == "" { + return errors.New("contract is required") + } else { + contract = common.HexToAddress(contractRaw) + } + + if keyFile == "" { + return errors.New("keyfile is required") + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + fmt.Println("Bridging to", recipientRaw) + + key, err := TokenMessenger.KeyFromFile(keyFile, password) + if err != nil { + return err + } + + client, err := ethclient.Dial(rpc) + if err != nil { + return err + } + + return cctpBridge(key, client, recipient, domain, amount, token, contract) + }, + } + + cctpCmd.Flags().StringVar(&password, "password", "", "Password to encrypt accounts with") + cctpCmd.Flags().StringVar(&keyFile, "keyfile", "", "Keyfile to sign transaction with") + cctpCmd.Flags().StringVar(&rpc, "rpc", "", "RPC URL") + cctpCmd.Flags().StringVar(&recipientRaw, "recipient", "", "Recipient address in the destination domain") + cctpCmd.Flags().Uint32Var(&domain, "domain", 0, "Destination domain") + cctpCmd.Flags().StringVar(&amountRaw, "amount", "", "Amount of tokens to send") + cctpCmd.Flags().StringVar(&tokenRaw, "token", "", "Token to send") + cctpCmd.Flags().StringVar(&contractRaw, "contract", "", "Contract to send tokens from") + return cctpCmd +} diff --git a/cmd/cctp/ethereum.go b/cmd/cctp/ethereum.go new file mode 100644 index 0000000..05933a1 --- /dev/null +++ b/cmd/cctp/ethereum.go @@ -0,0 +1,71 @@ +package cctp + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" +) + +// Function to send a transaction +func SendTransaction(client *ethclient.Client, key *keystore.Key, calldata []byte, to string, value *big.Int) (*types.Transaction, error) { + chainID, chainIDErr := client.ChainID(context.Background()) + if chainIDErr != nil { + return nil, chainIDErr + } + + recipientAddress := common.HexToAddress(to) + + callMsg := ethereum.CallMsg{ + From: key.Address, + To: &recipientAddress, + Value: value, + Data: calldata, + } + + gasLimit, gasLimitErr := client.EstimateGas(context.Background(), callMsg) + if gasLimitErr != nil { + return nil, gasLimitErr + } + + baseFee, baseFeeErr := client.SuggestGasPrice(context.Background()) + if baseFeeErr != nil { + return nil, baseFeeErr + } + + gasTipCap, gasTipCapErr := client.SuggestGasTipCap(context.Background()) + if gasTipCapErr != nil { + return nil, gasTipCapErr + } + + nonce, nonceErr := client.PendingNonceAt(context.Background(), key.Address) + if nonceErr != nil { + return nil, nonceErr + } + + rawTransaction := types.NewTx(&types.DynamicFeeTx{ + ChainID: chainID, + Nonce: nonce, + GasTipCap: gasTipCap, + GasFeeCap: baseFee, + Gas: gasLimit, + To: &recipientAddress, + Value: value, + Data: calldata, + }) + + signedTransaction, signedTransactionErr := types.SignTx(rawTransaction, types.NewLondonSigner(chainID), key.PrivateKey) + if signedTransactionErr != nil { + return nil, signedTransactionErr + } + + sendTransactionErr := client.SendTransaction(context.Background(), signedTransaction) + if sendTransactionErr != nil { + return nil, sendTransactionErr + } + return signedTransaction, nil +} diff --git a/cmd/cmd.go b/cmd/cmd.go index cd40f02..e866093 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -4,6 +4,7 @@ import ( "os" arbitrum_bifrost "github.com/G7DAO/bifrost/cmd/arbitrum" + "github.com/G7DAO/bifrost/cmd/cctp" "github.com/G7DAO/bifrost/cmd/version" "github.com/spf13/cobra" ) @@ -22,8 +23,9 @@ func CreateRootCommand() *cobra.Command { versionCmd := CreateVersionCommand() arbitrumCmd := arbitrum_bifrost.CreateArbitrumCommand() + cctpCmd := cctp.CreateCctpCommand() - rootCmd.AddCommand(completionCmd, versionCmd, arbitrumCmd) + rootCmd.AddCommand(completionCmd, versionCmd, arbitrumCmd, cctpCmd) // By default, cobra Command objects write to stderr. We have to forcibly set them to output to // stdout. diff --git a/go.mod b/go.mod index 3515569..ee43122 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.22.0 toolchain go1.22.2 require ( + github.com/G7DAO/seer v0.3.15 github.com/ethereum/go-ethereum v1.14.10 github.com/spf13/cobra v1.8.0 golang.org/x/term v0.20.0 @@ -41,6 +42,5 @@ require ( golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.18.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/go.sum b/go.sum index 417a56d..b038912 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/G7DAO/seer v0.3.15 h1:EO0Q/dD1fSPvQVMpewxFuowI+n95x40j1iJ+sJWrE5M= +github.com/G7DAO/seer v0.3.15/go.mod h1:JVdBWa8ma30x4xCiAVljKczYpl0To7gMWBTFsPSEA/A= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=