From d35b992125190b0b03dc0b1940c26017bcc06fe0 Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Sat, 11 May 2024 19:21:08 +0330 Subject: [PATCH 01/29] =?UTF-8?q?=E2=9C=A8=20feat(signers):=20gather=20all?= =?UTF-8?q?=20signers=20behind=20an=20interface=20and=20write=20first=20im?= =?UTF-8?q?plmnt=20of=20tss=20>>>=20=E2=8F=B0=202d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + cmd/handler/broker.go | 1 + cmd/handler/consumer.go | 1 + cmd/handler/worker.go | 1 + cmd/main.go | 2 + go.mod | 14 +- go.sum | 39 ++++- internal/config/config.go | 5 + internal/config/model.go | 11 ++ internal/consts/channels.go | 1 + internal/consts/errors.go | 1 + internal/consts/opcodes.go | 1 + internal/crypto/bls/bls.go | 32 ++-- internal/crypto/bls/identity.go | 80 ++++++--- internal/crypto/bls/identity_test.go | 77 +++++++++ internal/crypto/ethereum/identity.go | 32 +++- internal/crypto/identity.go | 46 +++-- internal/crypto/tss/identity.go | 158 ++++++++++++++++++ internal/crypto/tss/identity_test.go | 125 ++++++++++++++ internal/model/bls.go | 12 +- internal/repository/postgres/assetprice.go | 3 + internal/repository/postgres/correctness.go | 3 + internal/service/correctness/correctness.go | 30 +--- internal/service/evmlog/evmlog.go | 48 ++---- internal/service/evmlog/process.go | 15 +- internal/service/evmlog/record.go | 2 +- internal/service/pos/eip712.go | 3 +- internal/service/pos/eip712/helper.go | 33 ++++ internal/service/pos/eip712/sign.go | 88 +++++----- internal/service/pos/pos.go | 16 +- internal/service/uniswap/record.go | 4 +- internal/service/uniswap/uniswap.go | 57 +++---- .../transport/client/handler/challenge.go | 20 ++- .../transport/client/handler/correctness.go | 13 +- internal/transport/client/handler/event.go | 13 +- internal/transport/client/handler/price.go | 13 +- .../server/websocket/handler/correctness.go | 7 +- .../server/websocket/handler/event.go | 7 +- .../server/websocket/handler/kosk.go | 8 +- .../server/websocket/handler/price.go | 7 +- .../server/websocket/middleware/signature.go | 18 +- 41 files changed, 737 insertions(+), 311 deletions(-) create mode 100644 internal/crypto/bls/identity_test.go create mode 100644 internal/crypto/tss/identity.go create mode 100644 internal/crypto/tss/identity_test.go create mode 100644 internal/service/pos/eip712/helper.go diff --git a/.gitignore b/.gitignore index 85ef8d18..3e7cebda 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ internal/bin bin **/conf.*.private .idea +/demo.go diff --git a/cmd/handler/broker.go b/cmd/handler/broker.go index dc05b765..9e95a507 100644 --- a/cmd/handler/broker.go +++ b/cmd/handler/broker.go @@ -28,6 +28,7 @@ func WithBrokerCmd(cmd *cobra.Command) { cmd.AddCommand(broker) } +// init loads CLI flags of broker command func init() { broker.Flags().StringP( "broker", diff --git a/cmd/handler/consumer.go b/cmd/handler/consumer.go index e8066f24..e6e1ea95 100644 --- a/cmd/handler/consumer.go +++ b/cmd/handler/consumer.go @@ -34,6 +34,7 @@ func WithConsumerCmd(cmd *cobra.Command) { cmd.AddCommand(consumer) } +// init loads CLI flags of consumer command func init() { consumer.Flags().StringP( "broker", diff --git a/cmd/handler/worker.go b/cmd/handler/worker.go index c4f12148..5b765102 100644 --- a/cmd/handler/worker.go +++ b/cmd/handler/worker.go @@ -33,6 +33,7 @@ func WithWorkerCmd(cmd *cobra.Command) { cmd.AddCommand(worker) } +// init loads CLI flags of worker command func init() { worker.Flags().StringP( "broker", diff --git a/cmd/main.go b/cmd/main.go index 100af6ac..3c91f2f4 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -24,6 +24,7 @@ var root = &cobra.Command{ }, } +// Unchained entrypoint func main() { handler.WithBrokerCmd(root) handler.WithConsumerCmd(root) @@ -35,6 +36,7 @@ func main() { } } +// init loads global CLI flags func init() { root.Flags().BoolVarP(&config.App.System.PrintVersion, "version", "v", false, "Print the Unchained version number and die") root.PersistentFlags().StringVarP(&config.App.System.ConfigPath, "config", "c", "./conf.yaml", "Config file") diff --git a/go.mod b/go.mod index a5b70934..e1078689 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( entgo.io/contrib v0.4.6-0.20240215171353-eff33e4dca0b entgo.io/ent v0.13.1 github.com/99designs/gqlgen v0.17.45 + github.com/bnb-chain/tss-lib v1.3.5 github.com/btcsuite/btcutil v1.0.2 github.com/consensys/gnark-crypto v0.12.1 github.com/dgraph-io/badger/v4 v4.2.0 @@ -16,10 +17,12 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/ilyakaznacheev/cleanenv v1.5.0 github.com/jackc/pgx/v5 v5.5.5 + github.com/lastingasset/tss-lib v0.0.0-20221022151431-0bdbdcdfba56 github.com/lib/pq v1.10.9 github.com/lmittmann/tint v1.0.4 github.com/mattn/go-colorable v0.1.13 github.com/peterldowns/pgtestdb v0.0.14 + github.com/pkg/errors v0.9.1 github.com/pouya-eghbali/go-sia/v2 v2.1.0 github.com/puzpuzpuz/xsync/v3 v3.1.0 github.com/spf13/cobra v1.8.0 @@ -38,12 +41,13 @@ require ( github.com/Microsoft/go-winio v0.6.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect github.com/agext/levenshtein v1.2.3 // indirect + github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.13.0 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect - github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect + github.com/btcsuite/btcd v0.20.1-beta // indirect + github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cockroachdb/errors v1.8.1 // indirect github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f // indirect @@ -57,6 +61,7 @@ require ( github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect + github.com/decred/dcrd/dcrec/edwards/v2 v2.0.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect @@ -85,6 +90,7 @@ require ( github.com/holiman/uint256 v1.2.4 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/ipfs/go-log v0.0.1 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect @@ -102,7 +108,8 @@ require ( github.com/mitchellh/pointerstructure v1.2.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/pkg/errors v0.9.1 // indirect + github.com/opentracing/opentracing-go v1.1.0 // indirect + github.com/otiai10/primes v0.0.0-20180210170552-f6d2a1ba97c4 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.12.0 // indirect github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a // indirect @@ -126,6 +133,7 @@ require ( github.com/urfave/cli/v2 v2.27.1 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zclconf/go-cty v1.14.4 // indirect diff --git a/go.sum b/go.sum index 2ea0c99e..7bcddce8 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ ariga.io/atlas v0.20.0 h1:b2dL/OIubrCDKDUUXtudS+lJjoTzzKsTamfEg0VkcPI= ariga.io/atlas v0.20.0/go.mod h1:VPlcXdd4w2KqKnH54yEZcry79UAhpaWaxEsmn5JRNoE= +bou.ke/monkey v1.0.1 h1:zEMLInw9xvNakzUUPjfS4Ds6jYPqCFx3m7bRmG5NH2U= +bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -63,6 +65,8 @@ github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWk github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI= +github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= @@ -89,11 +93,13 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bnb-chain/tss-lib v1.3.5 h1:HqhrsiZfR+YPTOuedi65JnwE1HxsHAxKdoy7I2QQAPs= +github.com/bnb-chain/tss-lib v1.3.5/go.mod h1:o3zAAo7A88ZJnCE1qpjy1hTqPn+GPQlxRsj8soz14UU= +github.com/btcsuite/btcd v0.0.0-20190629003639-c26ffa870fd8/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= -github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= -github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= -github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= +github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts= @@ -156,6 +162,8 @@ github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80N github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/edwards/v2 v2.0.0 h1:E5KszxGgpjpmW8vN811G6rBAZg0/S/DftdGqN4FW5x4= +github.com/decred/dcrd/dcrec/edwards/v2 v2.0.0/go.mod h1:d0H8xGMWbiIQP7gN3v2rByWUcuZPm9YsgmnfoxgbINc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= @@ -228,6 +236,7 @@ github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -316,6 +325,7 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= @@ -343,6 +353,8 @@ github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/C github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= @@ -381,6 +393,7 @@ github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4 github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -404,6 +417,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/lastingasset/tss-lib v0.0.0-20221022151431-0bdbdcdfba56 h1:AaQnzJFRrI3NbWkHHN5v7KGS2n2hm7SuL81QdGRBmlQ= +github.com/lastingasset/tss-lib v0.0.0-20221022151431-0bdbdcdfba56/go.mod h1:4ZSo/Of0YmsxTaksO94Y/PcHP5kW3l9j0K95hTqVpi4= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= @@ -411,9 +426,11 @@ github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc= github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= @@ -469,6 +486,14 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= +github.com/otiai10/mint v1.2.4 h1:DxYL0itZyPaR5Z9HILdxSoHx+gNs6Yx+neOGS3IVUk0= +github.com/otiai10/mint v1.2.4/go.mod h1:d+b7n/0R3tdyUYYylALXpWQ/kTN+QobSq/4SRGBkR3M= +github.com/otiai10/primes v0.0.0-20180210170552-f6d2a1ba97c4 h1:blMAhTXF6uL1+e3eVSajjLT43Cc0U8mU1gcigbbolJM= +github.com/otiai10/primes v0.0.0-20180210170552-f6d2a1ba97c4/go.mod h1:UmSP7QeU3XmAdGu5+dnrTJqjBc+IscpVZkQzk473cjM= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterldowns/pgtestdb v0.0.14 h1:myVNL8ethaPZG7CQIjZxZCXwOG428THYRbSm0mIelpU= github.com/peterldowns/pgtestdb v0.0.14/go.mod h1:aG99+zgvWKOdGH+vtEFTDNVmaPOJD8ldIleuwJOgacA= @@ -590,6 +615,8 @@ github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IU github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= @@ -670,6 +697,7 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -736,6 +764,7 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -790,6 +819,7 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -921,6 +951,7 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= diff --git a/internal/config/config.go b/internal/config/config.go index 0533a983..4d13de3c 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -13,9 +13,13 @@ import ( "github.com/ilyakaznacheev/cleanenv" ) +// App holds global configs of application. var App Config + +// SecretFilePath holds the path of secret file. var SecretFilePath string +// Load function read config and secret file and override them if env variable provided. func Load(configPath, secretPath string) error { if configPath == "" { configPath = "./config.yaml" @@ -45,6 +49,7 @@ func Load(configPath, secretPath string) error { return nil } +// Save function write app's secret values to secret file. func (s *Secret) Save() error { yamlData, err := yaml.Marshal(&s) if err != nil { diff --git a/internal/config/model.go b/internal/config/model.go index 2c2efba9..ab6ce4d4 100644 --- a/internal/config/model.go +++ b/internal/config/model.go @@ -16,27 +16,32 @@ type System struct { PrintVersion bool } +// RPC struct represent a RPC configs. type RPC struct { Name string `yaml:"name"` Nodes []string `yaml:"nodes"` } +// Uniswap struct represent all task's detail of its plugin. type Uniswap struct { Schedule map[string]time.Duration `yaml:"schedule"` Tokens []Token `yaml:"tokens"` } +// EthLog struct represent all task's detail of its plugin. type EthLog struct { Schedule map[string]time.Duration `yaml:"schedule"` Events []Event `yaml:"events"` } +// Plugins struct holds all applications plugin configs. type Plugins struct { EthLog *EthLog `yaml:"logs"` Uniswap *Uniswap `yaml:"uniswap"` Correctness []string `yaml:"correctness"` } +// Event struct represent all events in EthLog plugin. type Event struct { Name string `yaml:"name"` Chain string `yaml:"chain"` @@ -50,6 +55,7 @@ type Event struct { Send bool `yaml:"send"` } +// Token struct represent all info about a token in plugin. type Token struct { Name string `yaml:"name"` Pair string `yaml:"pair"` @@ -61,12 +67,14 @@ type Token struct { Store bool `yaml:"store"` } +// ProofOfStake struct holds information about POS contract of application. type ProofOfStake struct { Chain string `env:"POS_CHAIN" env-default:"arbitrumSepolia" yaml:"chain"` Address string `env:"POS_ADDRESS" env-default:"0x965e364987356785b7E89e2Fe7B70f5E5107332d" yaml:"address"` Base int64 `env:"POS_BASE" env-default:"1" yaml:"base"` } +// Network struct holds all application network configuration. type Network struct { Bind string `env:"BIND" env-default:"0.0.0.0:9123" yaml:"bind"` BrokerURI string `env:"BROKER_URI" env-default:"wss://shinobi.brokers.kenshi.io" yaml:"brokerUri"` @@ -74,6 +82,7 @@ type Network struct { BrokerTimeout time.Duration `env:"BROKER_TIMEOUT" env-default:"3s" yaml:"brokerTimeout"` } +// Postgres struct holds all configs to connect to a pg instance. type Postgres struct { URL string `env:"DATABASE_URL" yaml:"url"` } @@ -85,6 +94,8 @@ type Secret struct { SecretKey string `env:"SECRET_KEY" yaml:"secretKey"` PublicKey string `env:"PUBLIC_KEY" yaml:"publicKey"` EvmPrivateKey string `env:"EVM_PRIVATE_KEY" yaml:"evmPrivateKey"` + + ShortPublicKey [48]byte } // Config struct is the main configuration struct of application. diff --git a/internal/consts/channels.go b/internal/consts/channels.go index 178cff37..d3ff0484 100644 --- a/internal/consts/channels.go +++ b/internal/consts/channels.go @@ -1,5 +1,6 @@ package consts +// Channels represent all channels which can be subscribed by consumers. type Channels string const ( diff --git a/internal/consts/errors.go b/internal/consts/errors.go index 55b0ced9..a87fa315 100644 --- a/internal/consts/errors.go +++ b/internal/consts/errors.go @@ -28,4 +28,5 @@ var ( ErrDuplicateSignature = errors.New("duplicate signature") ErrCrossPriceIsNotZero = errors.New("cross price is not zero") ErrAlreadySynced = errors.New("already synced") + ErrSignerIsNotReady = errors.New("signer is not ready yet") ) diff --git a/internal/consts/opcodes.go b/internal/consts/opcodes.go index f0a1c4c0..448fe703 100644 --- a/internal/consts/opcodes.go +++ b/internal/consts/opcodes.go @@ -2,6 +2,7 @@ package consts // TODO: Should we have a Data opcode instead of PriceReport & EventLog? +// OpCode represent all packet types which is used by networks participants. type OpCode byte const ( diff --git a/internal/crypto/bls/bls.go b/internal/crypto/bls/bls.go index 7b1460db..39ac22a0 100644 --- a/internal/crypto/bls/bls.go +++ b/internal/crypto/bls/bls.go @@ -1,8 +1,6 @@ package bls import ( - "math/big" - bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" ) @@ -11,16 +9,6 @@ func Hash(message []byte) (bls12381.G1Affine, error) { return bls12381.HashToG1(message, dst) } -func Sign(secretKey big.Int, message []byte) (bls12381.G1Affine, bls12381.G1Affine) { - hashedMessage, err := Hash(message) - if err != nil { - panic(err) - } - signature := new(bls12381.G1Affine).ScalarMultiplication(&hashedMessage, &secretKey) - - return *signature, hashedMessage -} - func RecoverSignature(bytes [48]byte) (bls12381.G1Affine, error) { signature := new(bls12381.G1Affine) _, err := signature.SetBytes(bytes[:]) @@ -33,15 +21,27 @@ func RecoverPublicKey(bytes [96]byte) (bls12381.G2Affine, error) { return *pk, err } -func AggregateSignatures(signatures []bls12381.G1Affine) (bls12381.G1Affine, error) { - aggregated := new(bls12381.G1Jac).FromAffine(&signatures[0]) +func AggregateSignatures(signatures [][]byte) ([]byte, error) { + signaturesBls := []bls12381.G1Affine{} + + for _, signature := range signatures { + signatureBls, err := RecoverSignature([48]byte(signature)) + if err != nil { + return nil, err + } + + signaturesBls = append(signaturesBls, signatureBls) + } + + aggregated := new(bls12381.G1Jac).FromAffine(&signaturesBls[0]) - for _, sig := range signatures[1:] { + for _, sig := range signaturesBls[1:] { sigJac := new(bls12381.G1Jac).FromAffine(&sig) aggregated.AddAssign(sigJac) } aggregatedAffine := new(bls12381.G1Affine).FromJacobian(aggregated) + aggregatedAffineByte := aggregatedAffine.Bytes() - return *aggregatedAffine, nil + return aggregatedAffineByte[:], nil } diff --git a/internal/crypto/bls/identity.go b/internal/crypto/bls/identity.go index bc97a22e..74ed867f 100644 --- a/internal/crypto/bls/identity.go +++ b/internal/crypto/bls/identity.go @@ -5,12 +5,16 @@ import ( "encoding/hex" "math/big" + "github.com/TimeleapLabs/unchained/internal/consts" + + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/btcsuite/btcutil/base58" + bls12381_fr "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" + "github.com/TimeleapLabs/unchained/internal/utils/address" "github.com/TimeleapLabs/unchained/internal/config" - "github.com/btcsuite/btcutil/base58" bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" - bls12381_fr "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" ) // Signer represents a BLS identity. @@ -24,6 +28,18 @@ type Signer struct { g1Aff bls12381.G1Affine } +// Sign will sign a data with bls secret and return signed data. +func (s *Signer) Sign(data []byte) ([]byte, error) { + hashedMessage, err := Hash(data) + if err != nil { + panic(err) + } + + signature := new(bls12381.G1Affine).ScalarMultiplication(&hashedMessage, s.SecretKey).Bytes() + + return signature[:], err +} + // WriteConfigs writes the secret key, public key and address to the global config object. func (s *Signer) WriteConfigs() { pkBytes := s.PublicKey.Bytes() @@ -32,6 +48,42 @@ func (s *Signer) WriteConfigs() { config.App.Secret.Address = address.Calculate(pkBytes[:]) } +// Verify verifies the signature of a message belongs to the public key. +func (s *Signer) Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) { + signatureBls, err := RecoverSignature([48]byte(signature)) + if err != nil { + utils.Logger.With("Err", err).Error("Can't recover bls signature") + return false, consts.ErrInternalError + } + + publicKeyBls, err := RecoverPublicKey([96]byte(publicKey)) + if err != nil { + utils.Logger.With("Err", err).Error("Can't recover pub-key") + return false, consts.ErrInternalError + } + + messageBls, err := Hash(hashedMessage) + if err != nil { + utils.Logger.With("Err", err).Error("Can't convert message to hash") + return false, consts.ErrInternalError + } + + pairingSigG2, err := bls12381.Pair( + []bls12381.G1Affine{signatureBls}, + []bls12381.G2Affine{s.g2Aff}) + if err != nil { + return false, err + } + + pairingHmPk, pairingError := bls12381.Pair( + []bls12381.G1Affine{messageBls}, + []bls12381.G2Affine{publicKeyBls}) + + ok := pairingSigG2.Equal(&pairingHmPk) + + return ok, pairingError +} + // NewIdentity creates a new BLS identity. func NewIdentity() *Signer { s := &Signer{ @@ -70,25 +122,9 @@ func NewIdentity() *Signer { s.ShortPublicKey = new(bls12381.G1Affine).ScalarMultiplication(&s.g1Aff, s.SecretKey) - return s -} + utils.Logger. + With("Address", s.ShortPublicKey.String()). + Info("Unchained identity initialized") -// Verify verifies the signature of a message belongs to the public key. -func (s *Signer) Verify( - signature bls12381.G1Affine, hashedMessage bls12381.G1Affine, publicKey bls12381.G2Affine, -) (bool, error) { - pairingSigG2, err := bls12381.Pair( - []bls12381.G1Affine{signature}, - []bls12381.G2Affine{s.g2Aff}) - if err != nil { - return false, err - } - - pairingHmPk, pairingError := bls12381.Pair( - []bls12381.G1Affine{hashedMessage}, - []bls12381.G2Affine{publicKey}) - - ok := pairingSigG2.Equal(&pairingHmPk) - - return ok, pairingError + return s } diff --git a/internal/crypto/bls/identity_test.go b/internal/crypto/bls/identity_test.go new file mode 100644 index 00000000..0b530354 --- /dev/null +++ b/internal/crypto/bls/identity_test.go @@ -0,0 +1,77 @@ +package bls + +import ( + "crypto/rand" + "testing" + + "github.com/TimeleapLabs/unchained/internal/config" + "github.com/TimeleapLabs/unchained/internal/utils" + bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" + bls12381_fr "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" +) + +var ( + testData = []byte("HELLO hello") + secondTestData = []byte("HELLO hello 2") +) + +type BlsIdentityTestSuite struct { + suite.Suite + identity *Signer +} + +func (s *BlsIdentityTestSuite) SetupTest() { + utils.SetupLogger("info") + + config.App.System.AllowGenerateSecrets = true + s.identity = NewIdentity() +} + +func (s *BlsIdentityTestSuite) TestSign() { + signedData, err := s.identity.Sign(testData) + assert.NoError(s.T(), err) + + publicKey := s.identity.PublicKey.Bytes() + + s.Run("Should verify the message correctly", func() { + isVerified, err := s.identity.Verify(signedData, testData, publicKey[:]) + assert.NoError(s.T(), err) + assert.True(s.T(), isVerified) + }) + + s.Run("Should not verify the message because of wrong data case", func() { + isVerified, err := s.identity.Verify(signedData, secondTestData, publicKey[:]) + assert.NoError(s.T(), err) + assert.False(s.T(), isVerified) + }) + + s.Run("Should not verify the message because of wrong data case", func() { + signedSecondData, err := s.identity.Sign(secondTestData) + assert.NoError(s.T(), err) + + isVerified, err := s.identity.Verify(signedSecondData, testData, publicKey[:]) + assert.NoError(s.T(), err) + assert.False(s.T(), isVerified) + }) + + s.Run("Should not verify the message because publicKey is not belong to this message", func() { + _, _, _, g2Aff := bls12381.Generators() + g2Order := bls12381_fr.Modulus() + sk, err := rand.Int(rand.Reader, g2Order) + if err != nil { + panic(err) + } + + pk := new(bls12381.G2Affine).ScalarMultiplication(&g2Aff, sk).Bytes() + + isVerified, err := s.identity.Verify(signedData, secondTestData, pk[:]) + assert.NoError(s.T(), err) + assert.False(s.T(), isVerified) + }) +} + +func TestBlsIdentitySuite(t *testing.T) { + suite.Run(t, new(BlsIdentityTestSuite)) +} diff --git a/internal/crypto/ethereum/identity.go b/internal/crypto/ethereum/identity.go index 648740a8..2e9246f7 100644 --- a/internal/crypto/ethereum/identity.go +++ b/internal/crypto/ethereum/identity.go @@ -6,7 +6,7 @@ import ( "github.com/TimeleapLabs/unchained/internal/config" "github.com/TimeleapLabs/unchained/internal/utils" "github.com/ethereum/go-ethereum/common/hexutil" - ethCrypto "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto" ) // Signer represents an Ethereum identity. @@ -16,13 +16,31 @@ type Signer struct { Address string } +func (s *Signer) Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) { + // TODO implement me + panic("implement me") +} + // WriteConfigs writes the secret key, public key and address to the global config object. func (s *Signer) WriteConfigs() { - privateKeyBytes := ethCrypto.FromECDSA(s.PrivateKey) + privateKeyBytes := crypto.FromECDSA(s.PrivateKey) config.App.Secret.EvmPrivateKey = hexutil.Encode(privateKeyBytes)[2:] config.App.Secret.EvmAddress = s.Address } +func (s *Signer) Sign(data []byte) ([]byte, error) { + signature, err := crypto.Sign(data, s.PrivateKey) + if err != nil { + return nil, err + } + + if signature[64] < 27 { + signature[64] += 27 + } + + return signature, nil +} + // NewIdentity creates a new Ethereum identity. func NewIdentity() *Signer { var privateKey *ecdsa.PrivateKey @@ -33,7 +51,7 @@ func NewIdentity() *Signer { } if config.App.Secret.EvmPrivateKey != "" { - privateKey, err = ethCrypto.HexToECDSA(config.App.Secret.EvmPrivateKey) + privateKey, err = crypto.HexToECDSA(config.App.Secret.EvmPrivateKey) if err != nil { utils.Logger. With("Error", err). @@ -42,7 +60,7 @@ func NewIdentity() *Signer { panic(err) } } else { - privateKey, err = ethCrypto.GenerateKey() + privateKey, err = crypto.GenerateKey() if err != nil { utils.Logger. With("Error", err). @@ -60,8 +78,12 @@ func NewIdentity() *Signer { s := &Signer{ PublicKey: publicKeyECDSA, PrivateKey: privateKey, - Address: ethCrypto.PubkeyToAddress(*publicKeyECDSA).Hex(), + Address: crypto.PubkeyToAddress(*publicKeyECDSA).Hex(), } + utils.Logger. + With("Address", s.Address). + Info("EVM identity initialized") + return s } diff --git a/internal/crypto/identity.go b/internal/crypto/identity.go index 10b02809..8e7e4146 100644 --- a/internal/crypto/identity.go +++ b/internal/crypto/identity.go @@ -1,17 +1,26 @@ package crypto import ( + "encoding/hex" "github.com/TimeleapLabs/unchained/internal/config" "github.com/TimeleapLabs/unchained/internal/crypto/bls" "github.com/TimeleapLabs/unchained/internal/crypto/ethereum" + "github.com/TimeleapLabs/unchained/internal/crypto/tss" "github.com/TimeleapLabs/unchained/internal/model" - "github.com/TimeleapLabs/unchained/internal/utils" ) +// Signer represents a Signing method. +type Signer interface { + Sign(data []byte) ([]byte, error) + Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) + WriteConfigs() +} + // MachineIdentity holds machine identity and provide and manage keys. type MachineIdentity struct { - Bls *bls.Signer - Eth *ethereum.Signer + Bls Signer + Eth Signer + Tss Signer } // Identity is a global variable that holds machine identity. @@ -39,38 +48,45 @@ func InitMachineIdentity(options ...Option) { // ExportEvmSigner returns EVM signer from machine identity. func (i *MachineIdentity) ExportEvmSigner() *model.Signer { + blsPublicKey, err := hex.DecodeString(config.App.Secret.PublicKey) + if err != nil { + panic(err) + } + return &model.Signer{ Name: config.App.System.Name, - EvmAddress: Identity.Eth.Address, - PublicKey: Identity.Bls.PublicKey.Bytes(), - ShortPublicKey: Identity.Bls.ShortPublicKey.Bytes(), + EvmAddress: config.App.Secret.EvmAddress, + PublicKey: [96]byte(blsPublicKey), + ShortPublicKey: config.App.Secret.ShortPublicKey, } } -// WithEvmSigner initialize and will add Evm keys to machine identity. +// WithEvmSigner initialize and will add Evm identity to machine identity. func WithEvmSigner() func(machineIdentity *MachineIdentity) error { return func(machineIdentity *MachineIdentity) error { machineIdentity.Eth = ethereum.NewIdentity() machineIdentity.Eth.WriteConfigs() - utils.Logger. - With("Address", machineIdentity.Eth.Address). - Info("EVM identity initialized") + return nil + } +} + +// WithTssSigner initialize and will add Tss identity to machine identity. +func WithTssSigner(signers []string, minThreshold int) func(machineIdentity *MachineIdentity) error { + return func(machineIdentity *MachineIdentity) error { + machineIdentity.Tss = tss.NewIdentity(signers, minThreshold) + //machineIdentity.Tss.WriteConfigs() return nil } } -// WithBlsIdentity initialize and will add Bls keys to machine identity. +// WithBlsIdentity initialize and will add Bls identity to machine identity. func WithBlsIdentity() func(machineIdentity *MachineIdentity) error { return func(machineIdentity *MachineIdentity) error { machineIdentity.Bls = bls.NewIdentity() machineIdentity.Bls.WriteConfigs() - utils.Logger. - With("Address", machineIdentity.Bls.ShortPublicKey.String()). - Info("Unchained identity initialized") - return nil } } diff --git a/internal/crypto/tss/identity.go b/internal/crypto/tss/identity.go new file mode 100644 index 00000000..4afa40e0 --- /dev/null +++ b/internal/crypto/tss/identity.go @@ -0,0 +1,158 @@ +package tss + +import ( + "github.com/TimeleapLabs/unchained/internal/consts" + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/bnb-chain/tss-lib/common" + "github.com/bnb-chain/tss-lib/ecdsa/keygen" + "github.com/bnb-chain/tss-lib/ecdsa/signing" + "github.com/bnb-chain/tss-lib/tss" + "math/big" +) + +// Signer represents a TSS identity. +type Signer struct { + ctx *tss.PeerContext + PartyID *tss.PartyID + keyParty *keygen.LocalParty + localPartySaved *keygen.LocalPartySaveData + result chan keygen.LocalPartySaveData + minThreshold int + numberOfPeers int +} + +type MessageSigner struct { + party *signing.LocalParty +} + +func (s *Signer) Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) { + //TODO implement me + panic("implement me") +} + +func (s *Signer) WriteConfigs() { + //TODO implement me + panic("implement me") +} + +// NewSigning will sign a data with tss secret and return signed data. +func (s *Signer) NewSigning(data []byte, out chan tss.Message, end chan<- common.SignatureData) (*MessageSigner, error) { + if !s.localPartySaved.ValidateWithProof() { + return &MessageSigner{}, consts.ErrSignerIsNotReady + } + + dataBig := new(big.Int).SetBytes(data) + + params := tss.NewParameters(tss.S256(), s.ctx, s.PartyID, s.numberOfPeers, s.minThreshold) + signer := &MessageSigner{ + party: signing.NewLocalParty(dataBig, params, *s.localPartySaved, out, end).(*signing.LocalParty), + } + + go func(signer *MessageSigner) { + err := signer.party.Start() + if err != nil { + panic(err) + } + }(signer) + + return signer, nil +} + +func (s *MessageSigner) AckSignature(msg tss.Message) error { + if s.party.PartyID() == msg.GetFrom() { + return nil + } + + bz, _, err := msg.WireBytes() + if err != nil { + utils.Logger.Error(err.Error()) + return err + } + + pMsg, err := tss.ParseWireMessage(bz, msg.GetFrom(), msg.IsBroadcast()) + if err != nil { + utils.Logger.Error(err.Error()) + return err + } + + isOK, err := s.party.Update(pMsg) + if err != nil && !isOK { + utils.Logger.Error(err.Error()) + return err + } + + return nil +} + +func (s *Signer) Update(msg tss.Message) error { + if s.keyParty.PartyID() == msg.GetFrom() { + return nil + } + + bz, _, err := msg.WireBytes() + if err != nil { + utils.Logger.Error(err.Error()) + return err + } + + pMsg, err := tss.ParseWireMessage(bz, msg.GetFrom(), msg.IsBroadcast()) + if err != nil { + utils.Logger.Error(err.Error()) + return err + } + + isOK, err := s.keyParty.Update(pMsg) + if err != nil && !isOK { + utils.Logger.Error(err.Error()) + return err + } + + return nil +} + +// NewIdentity creates a new BLS identity. +func NewIdentity(signerID int, signers []string, outCh chan tss.Message, done chan struct{}, minThreshold int) *Signer { + partyIDs := make(tss.UnSortedPartyIDs, len(signers)) + for i, signer := range signers { + party := tss.NewPartyID(signer, signer, big.NewInt(int64(i+1))) + partyIDs[i] = party + } + + signer := &Signer{ + minThreshold: minThreshold, + numberOfPeers: len(signers), + //rawPartyID: signers[signerID], + PartyID: partyIDs[signerID], + result: make(chan keygen.LocalPartySaveData, len(signers)), + } + + sortedPartyIDs := tss.SortPartyIDs(partyIDs) + + signer.ctx = tss.NewPeerContext(sortedPartyIDs) + + signer.keyParty = keygen.NewLocalParty( + tss.NewParameters(tss.S256(), signer.ctx, sortedPartyIDs[signerID], len(signers), minThreshold), + outCh, + signer.result, + ).(*keygen.LocalParty) + + go func(signer *Signer) { + err := signer.keyParty.Start() + if err != nil { + panic(err) + } + utils.Logger.With("ID", signer.PartyID.Moniker).Info("New Tss party started") + + for { + select { + case save := <-signer.result: + signer.localPartySaved = &save + done <- struct{}{} + break + } + } + + }(signer) + + return signer +} diff --git a/internal/crypto/tss/identity_test.go b/internal/crypto/tss/identity_test.go new file mode 100644 index 00000000..9d25f842 --- /dev/null +++ b/internal/crypto/tss/identity_test.go @@ -0,0 +1,125 @@ +package tss + +import ( + "fmt" + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/bnb-chain/tss-lib/common" + "github.com/bnb-chain/tss-lib/tss" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + "testing" +) + +const ( + numOfSigners = 4 + minNumOfSigners = 2 +) + +var ( + testData = []byte("HELLO hello") + secondTestData = []byte("HELLO hello 2") + signers = []string{} +) + +type TssIdentityTestSuite struct { + suite.Suite + parties []*Signer +} + +func (s *TssIdentityTestSuite) SetupTest() { + utils.SetupLogger("info") + + for i := 0; i < numOfSigners; i++ { + signers = append(signers, fmt.Sprintf("signer-%d", i)) + } + + outCh := make(chan tss.Message, len(signers)) + wg := make(chan struct{}) + + for i := 0; i < numOfSigners; i++ { + party := NewIdentity(i, signers, outCh, wg, minNumOfSigners) + s.parties = append(s.parties, party) + } + + wait := 0 +keygen: + for { + select { + case msg := <-outCh: + dest := msg.GetTo() + + if dest == nil { // broadcast! + for _, P := range s.parties { + if P.PartyID.Index == msg.GetFrom().Index { + continue + } + + go P.Update(msg) + } + } else { // point-to-point! + if dest[0].Index == msg.GetFrom().Index { + fmt.Printf("party %d tried to send a message to itself (%d)", dest[0].Index, msg.GetFrom().Index) + return + } + go s.parties[dest[0].Index].Update(msg) + } + + case <-wg: + wait++ + if wait == numOfSigners { + break keygen + } + } + } +} + +func (s *TssIdentityTestSuite) TestSign() { + outCh := make(chan tss.Message, len(s.parties)) + endCh := make(chan common.SignatureData, len(s.parties)) + msgSigners := []*MessageSigner{} + + for i := 0; i < numOfSigners; i++ { + go func() { + signer, err := s.parties[i].NewSigning(testData, outCh, endCh) + assert.NoError(s.T(), err) + + msgSigners = append(msgSigners, signer) + }() + } + + // wait := 0 + //signing: + for { + select { + case msg := <-outCh: + dest := msg.GetTo() + if dest == nil { + for _, P := range msgSigners { + if P.party.PartyID().Index == msg.GetFrom().Index { + continue + } + + go P.AckSignature(msg) + } + } else { + if dest[0].Index == msg.GetFrom().Index { + common.Logger.Fatalf("party %d tried to send a message to itself (%d)", dest[0].Index, msg.GetFrom().Index) + } + + go msgSigners[dest[0].Index].AckSignature(msg) + } + case <-endCh: + fmt.Println("end") + } + } + + //s.Run("Should verify the message correctly", func() { + // isVerified, err := s.identity.Verify() + // assert.NoError(s.T(), err) + // assert.True(s.T(), isVerified) + //}) +} + +func TestTssIdentitySuite(t *testing.T) { + suite.Run(t, new(TssIdentityTestSuite)) +} diff --git a/internal/model/bls.go b/internal/model/bls.go index ebbf554a..4449e623 100644 --- a/internal/model/bls.go +++ b/internal/model/bls.go @@ -1,7 +1,6 @@ package model import ( - bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" sia "github.com/pouya-eghbali/go-sia/v2/pkg" ) @@ -13,13 +12,13 @@ type Signer struct { } type Signature struct { - Signature bls12381.G1Affine + Signature []byte Signer Signer } func (s *Signature) Sia() sia.Sia { return sia.New(). - AddByteArray8(s.Signature.Marshal()). + AddByteArray8(s.Signature). EmbedBytes(s.Signer.Sia().Bytes()) } @@ -29,12 +28,7 @@ func (s *Signature) FromBytes(payload []byte) *Signature { } func (s *Signature) FromSia(sia sia.Sia) *Signature { - err := s.Signature.Unmarshal(sia.ReadByteArray8()) - - if err != nil { - s.Signature = bls12381.G1Affine{} - } - + s.Signature = sia.ReadByteArray8() s.Signer.FromSia(sia) return s diff --git a/internal/repository/postgres/assetprice.go b/internal/repository/postgres/assetprice.go index 441a898d..c391a784 100644 --- a/internal/repository/postgres/assetprice.go +++ b/internal/repository/postgres/assetprice.go @@ -34,6 +34,9 @@ func (a AssetPriceRepo) Upsert(ctx context.Context, data model.AssetPrice) error AddSignerIDs(data.SignerIDs...). OnConflictColumns("block", "chain", "asset", "pair"). UpdateNewValues(). + Update(func(u *ent.AssetPriceUpsert) { + u.Add("voted", 1) + }). Exec(ctx) if err != nil { diff --git a/internal/repository/postgres/correctness.go b/internal/repository/postgres/correctness.go index c4095362..b5d9a7dc 100644 --- a/internal/repository/postgres/correctness.go +++ b/internal/repository/postgres/correctness.go @@ -53,6 +53,9 @@ func (c CorrectnessRepo) Upsert(ctx context.Context, data model.Correctness) err AddSignerIDs(data.SignerIDs...). OnConflictColumns("topic", "hash"). UpdateNewValues(). + Update(func(u *ent.CorrectnessReportUpsert) { + u.Add("voted", 1) + }). Exec(ctx) if err != nil { diff --git a/internal/service/correctness/correctness.go b/internal/service/correctness/correctness.go index ad4524d1..a9c20a35 100644 --- a/internal/service/correctness/correctness.go +++ b/internal/service/correctness/correctness.go @@ -39,7 +39,7 @@ type SaveSignatureArgs struct { type Service interface { IsNewSigner(signature model.Signature, records []*ent.CorrectnessReport) bool RecordSignature( - ctx context.Context, signature bls12381.G1Affine, signer model.Signer, hash bls12381.G1Affine, info model.Correctness, debounce bool, + ctx context.Context, signature []byte, signer model.Signer, hash bls12381.G1Affine, info model.Correctness, debounce bool, ) error SaveSignatures(ctx context.Context, args SaveSignatureArgs) error } @@ -74,7 +74,7 @@ func (s *service) IsNewSigner(signature model.Signature, records []*ent.Correctn // TODO: How should we handle older records? // Possible Solution: Add a not after timestamp to the document. func (s *service) RecordSignature( - ctx context.Context, signature bls12381.G1Affine, signer model.Signer, hash bls12381.G1Affine, info model.Correctness, debounce bool, + ctx context.Context, signature []byte, signer model.Signer, hash bls12381.G1Affine, info model.Correctness, debounce bool, ) error { if supported := s.supportedTopics[info.Topic]; !supported { utils.Logger. @@ -168,10 +168,7 @@ func (s *service) SaveSignatures(ctx context.Context, args SaveSignatureArgs) er return consts.ErrSignatureNotfound } - var newSigners []model.Signer - var newSignatures []bls12381.G1Affine var keys [][]byte - for i := range signatures { signature := signatures[i] keys = append(keys, signature.Signer.PublicKey[:]) @@ -182,11 +179,10 @@ func (s *service) SaveSignatures(ctx context.Context, args SaveSignatureArgs) er return err } + var newSigners []model.Signer + var newSignatures [][]byte // Select the new signers and signatures - - for i := range signatures { - signature := signatures[i] - + for _, signature := range signatures { if !s.IsNewSigner(signature, currentRecords) { continue } @@ -207,31 +203,21 @@ func (s *service) SaveSignatures(ctx context.Context, args SaveSignatureArgs) er return err } - var aggregate bls12381.G1Affine - for _, record := range currentRecords { if record.Correct == args.Info.Correct { - currentSignature, err := bls.RecoverSignature([48]byte(record.Signature)) - - if err != nil { - return err - } - - newSignatures = append(newSignatures, currentSignature) + newSignatures = append(newSignatures, record.Signature) break } } - aggregate, err = bls.AggregateSignatures(newSignatures) + aggregatedSignature, err := bls.AggregateSignatures(newSignatures) if err != nil { return consts.ErrCantAggregateSignatures } - signatureBytes := aggregate.Bytes() - err = s.correctnessRepo.Upsert(ctx, model.Correctness{ SignersCount: uint64(len(signatures)), - Signature: signatureBytes[:], + Signature: aggregatedSignature, Consensus: args.Consensus, Voted: *args.Voted, SignerIDs: signerIDs, diff --git a/internal/service/evmlog/evmlog.go b/internal/service/evmlog/evmlog.go index b96d1bfb..fc924f93 100644 --- a/internal/service/evmlog/evmlog.go +++ b/internal/service/evmlog/evmlog.go @@ -2,13 +2,14 @@ package evmlog import ( "context" - "fmt" "math/big" "os" "slices" "sync" "time" + "github.com/TimeleapLabs/unchained/internal/crypto" + "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/model" "github.com/TimeleapLabs/unchained/internal/repository" @@ -42,15 +43,16 @@ type SaveSignatureArgs struct { type Service interface { GetBlockNumber(ctx context.Context, network string) (*uint64, error) SaveSignatures(ctx context.Context, args SaveSignatureArgs) error - SendPriceReport(signature bls12381.G1Affine, event model.EventLog) + SendPriceReport(signature []byte, event model.EventLog) ProcessBlocks(ctx context.Context, chain string) error RecordSignature( - ctx context.Context, signature bls12381.G1Affine, signer model.Signer, hash bls12381.G1Affine, info model.EventLog, debounce bool, historical bool, + ctx context.Context, signature []byte, signer model.Signer, hash bls12381.G1Affine, info model.EventLog, debounce bool, historical bool, ) error } type service struct { ethRPC ethereum.RPC + signer crypto.Signer pos pos.Service eventLogRepo repository.EventLog signerRepo repository.Signer @@ -83,7 +85,7 @@ func (s *service) SaveSignatures(ctx context.Context, args SaveSignatureArgs) er } var newSigners []model.Signer - var newSignatures []bls12381.G1Affine + var newSignatures [][]byte var keys [][]byte currentRecords, err := s.eventLogRepo.Find(ctx, args.Info.Block, args.Info.TxHash[:], args.Info.LogIndex) @@ -91,8 +93,7 @@ func (s *service) SaveSignatures(ctx context.Context, args SaveSignatureArgs) er return err } - for i := range signatures { - signature := signatures[i] + for _, signature := range signatures { keys = append(keys, signature.Signer.PublicKey[:]) if !isNewSigner(signature, currentRecords) { @@ -104,19 +105,15 @@ func (s *service) SaveSignatures(ctx context.Context, args SaveSignatureArgs) er } err = s.signerRepo.CreateSigners(ctx, newSigners) - if err != nil { return err } signerIDs, err := s.signerRepo.GetSingerIDsByKeys(ctx, keys) - if err != nil { return err } - var aggregate bls12381.G1Affine - sortedCurrentArgs := make([]model.EventLogArg, len(args.Info.Args)) copy(sortedCurrentArgs, args.Info.Args) slices.SortFunc(sortedCurrentArgs, sortEventArgs) @@ -145,39 +142,22 @@ func (s *service) SaveSignatures(ctx context.Context, args SaveSignatureArgs) er continue } - currentAggregate, err := bls.RecoverSignature([48]byte(record.Signature)) - - if err != nil { - utils.Logger. - With("Block", args.Info.Block). - With("Transaction", fmt.Sprintf("%x", args.Info.TxHash)). - With("Index", args.Info.LogIndex). - With("Event", args.Info.Event). - With("Hash", fmt.Sprintf("%x", args.Hash.Bytes())[:8]). - With("Error", err). - Debug("Failed to recover signature") - return consts.ErrCantRecoverSignature - } - - newSignatures = append(newSignatures, currentAggregate) + newSignatures = append(newSignatures, record.Signature) break } - aggregate, err = bls.AggregateSignatures(newSignatures) - + aggregatedSignature, err := bls.AggregateSignatures(newSignatures) if err != nil { return consts.ErrCantAggregateSignatures } - signatureBytes := aggregate.Bytes() - args.Info.SignersCount = uint64(len(signatures)) args.Info.SignerIDs = signerIDs args.Info.Consensus = args.Consensus - args.Info.Signature = signatureBytes[:] + args.Info.Signature = aggregatedSignature args.Info.Voted = &helpers.BigInt{Int: *args.Voted} - err = s.eventLogRepo.Upsert(ctx, args.Info) + err = s.eventLogRepo.Upsert(ctx, args.Info) if err != nil { return err } @@ -185,12 +165,10 @@ func (s *service) SaveSignatures(ctx context.Context, args SaveSignatureArgs) er return nil } -func (s *service) SendPriceReport(signature bls12381.G1Affine, event model.EventLog) { - compressedSignature := signature.Bytes() - +func (s *service) SendPriceReport(signature []byte, event model.EventLog) { priceReport := model.EventLogReportPacket{ EventLog: event, - Signature: compressedSignature, + Signature: [48]byte(signature), } conn.Send(consts.OpCodeEventLog, priceReport.Sia().Bytes()) diff --git a/internal/service/evmlog/process.go b/internal/service/evmlog/process.go index d07759df..26753e88 100644 --- a/internal/service/evmlog/process.go +++ b/internal/service/evmlog/process.go @@ -8,13 +8,14 @@ import ( "sort" "strings" + "github.com/TimeleapLabs/unchained/internal/crypto/bls" + "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/model" "github.com/TimeleapLabs/unchained/internal/utils" "github.com/TimeleapLabs/unchained/internal/config" "github.com/TimeleapLabs/unchained/internal/crypto" - "github.com/TimeleapLabs/unchained/internal/crypto/bls" "github.com/dgraph-io/badger/v4" goEthereum "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" @@ -164,7 +165,15 @@ func (s *service) ProcessBlocks(ctx context.Context, chain string) error { } toHash := event.Sia().Bytes() - signature, hash := bls.Sign(*crypto.Identity.Bls.SecretKey, toHash) + signature, err := s.signer.Sign(toHash) + if err != nil { + panic(err) + } + + hashedMessage, err := bls.Hash(signature) + if err != nil { + panic(err) + } if conf.Send { s.SendPriceReport(signature, event) @@ -175,7 +184,7 @@ func (s *service) ProcessBlocks(ctx context.Context, chain string) error { ctx, signature, *crypto.Identity.ExportEvmSigner(), - hash, + hashedMessage, event, false, true, diff --git a/internal/service/evmlog/record.go b/internal/service/evmlog/record.go index 706876df..c59d03c2 100644 --- a/internal/service/evmlog/record.go +++ b/internal/service/evmlog/record.go @@ -13,7 +13,7 @@ import ( ) func (s *service) RecordSignature( - ctx context.Context, signature bls12381.G1Affine, signer model.Signer, hash bls12381.G1Affine, info model.EventLog, debounce bool, historical bool, + ctx context.Context, signature []byte, signer model.Signer, hash bls12381.G1Affine, info model.EventLog, debounce bool, historical bool, ) error { supportKey := SupportKey{ Chain: info.Chain, diff --git a/internal/service/pos/eip712.go b/internal/service/pos/eip712.go index fc18c7ba..9c42bc7b 100644 --- a/internal/service/pos/eip712.go +++ b/internal/service/pos/eip712.go @@ -6,7 +6,6 @@ import ( "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/TimeleapLabs/unchained/internal/crypto" "github.com/TimeleapLabs/unchained/internal/crypto/ethereum/contracts" "github.com/TimeleapLabs/unchained/internal/config" @@ -32,7 +31,7 @@ func (s *service) Slash(ctx context.Context, address [20]byte, to common.Address NftIds: nftIDs, } - signature, err := s.eip712Signer.SignTransferRequest(crypto.Identity.Eth, &transfer) + signature, err := s.eip712Signer.SignTransferRequest(&transfer) if err != nil { utils.Logger. diff --git a/internal/service/pos/eip712/helper.go b/internal/service/pos/eip712/helper.go new file mode 100644 index 00000000..deb19074 --- /dev/null +++ b/internal/service/pos/eip712/helper.go @@ -0,0 +1,33 @@ +package eip712 + +import ( + "fmt" + + "github.com/TimeleapLabs/unchained/internal/crypto/ethereum/contracts" + ethCrypto "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/signer/core/apitypes" +) + +func NewUnchainedSignatureFromBytes(signature []byte) *contracts.UnchainedStakingSignature { + return &contracts.UnchainedStakingSignature{ + V: signature[64], + R: [32]byte(signature[:32]), + S: [32]byte(signature[32:64]), + } +} + +func TypedDataToByte(data *apitypes.TypedData) ([]byte, error) { + domainSeparator, err := data.HashStruct("EIP712Domain", data.Domain.Map()) + if err != nil { + return nil, err + } + + typedDataHash, err := data.HashStruct(data.PrimaryType, data.Message) + if err != nil { + return nil, err + } + message := []byte(fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash))) + messageHash := ethCrypto.Keccak256(message) + + return messageHash, nil +} diff --git a/internal/service/pos/eip712/sign.go b/internal/service/pos/eip712/sign.go index 1c5e7ff1..e10a8114 100644 --- a/internal/service/pos/eip712/sign.go +++ b/internal/service/pos/eip712/sign.go @@ -1,14 +1,14 @@ package eip712 import ( - "fmt" "math/big" - "github.com/TimeleapLabs/unchained/internal/crypto/ethereum" + "github.com/TimeleapLabs/unchained/internal/config" + "github.com/TimeleapLabs/unchained/internal/crypto" + "github.com/TimeleapLabs/unchained/internal/crypto/ethereum/contracts" "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/signer/core/apitypes" ) @@ -16,47 +16,13 @@ type Signer struct { domain apitypes.TypedDataDomain } -func (s *Signer) bytesToUnchainedSignature(signature []byte) *contracts.UnchainedStakingSignature { - return &contracts.UnchainedStakingSignature{ - V: signature[64], - R: [32]byte(signature[:32]), - S: [32]byte(signature[32:64]), - } -} - -func (s *Signer) signEip712Message(evmSigner *ethereum.Signer, data *apitypes.TypedData) (*contracts.UnchainedStakingSignature, error) { - domainSeparator, err := data.HashStruct("EIP712Domain", data.Domain.Map()) - if err != nil { - return nil, err - } - - typedDataHash, err := data.HashStruct(data.PrimaryType, data.Message) - if err != nil { - return nil, err - } - - message := []byte(fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash))) - messageHash := crypto.Keccak256(message) - - signature, err := crypto.Sign(messageHash, evmSigner.PrivateKey) - if err != nil { - return nil, err - } - - if signature[64] < 27 { - signature[64] += 27 - } - - return s.bytesToUnchainedSignature(signature), nil -} - -func (s *Signer) SignTransferRequest(evmSigner *ethereum.Signer, request *contracts.UnchainedStakingEIP712Transfer) (*contracts.UnchainedStakingSignature, error) { +func (s *Signer) SignTransferRequest(request *contracts.UnchainedStakingEIP712Transfer) (*contracts.UnchainedStakingSignature, error) { data := &apitypes.TypedData{ Types: Types, PrimaryType: "Transfer", Domain: s.domain, Message: map[string]interface{}{ - "signer": evmSigner.Address, + "signer": config.App.Secret.EvmAddress, "from": request.From, "to": request.To, "amount": request.Amount, @@ -65,16 +31,26 @@ func (s *Signer) SignTransferRequest(evmSigner *ethereum.Signer, request *contra }, } - return s.signEip712Message(evmSigner, data) + dataBytes, err := TypedDataToByte(data) + if err != nil { + return nil, err + } + + signedData, err := crypto.Identity.Eth.Sign(dataBytes) + if err != nil { + return nil, err + } + + return NewUnchainedSignatureFromBytes(signedData), nil } -func (s *Signer) SignSetParamsRequest(evmSigner *ethereum.Signer, request *contracts.UnchainedStakingEIP712SetParams) (*contracts.UnchainedStakingSignature, error) { +func (s *Signer) SignSetParamsRequest(request *contracts.UnchainedStakingEIP712SetParams) (*contracts.UnchainedStakingSignature, error) { data := &apitypes.TypedData{ Types: Types, PrimaryType: "SetParams", Domain: s.domain, Message: map[string]interface{}{ - "requester": evmSigner.Address, + "requester": config.App.Secret.EvmAddress, "token": request.Token, "nft": request.Nft, "nftTracker": request.NftTracker, @@ -84,23 +60,43 @@ func (s *Signer) SignSetParamsRequest(evmSigner *ethereum.Signer, request *contr }, } - return s.signEip712Message(evmSigner, data) + dataBytes, err := TypedDataToByte(data) + if err != nil { + return nil, err + } + + signedData, err := crypto.Identity.Eth.Sign(dataBytes) + if err != nil { + return nil, err + } + + return NewUnchainedSignatureFromBytes(signedData), nil } -func (s *Signer) SignSetNftPriceRequest(evmSigner *ethereum.Signer, request *contracts.UnchainedStakingEIP712SetNftPrice) (*contracts.UnchainedStakingSignature, error) { +func (s *Signer) SignSetNftPriceRequest(request *contracts.UnchainedStakingEIP712SetNftPrice) (*contracts.UnchainedStakingSignature, error) { data := &apitypes.TypedData{ Types: Types, PrimaryType: "SetNftPrice", Domain: s.domain, Message: map[string]interface{}{ - "requester": evmSigner.Address, + "requester": config.App.Secret.EvmAddress, "nftId": request.NftId, "price": request.Price, "nonce": request.Nonce, }, } - return s.signEip712Message(evmSigner, data) + dataBytes, err := TypedDataToByte(data) + if err != nil { + return nil, err + } + + signedData, err := crypto.Identity.Eth.Sign(dataBytes) + if err != nil { + return nil, err + } + + return NewUnchainedSignatureFromBytes(signedData), nil } func New(chainID *big.Int, verifyingContract string) *Signer { diff --git a/internal/service/pos/pos.go b/internal/service/pos/pos.go index 32c9e232..6ee505b7 100644 --- a/internal/service/pos/pos.go +++ b/internal/service/pos/pos.go @@ -2,10 +2,10 @@ package pos import ( "context" + "encoding/hex" "math/big" "github.com/TimeleapLabs/unchained/internal/config" - "github.com/TimeleapLabs/unchained/internal/crypto" "github.com/TimeleapLabs/unchained/internal/crypto/ethereum" "github.com/TimeleapLabs/unchained/internal/crypto/ethereum/contracts" "github.com/TimeleapLabs/unchained/internal/service/pos/eip712" @@ -91,14 +91,10 @@ func New(ethRPC ethereum.RPC) Service { lastUpdated: xsync.NewMapOf[[20]byte, *big.Int](), } - pkBytes := crypto.Identity.Bls.PublicKey.Bytes() - addrHexStr, addrHex := address.CalculateHex(pkBytes[:]) - - utils.Logger. - With("Address", addrHexStr). - Info("PoS identity initialized") - - var err error + blsPublicKey, err := hex.DecodeString(config.App.Secret.PublicKey) + if err != nil { + panic(err) + } s.posContract, err = s.ethRPC.GetNewStakingContract( config.App.ProofOfStake.Chain, @@ -113,7 +109,7 @@ func New(ethRPC ethereum.RPC) Service { panic(err) } - power, err := s.GetVotingPower(addrHex, big.NewInt(0)) + power, err := s.GetVotingPower([20]byte(blsPublicKey), big.NewInt(0)) if err != nil { utils.Logger. With("Error", err). diff --git a/internal/service/uniswap/record.go b/internal/service/uniswap/record.go index 070c01b3..04c03f09 100644 --- a/internal/service/uniswap/record.go +++ b/internal/service/uniswap/record.go @@ -17,7 +17,7 @@ import ( // TODO: This needs to work with different datasets // TODO: Can we turn this into a library func? func (s *service) RecordSignature( - ctx context.Context, signature bls12381.G1Affine, signer model.Signer, hash bls12381.G1Affine, info model.PriceInfo, debounce bool, historical bool, + ctx context.Context, signature []byte, signer model.Signer, hash bls12381.G1Affine, info model.PriceInfo, debounce bool, historical bool, ) error { if supported := s.SupportedTokens[info.Asset.Token]; !supported { utils.Logger. @@ -89,7 +89,7 @@ func (s *service) RecordSignature( } if !debounce { - err = s.saveSignatures(ctx, saveArgs) + err = s.SaveSignatures(ctx, saveArgs) if err != nil { return err } diff --git a/internal/service/uniswap/uniswap.go b/internal/service/uniswap/uniswap.go index 411b1d90..40c41f53 100644 --- a/internal/service/uniswap/uniswap.go +++ b/internal/service/uniswap/uniswap.go @@ -41,16 +41,16 @@ var DebouncedSaveSignatures func(key model.AssetKey, arg SaveSignatureArgs) type Service interface { checkAndCacheSignature( - reportedValues *xsync.MapOf[bls12381.G1Affine, big.Int], signature bls12381.G1Affine, signer model.Signer, + reportedValues *xsync.MapOf[bls12381.G1Affine, big.Int], signature []byte, signer model.Signer, hash bls12381.G1Affine, totalVoted *big.Int, ) error - saveSignatures(ctx context.Context, args SaveSignatureArgs) error + SaveSignatures(ctx context.Context, args SaveSignatureArgs) error GetBlockNumber(ctx context.Context, network string) (*uint64, error) GetPriceAtBlockFromPair(network string, blockNumber uint64, pairAddr string, decimalDif int64, inverse bool) (*big.Int, error) SyncBlocks(ctx context.Context, token model.Token, key model.TokenKey, latest uint64) error TokenKey(token model.Token) *model.TokenKey RecordSignature( - ctx context.Context, signature bls12381.G1Affine, signer model.Signer, hash bls12381.G1Affine, info model.PriceInfo, debounce bool, historical bool, + ctx context.Context, signature []byte, signer model.Signer, hash bls12381.G1Affine, info model.PriceInfo, debounce bool, historical bool, ) error ProcessBlocks(ctx context.Context, chain string) error } @@ -77,7 +77,7 @@ type service struct { } func (s *service) checkAndCacheSignature( - reportedValues *xsync.MapOf[bls12381.G1Affine, big.Int], signature bls12381.G1Affine, signer model.Signer, + reportedValues *xsync.MapOf[bls12381.G1Affine, big.Int], signature []byte, signer model.Signer, hash bls12381.G1Affine, totalVoted *big.Int, ) error { s.signatureMutex.Lock() @@ -113,7 +113,7 @@ type SaveSignatureArgs struct { Voted *big.Int } -func (s *service) saveSignatures(ctx context.Context, args SaveSignatureArgs) error { +func (s *service) SaveSignatures(ctx context.Context, args SaveSignatureArgs) error { utils.Logger. With("Block", args.Info.Asset.Block). With("Hash", fmt.Sprintf("%x", args.Hash.Bytes())[:8]). @@ -129,7 +129,7 @@ func (s *service) saveSignatures(ctx context.Context, args SaveSignatureArgs) er } var newSigners []model.Signer - var newSignatures []bls12381.G1Affine + var newSignatures [][]byte var keys [][]byte currentRecords, err := s.assetPriceRepo.Find( @@ -141,8 +141,7 @@ func (s *service) saveSignatures(ctx context.Context, args SaveSignatureArgs) er return err } - for i := range signatures { - signature := signatures[i] + for _, signature := range signatures { keys = append(keys, signature.Signer.PublicKey[:]) if !IsNewSigner(signature, currentRecords) { @@ -172,28 +171,14 @@ func (s *service) saveSignatures(ctx context.Context, args SaveSignatureArgs) er return err } - var aggregate bls12381.G1Affine - for _, record := range currentRecords { if record.Price.Cmp(&args.Info.Price) == 0 { - currentAggregate, err := bls.RecoverSignature([48]byte(record.Signature)) - - if err != nil { - utils.Logger. - With("Block", args.Info.Asset.Block). - With("Hash", fmt.Sprintf("%x", args.Hash.Bytes())[:8]). - With("Error", err). - Debug("Failed to recover signature") - return consts.ErrCantRecoverSignature - } - - newSignatures = append(newSignatures, currentAggregate) + newSignatures = append(newSignatures, record.Signature) break } } - aggregate, err = bls.AggregateSignatures(newSignatures) - + aggregatedSignature, err := bls.AggregateSignatures(newSignatures) if err != nil { utils.Logger. With("Block", args.Info.Asset.Block). @@ -202,8 +187,6 @@ func (s *service) saveSignatures(ctx context.Context, args SaveSignatureArgs) er return consts.ErrCantAggregateSignatures } - signatureBytes := aggregate.Bytes() - // TODO: Handle cases where signerIDs need to be removed err = s.assetPriceRepo.Upsert(ctx, model.AssetPrice{ Pair: strings.ToLower(args.Info.Asset.Token.Pair), @@ -212,12 +195,11 @@ func (s *service) saveSignatures(ctx context.Context, args SaveSignatureArgs) er Block: args.Info.Asset.Block, Price: args.Info.Price, SignersCount: uint64(len(signatures)), - Signature: signatureBytes[:], + Signature: aggregatedSignature, Consensus: args.Consensus, Voted: *args.Voted, SignerIDs: signerIDs, }) - if err != nil { utils.Logger. With("Block", args.Info.Asset.Block). @@ -355,13 +337,20 @@ func (s *service) syncBlock(ctx context.Context, token model.Token, caser cases. }, } - signature, hash := bls.Sign(*crypto.Identity.Bls.SecretKey, priceInfo.Sia().Bytes()) + signedData, err := crypto.Identity.Bls.Sign(priceInfo.Sia().Bytes()) + if err != nil { + panic(err) + } + + hashedMessage, err := bls.Hash(signedData) + if err != nil { + panic(err) + } if token.Send && !conn.IsClosed { - compressedSignature := signature.Bytes() priceReport := model.PriceReportPacket{ PriceInfo: priceInfo, - Signature: compressedSignature, + Signature: [48]byte(signedData), } conn.Send(consts.OpCodePriceReport, priceReport.Sia().Bytes()) @@ -370,9 +359,9 @@ func (s *service) syncBlock(ctx context.Context, token model.Token, caser cases. if token.Store { err = s.RecordSignature( ctx, - signature, + signedData, *crypto.Identity.ExportEvmSigner(), - hash, + hashedMessage, priceInfo, false, true, @@ -454,7 +443,7 @@ func New( crossTokens: map[string]model.TokenKey{}, } - DebouncedSaveSignatures = utils.Debounce[model.AssetKey, SaveSignatureArgs](5*time.Second, s.saveSignatures) + DebouncedSaveSignatures = utils.Debounce[model.AssetKey, SaveSignatureArgs](5*time.Second, s.SaveSignatures) s.twoOneNineTwo.Exp(big.NewInt(2), big.NewInt(192), nil) s.tenEighteen.Exp(big.NewInt(10), big.NewInt(18), nil) diff --git a/internal/transport/client/handler/challenge.go b/internal/transport/client/handler/challenge.go index 8d40f171..ec41609e 100644 --- a/internal/transport/client/handler/challenge.go +++ b/internal/transport/client/handler/challenge.go @@ -2,15 +2,20 @@ package handler import ( "github.com/TimeleapLabs/unchained/internal/crypto" - "github.com/TimeleapLabs/unchained/internal/crypto/bls" "github.com/TimeleapLabs/unchained/internal/model" + "github.com/TimeleapLabs/unchained/internal/utils" ) func (h *consumer) Challenge(message []byte) []byte { challenge := new(model.ChallengePacket).FromBytes(message) - signature, _ := bls.Sign(*crypto.Identity.Bls.SecretKey, challenge.Random[:]) - challenge.Signature = signature.Bytes() + signature, err := crypto.Identity.Bls.Sign(challenge.Random[:]) + if err != nil { + utils.Logger.Error(err.Error()) + return nil + } + + challenge.Signature = [48]byte(signature) return challenge.Sia().Bytes() } @@ -18,8 +23,13 @@ func (h *consumer) Challenge(message []byte) []byte { func (w worker) Challenge(message []byte) []byte { challenge := new(model.ChallengePacket).FromBytes(message) - signature, _ := bls.Sign(*crypto.Identity.Bls.SecretKey, challenge.Random[:]) - challenge.Signature = signature.Bytes() + signature, err := crypto.Identity.Bls.Sign(challenge.Random[:]) + if err != nil { + utils.Logger.Error(err.Error()) + return nil + } + + challenge.Signature = [48]byte(signature) return challenge.Sia().Bytes() } diff --git a/internal/transport/client/handler/correctness.go b/internal/transport/client/handler/correctness.go index 50486e1a..7cfdf6b0 100644 --- a/internal/transport/client/handler/correctness.go +++ b/internal/transport/client/handler/correctness.go @@ -3,9 +3,7 @@ package handler import ( "context" - "github.com/TimeleapLabs/unchained/internal/crypto/bls" "github.com/TimeleapLabs/unchained/internal/model" - "github.com/TimeleapLabs/unchained/internal/utils" ) func (h *consumer) CorrectnessReport(ctx context.Context, message []byte) { @@ -16,18 +14,9 @@ func (h *consumer) CorrectnessReport(ctx context.Context, message []byte) { return } - signature, err := bls.RecoverSignature(packet.Signature) - if err != nil { - utils.Logger. - With("Error", err). - Error("Failed to recover packet signature") - - return - } - err = h.correctness.RecordSignature( ctx, - signature, + packet.Signature[:], packet.Signer, correctnessHash, packet.Info, diff --git a/internal/transport/client/handler/event.go b/internal/transport/client/handler/event.go index a33f9f16..a397f637 100644 --- a/internal/transport/client/handler/event.go +++ b/internal/transport/client/handler/event.go @@ -3,9 +3,7 @@ package handler import ( "context" - "github.com/TimeleapLabs/unchained/internal/crypto/bls" "github.com/TimeleapLabs/unchained/internal/model" - "github.com/TimeleapLabs/unchained/internal/utils" ) func (h *consumer) EventLog(ctx context.Context, message []byte) { @@ -16,18 +14,9 @@ func (h *consumer) EventLog(ctx context.Context, message []byte) { return } - signature, err := bls.RecoverSignature(packet.Signature) - if err != nil { - utils.Logger. - With("Error", err). - Error("Failed to recover packet signature") - - return - } - err = h.evmlog.RecordSignature( ctx, - signature, + packet.Signature[:], packet.Signer, eventLogHash, packet.Info, diff --git a/internal/transport/client/handler/price.go b/internal/transport/client/handler/price.go index 09b34a33..535e4603 100644 --- a/internal/transport/client/handler/price.go +++ b/internal/transport/client/handler/price.go @@ -3,9 +3,7 @@ package handler import ( "context" - "github.com/TimeleapLabs/unchained/internal/crypto/bls" "github.com/TimeleapLabs/unchained/internal/model" - "github.com/TimeleapLabs/unchained/internal/utils" ) func (h *consumer) PriceReport(ctx context.Context, message []byte) { @@ -16,18 +14,9 @@ func (h *consumer) PriceReport(ctx context.Context, message []byte) { return } - signature, err := bls.RecoverSignature(packet.Signature) - if err != nil { - utils.Logger. - With("Error", err). - Error("Failed to recover packet signature") - - return - } - err = h.uniswap.RecordSignature( ctx, - signature, + packet.Signature[:], packet.Signer, priceInfoHash, packet.Info, diff --git a/internal/transport/server/websocket/handler/correctness.go b/internal/transport/server/websocket/handler/correctness.go index c99a9354..0399b13a 100644 --- a/internal/transport/server/websocket/handler/correctness.go +++ b/internal/transport/server/websocket/handler/correctness.go @@ -1,7 +1,6 @@ package handler import ( - "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/model" "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/middleware" "github.com/gorilla/websocket" @@ -14,12 +13,8 @@ func CorrectnessRecord(conn *websocket.Conn, payload []byte) ([]byte, error) { } correctness := new(model.CorrectnessReportPacket).FromBytes(payload) - correctnessHash, err := correctness.Correctness.Bls() - if err != nil { - return []byte{}, consts.ErrInternalError - } - signer, err := middleware.IsMessageValid(conn, correctnessHash, correctness.Signature) + signer, err := middleware.IsMessageValid(conn, correctness.Correctness.Sia().Bytes(), correctness.Signature) if err != nil { return []byte{}, err } diff --git a/internal/transport/server/websocket/handler/event.go b/internal/transport/server/websocket/handler/event.go index 4aa3d206..d2172314 100644 --- a/internal/transport/server/websocket/handler/event.go +++ b/internal/transport/server/websocket/handler/event.go @@ -1,7 +1,6 @@ package handler import ( - "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/model" "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/middleware" "github.com/gorilla/websocket" @@ -14,12 +13,8 @@ func EventLog(conn *websocket.Conn, payload []byte) ([]byte, error) { } priceReport := new(model.EventLogReportPacket).FromBytes(payload) - priceInfoHash, err := priceReport.EventLog.Bls() - if err != nil { - return []byte{}, consts.ErrInternalError - } - signer, err := middleware.IsMessageValid(conn, priceInfoHash, priceReport.Signature) + signer, err := middleware.IsMessageValid(conn, priceReport.EventLog.Sia().Bytes(), priceReport.Signature) if err != nil { return []byte{}, err } diff --git a/internal/transport/server/websocket/handler/kosk.go b/internal/transport/server/websocket/handler/kosk.go index 9555ca70..8f8e3329 100644 --- a/internal/transport/server/websocket/handler/kosk.go +++ b/internal/transport/server/websocket/handler/kosk.go @@ -2,7 +2,6 @@ package handler import ( "github.com/TimeleapLabs/unchained/internal/consts" - "github.com/TimeleapLabs/unchained/internal/crypto/bls" "github.com/TimeleapLabs/unchained/internal/model" "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/middleware" "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/store" @@ -12,12 +11,7 @@ import ( func Kosk(conn *websocket.Conn, payload []byte) error { challenge := new(model.ChallengePacket).FromBytes(payload) - hash, err := bls.Hash(challenge.Random[:]) - if err != nil { - return err - } - - _, err = middleware.IsMessageValid(conn, hash, challenge.Signature) + _, err := middleware.IsMessageValid(conn, challenge.Random[:], challenge.Signature) if err != nil { return consts.ErrInvalidKosk } diff --git a/internal/transport/server/websocket/handler/price.go b/internal/transport/server/websocket/handler/price.go index f56187e9..85eb7c0d 100644 --- a/internal/transport/server/websocket/handler/price.go +++ b/internal/transport/server/websocket/handler/price.go @@ -1,7 +1,6 @@ package handler import ( - "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/model" "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/middleware" "github.com/gorilla/websocket" @@ -15,12 +14,8 @@ func PriceReport(conn *websocket.Conn, payload []byte) ([]byte, error) { } priceReport := new(model.PriceReportPacket).FromBytes(payload) - priceInfoHash, err := priceReport.PriceInfo.Bls() - if err != nil { - return []byte{}, consts.ErrInternalError - } - signer, err := middleware.IsMessageValid(conn, priceInfoHash, priceReport.Signature) + signer, err := middleware.IsMessageValid(conn, priceReport.PriceInfo.Sia().Bytes(), priceReport.Signature) if err != nil { return []byte{}, err } diff --git a/internal/transport/server/websocket/middleware/signature.go b/internal/transport/server/websocket/middleware/signature.go index 4cf3dbde..cf4fdae1 100644 --- a/internal/transport/server/websocket/middleware/signature.go +++ b/internal/transport/server/websocket/middleware/signature.go @@ -3,33 +3,19 @@ package middleware import ( "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/crypto" - "github.com/TimeleapLabs/unchained/internal/crypto/bls" "github.com/TimeleapLabs/unchained/internal/model" "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/store" "github.com/TimeleapLabs/unchained/internal/utils" - bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" "github.com/gorilla/websocket" ) -func IsMessageValid(conn *websocket.Conn, message bls12381.G1Affine, signature [48]byte) (model.Signer, error) { +func IsMessageValid(conn *websocket.Conn, message []byte, signature [48]byte) (model.Signer, error) { signer, ok := store.Signers.Load(conn) if !ok { return model.Signer{}, consts.ErrMissingHello } - signatureBls, err := bls.RecoverSignature(signature) - if err != nil { - utils.Logger.With("Err", err).Error("Can't recover bls signature") - return model.Signer{}, consts.ErrInternalError - } - - pk, err := bls.RecoverPublicKey(signer.PublicKey) - if err != nil { - utils.Logger.With("Err", err).Error("Can't recover pub key pub-key") - return model.Signer{}, consts.ErrInternalError - } - - ok, err = crypto.Identity.Bls.Verify(signatureBls, message, pk) + ok, err := crypto.Identity.Bls.Verify(signature[:], message, signer.PublicKey[:]) if err != nil { utils.Logger.With("Err", err).Error("Can't verify bls") return model.Signer{}, consts.ErrCantVerifyBls From 3d074ed0e3ea804fd77d4b0cb936e755196f29f6 Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Sun, 12 May 2024 09:40:41 +0330 Subject: [PATCH 02/29] =?UTF-8?q?=F0=9F=90=9B=20fix(tss-sign):=20fix=20uni?= =?UTF-8?q?t=20test=20of=20tss=20signing=20>>>=20=E2=8F=B0=204h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .golangci.yml | 2 + cmd/handler/broker.go | 2 +- cmd/handler/consumer.go | 2 +- cmd/handler/worker.go | 2 +- cmd/main.go | 4 +- internal/config/model.go | 2 +- internal/crypto/ethereum/identity.go | 2 +- internal/crypto/identity.go | 22 ++++--- internal/crypto/tss/identity.go | 87 ++++++++++++++++++---------- internal/crypto/tss/identity_test.go | 79 +++++++++++++++---------- 10 files changed, 124 insertions(+), 80 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 3da1aa7a..dc2818b2 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -49,6 +49,8 @@ linters-settings: - "^google.golang.org/protobuf/.+Options$" - "^gopkg.in/yaml.v3.Node$" + nestif: + min-complexity: 8 funlen: # should be decreased to 30 lines: 200 diff --git a/cmd/handler/broker.go b/cmd/handler/broker.go index 9e95a507..33a48403 100644 --- a/cmd/handler/broker.go +++ b/cmd/handler/broker.go @@ -28,7 +28,7 @@ func WithBrokerCmd(cmd *cobra.Command) { cmd.AddCommand(broker) } -// init loads CLI flags of broker command +// init loads CLI flags of broker command. func init() { broker.Flags().StringP( "broker", diff --git a/cmd/handler/consumer.go b/cmd/handler/consumer.go index e6e1ea95..b62e0444 100644 --- a/cmd/handler/consumer.go +++ b/cmd/handler/consumer.go @@ -34,7 +34,7 @@ func WithConsumerCmd(cmd *cobra.Command) { cmd.AddCommand(consumer) } -// init loads CLI flags of consumer command +// init loads CLI flags of consumer command. func init() { consumer.Flags().StringP( "broker", diff --git a/cmd/handler/worker.go b/cmd/handler/worker.go index 5b765102..d8477ada 100644 --- a/cmd/handler/worker.go +++ b/cmd/handler/worker.go @@ -33,7 +33,7 @@ func WithWorkerCmd(cmd *cobra.Command) { cmd.AddCommand(worker) } -// init loads CLI flags of worker command +// init loads CLI flags of worker command. func init() { worker.Flags().StringP( "broker", diff --git a/cmd/main.go b/cmd/main.go index 3c91f2f4..0096e570 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -24,7 +24,7 @@ var root = &cobra.Command{ }, } -// Unchained entrypoint +// Unchained entrypoint. func main() { handler.WithBrokerCmd(root) handler.WithConsumerCmd(root) @@ -36,7 +36,7 @@ func main() { } } -// init loads global CLI flags +// init loads global CLI flags. func init() { root.Flags().BoolVarP(&config.App.System.PrintVersion, "version", "v", false, "Print the Unchained version number and die") root.PersistentFlags().StringVarP(&config.App.System.ConfigPath, "config", "c", "./conf.yaml", "Config file") diff --git a/internal/config/model.go b/internal/config/model.go index ab6ce4d4..7d312387 100644 --- a/internal/config/model.go +++ b/internal/config/model.go @@ -95,7 +95,7 @@ type Secret struct { PublicKey string `env:"PUBLIC_KEY" yaml:"publicKey"` EvmPrivateKey string `env:"EVM_PRIVATE_KEY" yaml:"evmPrivateKey"` - ShortPublicKey [48]byte + ShortPublicKey [48]byte `yaml:"-"` } // Config struct is the main configuration struct of application. diff --git a/internal/crypto/ethereum/identity.go b/internal/crypto/ethereum/identity.go index 2e9246f7..84a9c56a 100644 --- a/internal/crypto/ethereum/identity.go +++ b/internal/crypto/ethereum/identity.go @@ -16,7 +16,7 @@ type Signer struct { Address string } -func (s *Signer) Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) { +func (s *Signer) Verify(_ []byte, _ []byte, _ []byte) (bool, error) { // TODO implement me panic("implement me") } diff --git a/internal/crypto/identity.go b/internal/crypto/identity.go index 8e7e4146..971a853c 100644 --- a/internal/crypto/identity.go +++ b/internal/crypto/identity.go @@ -2,6 +2,7 @@ package crypto import ( "encoding/hex" + "github.com/TimeleapLabs/unchained/internal/config" "github.com/TimeleapLabs/unchained/internal/crypto/bls" "github.com/TimeleapLabs/unchained/internal/crypto/ethereum" @@ -20,7 +21,7 @@ type Signer interface { type MachineIdentity struct { Bls Signer Eth Signer - Tss Signer + Tss *tss.DistributedSigner } // Identity is a global variable that holds machine identity. @@ -72,14 +73,17 @@ func WithEvmSigner() func(machineIdentity *MachineIdentity) error { } // WithTssSigner initialize and will add Tss identity to machine identity. -func WithTssSigner(signers []string, minThreshold int) func(machineIdentity *MachineIdentity) error { - return func(machineIdentity *MachineIdentity) error { - machineIdentity.Tss = tss.NewIdentity(signers, minThreshold) - //machineIdentity.Tss.WriteConfigs() - - return nil - } -} +// func WithTssSigner(signers []string, minThreshold int) func(machineIdentity *MachineIdentity) error { +// return func(machineIdentity *MachineIdentity) error { +// machineIdentity.Tss = tss.NewIdentity( +// signers, +// minThreshold, +// ) +// //machineIdentity.Tss.WriteConfigs() +// +// return nil +// } +//} // WithBlsIdentity initialize and will add Bls identity to machine identity. func WithBlsIdentity() func(machineIdentity *MachineIdentity) error { diff --git a/internal/crypto/tss/identity.go b/internal/crypto/tss/identity.go index 4afa40e0..9ebd6a25 100644 --- a/internal/crypto/tss/identity.go +++ b/internal/crypto/tss/identity.go @@ -1,18 +1,20 @@ package tss import ( + "math/big" + "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/utils" "github.com/bnb-chain/tss-lib/common" "github.com/bnb-chain/tss-lib/ecdsa/keygen" "github.com/bnb-chain/tss-lib/ecdsa/signing" "github.com/bnb-chain/tss-lib/tss" - "math/big" ) // Signer represents a TSS identity. -type Signer struct { +type DistributedSigner struct { ctx *tss.PeerContext + partyIDs tss.UnSortedPartyIDs PartyID *tss.PartyID keyParty *keygen.LocalParty localPartySaved *keygen.LocalPartySaveData @@ -25,35 +27,46 @@ type MessageSigner struct { party *signing.LocalParty } -func (s *Signer) Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) { - //TODO implement me +func (s *DistributedSigner) Verify(_ []byte, _ []byte, _ []byte) (bool, error) { + // TODO implement me panic("implement me") } -func (s *Signer) WriteConfigs() { - //TODO implement me +func (s *DistributedSigner) WriteConfigs() { + // TODO implement me panic("implement me") } // NewSigning will sign a data with tss secret and return signed data. -func (s *Signer) NewSigning(data []byte, out chan tss.Message, end chan<- common.SignatureData) (*MessageSigner, error) { +func (s *DistributedSigner) NewSigning(signers []*DistributedSigner, data []byte, out chan tss.Message, end chan<- common.SignatureData) (*MessageSigner, error) { if !s.localPartySaved.ValidateWithProof() { return &MessageSigner{}, consts.ErrSignerIsNotReady } dataBig := new(big.Int).SetBytes(data) - params := tss.NewParameters(tss.S256(), s.ctx, s.PartyID, s.numberOfPeers, s.minThreshold) + partyIDs := make(tss.UnSortedPartyIDs, len(signers)) + for i, signer := range signers { + partyIDs[i] = signer.PartyID + } + + sortedPartyIDs := tss.SortPartyIDs(partyIDs) + + ctx := tss.NewPeerContext(sortedPartyIDs) + + params := tss.NewParameters(tss.S256(), ctx, s.PartyID, s.numberOfPeers, s.minThreshold) signer := &MessageSigner{ party: signing.NewLocalParty(dataBig, params, *s.localPartySaved, out, end).(*signing.LocalParty), } - go func(signer *MessageSigner) { - err := signer.party.Start() + go func(signer *signing.LocalParty) { + err := signer.Start() if err != nil { panic(err) } - }(signer) + + utils.Logger.With("ID", signer.PartyID().Moniker).Info("New Tss signer started") + }(signer.party) return signer, nil } @@ -75,16 +88,20 @@ func (s *MessageSigner) AckSignature(msg tss.Message) error { return err } - isOK, err := s.party.Update(pMsg) - if err != nil && !isOK { - utils.Logger.Error(err.Error()) + isOK, tssErr := s.party.Update(pMsg) + if tssErr != nil { + utils.Logger.Error(tssErr.Error()) return err } + if !isOK { + return consts.ErrInternalError + } + return nil } -func (s *Signer) Update(msg tss.Message) error { +func (s *DistributedSigner) Update(msg tss.Message) error { if s.keyParty.PartyID() == msg.GetFrom() { return nil } @@ -101,57 +118,63 @@ func (s *Signer) Update(msg tss.Message) error { return err } - isOK, err := s.keyParty.Update(pMsg) - if err != nil && !isOK { - utils.Logger.Error(err.Error()) + isOK, tssErr := s.keyParty.Update(pMsg) + if tssErr != nil { + utils.Logger.Error(tssErr.Error()) return err } + if !isOK { + return consts.ErrInternalError + } + return nil } // NewIdentity creates a new BLS identity. -func NewIdentity(signerID int, signers []string, outCh chan tss.Message, done chan struct{}, minThreshold int) *Signer { +func NewIdentity(signerID int, signers []string, outCh chan tss.Message, done chan struct{}, minThreshold int) *DistributedSigner { partyIDs := make(tss.UnSortedPartyIDs, len(signers)) for i, signer := range signers { party := tss.NewPartyID(signer, signer, big.NewInt(int64(i+1))) partyIDs[i] = party } - signer := &Signer{ + signer := &DistributedSigner{ minThreshold: minThreshold, numberOfPeers: len(signers), //rawPartyID: signers[signerID], - PartyID: partyIDs[signerID], - result: make(chan keygen.LocalPartySaveData, len(signers)), + partyIDs: partyIDs, + PartyID: partyIDs[signerID], + result: make(chan keygen.LocalPartySaveData, len(signers)), } sortedPartyIDs := tss.SortPartyIDs(partyIDs) signer.ctx = tss.NewPeerContext(sortedPartyIDs) - signer.keyParty = keygen.NewLocalParty( + var isOk bool + signer.keyParty, isOk = keygen.NewLocalParty( tss.NewParameters(tss.S256(), signer.ctx, sortedPartyIDs[signerID], len(signers), minThreshold), outCh, signer.result, ).(*keygen.LocalParty) - go func(signer *Signer) { + if !isOk { + panic(consts.ErrInternalError) + } + + go func(signer *DistributedSigner) { err := signer.keyParty.Start() if err != nil { panic(err) } utils.Logger.With("ID", signer.PartyID.Moniker).Info("New Tss party started") - for { - select { - case save := <-signer.result: - signer.localPartySaved = &save - done <- struct{}{} - break - } + for save := range signer.result { + localPartySaved := save + signer.localPartySaved = &localPartySaved + done <- struct{}{} } - }(signer) return signer diff --git a/internal/crypto/tss/identity_test.go b/internal/crypto/tss/identity_test.go index 9d25f842..81e26cb8 100644 --- a/internal/crypto/tss/identity_test.go +++ b/internal/crypto/tss/identity_test.go @@ -2,12 +2,13 @@ package tss import ( "fmt" + "testing" + "github.com/TimeleapLabs/unchained/internal/utils" "github.com/bnb-chain/tss-lib/common" "github.com/bnb-chain/tss-lib/tss" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" - "testing" ) const ( @@ -16,14 +17,14 @@ const ( ) var ( - testData = []byte("HELLO hello") - secondTestData = []byte("HELLO hello 2") - signers = []string{} + testData = []byte("HELLO hello") + + signers = []string{} ) type TssIdentityTestSuite struct { suite.Suite - parties []*Signer + parties []*DistributedSigner } func (s *TssIdentityTestSuite) SetupTest() { @@ -49,19 +50,28 @@ keygen: dest := msg.GetTo() if dest == nil { // broadcast! - for _, P := range s.parties { - if P.PartyID.Index == msg.GetFrom().Index { + for _, p := range s.parties { + if p.PartyID.Index == msg.GetFrom().Index { continue } - go P.Update(msg) + go func(signer *DistributedSigner) { + err := signer.Update(msg) + if err != nil { + utils.Logger.Error(err.Error()) + } + }(p) } } else { // point-to-point! if dest[0].Index == msg.GetFrom().Index { - fmt.Printf("party %d tried to send a message to itself (%d)", dest[0].Index, msg.GetFrom().Index) return } - go s.parties[dest[0].Index].Update(msg) + go func() { + err := s.parties[dest[0].Index].Update(msg) + if err != nil { + utils.Logger.Error(err.Error()) + } + }() } case <-wg: @@ -74,50 +84,55 @@ keygen: } func (s *TssIdentityTestSuite) TestSign() { - outCh := make(chan tss.Message, len(s.parties)) - endCh := make(chan common.SignatureData, len(s.parties)) - msgSigners := []*MessageSigner{} + outCh := make(chan tss.Message, minNumOfSigners+1) + endCh := make(chan common.SignatureData, minNumOfSigners+1) + msgSigners := make([]*MessageSigner, 0, minNumOfSigners+1) - for i := 0; i < numOfSigners; i++ { - go func() { - signer, err := s.parties[i].NewSigning(testData, outCh, endCh) - assert.NoError(s.T(), err) + for i := 0; i < minNumOfSigners+1; i++ { + signer, err := s.parties[i].NewSigning(s.parties[:minNumOfSigners+1], testData, outCh, endCh) + assert.NoError(s.T(), err) - msgSigners = append(msgSigners, signer) - }() + msgSigners = append(msgSigners, signer) } - // wait := 0 - //signing: + wait := 0 +signing: for { select { case msg := <-outCh: dest := msg.GetTo() if dest == nil { - for _, P := range msgSigners { - if P.party.PartyID().Index == msg.GetFrom().Index { + for _, p := range msgSigners { + if p.party.PartyID().Index == msg.GetFrom().Index { continue } - go P.AckSignature(msg) + go func(signer *MessageSigner, msg tss.Message) { + err := signer.AckSignature(msg) + if err != nil { + utils.Logger.Error(err.Error()) + } + }(p, msg) } } else { if dest[0].Index == msg.GetFrom().Index { common.Logger.Fatalf("party %d tried to send a message to itself (%d)", dest[0].Index, msg.GetFrom().Index) } - go msgSigners[dest[0].Index].AckSignature(msg) + go func(signer *MessageSigner, msg tss.Message) { + err := signer.AckSignature(msg) + if err != nil { + utils.Logger.Error(err.Error()) + } + }(msgSigners[dest[0].Index], msg) } case <-endCh: - fmt.Println("end") + wait++ + if wait == numOfSigners-1 { + break signing + } } } - - //s.Run("Should verify the message correctly", func() { - // isVerified, err := s.identity.Verify() - // assert.NoError(s.T(), err) - // assert.True(s.T(), isVerified) - //}) } func TestTssIdentitySuite(t *testing.T) { From 408f4c0b6d0a76581cfa577600b1719a0c4ef730 Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Sun, 12 May 2024 11:25:50 +0330 Subject: [PATCH 03/29] =?UTF-8?q?=E2=9C=A8=20feat(sprating-identity-and-me?= =?UTF-8?q?ssage-signer-of-tss-and-add-some-comments):=20tss=20identity=20?= =?UTF-8?q?>>>=20=E2=8F=B0=2030m?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/crypto/tss/identity.go | 78 ++------------------------- internal/crypto/tss/identity_test.go | 6 +-- internal/crypto/tss/signer.go | 80 ++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 76 deletions(-) create mode 100644 internal/crypto/tss/signer.go diff --git a/internal/crypto/tss/identity.go b/internal/crypto/tss/identity.go index 9ebd6a25..ee6d881b 100644 --- a/internal/crypto/tss/identity.go +++ b/internal/crypto/tss/identity.go @@ -5,13 +5,11 @@ import ( "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/bnb-chain/tss-lib/common" "github.com/bnb-chain/tss-lib/ecdsa/keygen" - "github.com/bnb-chain/tss-lib/ecdsa/signing" "github.com/bnb-chain/tss-lib/tss" ) -// Signer represents a TSS identity. +// DistributedSigner represents a TSS identity. type DistributedSigner struct { ctx *tss.PeerContext partyIDs tss.UnSortedPartyIDs @@ -23,84 +21,18 @@ type DistributedSigner struct { numberOfPeers int } -type MessageSigner struct { - party *signing.LocalParty -} - +// Verify function will check message signature to be valid func (s *DistributedSigner) Verify(_ []byte, _ []byte, _ []byte) (bool, error) { // TODO implement me panic("implement me") } +// WriteConfigs will write identity keys to a persistent storage func (s *DistributedSigner) WriteConfigs() { - // TODO implement me - panic("implement me") -} - -// NewSigning will sign a data with tss secret and return signed data. -func (s *DistributedSigner) NewSigning(signers []*DistributedSigner, data []byte, out chan tss.Message, end chan<- common.SignatureData) (*MessageSigner, error) { - if !s.localPartySaved.ValidateWithProof() { - return &MessageSigner{}, consts.ErrSignerIsNotReady - } - - dataBig := new(big.Int).SetBytes(data) - - partyIDs := make(tss.UnSortedPartyIDs, len(signers)) - for i, signer := range signers { - partyIDs[i] = signer.PartyID - } - - sortedPartyIDs := tss.SortPartyIDs(partyIDs) - - ctx := tss.NewPeerContext(sortedPartyIDs) - - params := tss.NewParameters(tss.S256(), ctx, s.PartyID, s.numberOfPeers, s.minThreshold) - signer := &MessageSigner{ - party: signing.NewLocalParty(dataBig, params, *s.localPartySaved, out, end).(*signing.LocalParty), - } - - go func(signer *signing.LocalParty) { - err := signer.Start() - if err != nil { - panic(err) - } - - utils.Logger.With("ID", signer.PartyID().Moniker).Info("New Tss signer started") - }(signer.party) - - return signer, nil -} - -func (s *MessageSigner) AckSignature(msg tss.Message) error { - if s.party.PartyID() == msg.GetFrom() { - return nil - } - - bz, _, err := msg.WireBytes() - if err != nil { - utils.Logger.Error(err.Error()) - return err - } - - pMsg, err := tss.ParseWireMessage(bz, msg.GetFrom(), msg.IsBroadcast()) - if err != nil { - utils.Logger.Error(err.Error()) - return err - } - - isOK, tssErr := s.party.Update(pMsg) - if tssErr != nil { - utils.Logger.Error(tssErr.Error()) - return err - } - - if !isOK { - return consts.ErrInternalError - } - - return nil + // nothing to do! } +// Update function will update the identity key about other parties func (s *DistributedSigner) Update(msg tss.Message) error { if s.keyParty.PartyID() == msg.GetFrom() { return nil diff --git a/internal/crypto/tss/identity_test.go b/internal/crypto/tss/identity_test.go index 81e26cb8..c8b6458b 100644 --- a/internal/crypto/tss/identity_test.go +++ b/internal/crypto/tss/identity_test.go @@ -35,10 +35,10 @@ func (s *TssIdentityTestSuite) SetupTest() { } outCh := make(chan tss.Message, len(signers)) - wg := make(chan struct{}) + done := make(chan struct{}) for i := 0; i < numOfSigners; i++ { - party := NewIdentity(i, signers, outCh, wg, minNumOfSigners) + party := NewIdentity(i, signers, outCh, done, minNumOfSigners) s.parties = append(s.parties, party) } @@ -74,7 +74,7 @@ keygen: }() } - case <-wg: + case <-done: wait++ if wait == numOfSigners { break keygen diff --git a/internal/crypto/tss/signer.go b/internal/crypto/tss/signer.go new file mode 100644 index 00000000..358268e2 --- /dev/null +++ b/internal/crypto/tss/signer.go @@ -0,0 +1,80 @@ +package tss + +import ( + "github.com/TimeleapLabs/unchained/internal/consts" + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/bnb-chain/tss-lib/common" + "github.com/bnb-chain/tss-lib/ecdsa/signing" + "github.com/bnb-chain/tss-lib/tss" + "math/big" +) + +// MessageSigner represents state of signing of a message. +type MessageSigner struct { + party *signing.LocalParty +} + +// NewSigning will sign a data with tss secret and return signed data. +func (s *DistributedSigner) NewSigning(signers []*DistributedSigner, data []byte, out chan tss.Message, end chan<- common.SignatureData) (*MessageSigner, error) { + if !s.localPartySaved.ValidateWithProof() { + return &MessageSigner{}, consts.ErrSignerIsNotReady + } + + dataBig := new(big.Int).SetBytes(data) + + partyIDs := make(tss.UnSortedPartyIDs, len(signers)) + for i, signer := range signers { + partyIDs[i] = signer.PartyID + } + + sortedPartyIDs := tss.SortPartyIDs(partyIDs) + + ctx := tss.NewPeerContext(sortedPartyIDs) + + params := tss.NewParameters(tss.S256(), ctx, s.PartyID, s.numberOfPeers, s.minThreshold) + signer := &MessageSigner{ + party: signing.NewLocalParty(dataBig, params, *s.localPartySaved, out, end).(*signing.LocalParty), + } + + go func(signer *signing.LocalParty) { + err := signer.Start() + if err != nil { + panic(err) + } + + utils.Logger.With("ID", signer.PartyID().Moniker).Info("New Tss signer started") + }(signer.party) + + return signer, nil +} + +// Acknowledge function will confirm an acceptance from other signers +func (s *MessageSigner) Acknowledge(msg tss.Message) error { + if s.party.PartyID() == msg.GetFrom() { + return nil + } + + bz, _, err := msg.WireBytes() + if err != nil { + utils.Logger.Error(err.Error()) + return err + } + + pMsg, err := tss.ParseWireMessage(bz, msg.GetFrom(), msg.IsBroadcast()) + if err != nil { + utils.Logger.Error(err.Error()) + return err + } + + isOK, tssErr := s.party.Update(pMsg) + if tssErr != nil { + utils.Logger.Error(tssErr.Error()) + return err + } + + if !isOK { + return consts.ErrInternalError + } + + return nil +} From d7c9a664113d2b793916fc8eed51e04434f777c2 Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Sun, 12 May 2024 11:27:21 +0330 Subject: [PATCH 04/29] =?UTF-8?q?=F0=9F=90=9B=20fix(linters):=20fix=20nami?= =?UTF-8?q?ng=20problem=20>>>=20=E2=8F=B0=205m?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/crypto/tss/identity.go | 6 +++--- internal/crypto/tss/identity_test.go | 4 ++-- internal/crypto/tss/signer.go | 5 +++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/internal/crypto/tss/identity.go b/internal/crypto/tss/identity.go index ee6d881b..3db295a0 100644 --- a/internal/crypto/tss/identity.go +++ b/internal/crypto/tss/identity.go @@ -21,18 +21,18 @@ type DistributedSigner struct { numberOfPeers int } -// Verify function will check message signature to be valid +// Verify function will check message signature to be valid. func (s *DistributedSigner) Verify(_ []byte, _ []byte, _ []byte) (bool, error) { // TODO implement me panic("implement me") } -// WriteConfigs will write identity keys to a persistent storage +// WriteConfigs will write identity keys to a persistent storage. func (s *DistributedSigner) WriteConfigs() { // nothing to do! } -// Update function will update the identity key about other parties +// Update function will update the identity key about other parties. func (s *DistributedSigner) Update(msg tss.Message) error { if s.keyParty.PartyID() == msg.GetFrom() { return nil diff --git a/internal/crypto/tss/identity_test.go b/internal/crypto/tss/identity_test.go index c8b6458b..08fda944 100644 --- a/internal/crypto/tss/identity_test.go +++ b/internal/crypto/tss/identity_test.go @@ -108,7 +108,7 @@ signing: } go func(signer *MessageSigner, msg tss.Message) { - err := signer.AckSignature(msg) + err := signer.Acknowledge(msg) if err != nil { utils.Logger.Error(err.Error()) } @@ -120,7 +120,7 @@ signing: } go func(signer *MessageSigner, msg tss.Message) { - err := signer.AckSignature(msg) + err := signer.Acknowledge(msg) if err != nil { utils.Logger.Error(err.Error()) } diff --git a/internal/crypto/tss/signer.go b/internal/crypto/tss/signer.go index 358268e2..d92a66aa 100644 --- a/internal/crypto/tss/signer.go +++ b/internal/crypto/tss/signer.go @@ -1,12 +1,13 @@ package tss import ( + "math/big" + "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/utils" "github.com/bnb-chain/tss-lib/common" "github.com/bnb-chain/tss-lib/ecdsa/signing" "github.com/bnb-chain/tss-lib/tss" - "math/big" ) // MessageSigner represents state of signing of a message. @@ -48,7 +49,7 @@ func (s *DistributedSigner) NewSigning(signers []*DistributedSigner, data []byte return signer, nil } -// Acknowledge function will confirm an acceptance from other signers +// Acknowledge function will confirm an acceptance from other signers. func (s *MessageSigner) Acknowledge(msg tss.Message) error { if s.party.PartyID() == msg.GetFrom() { return nil From 5acf9bb1a5f52ceb148d26f41ad90ecff6e69315 Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Sat, 18 May 2024 22:24:03 +0330 Subject: [PATCH 05/29] =?UTF-8?q?=E2=9C=A8=20feat(frost):=20remove=20tss?= =?UTF-8?q?=20signer=20and=20add=20frost=20algorithm=20>>>=20=E2=8F=B0=201?= =?UTF-8?q?.5d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 12 +- go.sum | 20 +- internal/consts/errors.go | 2 + internal/crypto/bls/bls.go | 47 - internal/crypto/bls/identity.go | 130 - internal/crypto/bls/identity_test.go | 77 - .../ethereum/contracts/UnchainedStaking.go | 2644 ----------------- internal/crypto/ethereum/contracts/UniV3.go | 251 -- internal/crypto/ethereum/identity.go | 89 - internal/crypto/ethereum/rpc.go | 112 - internal/crypto/ethereum/rpc_mock.go | 51 - internal/crypto/identity.go | 96 - internal/crypto/identity_test.go | 32 - internal/crypto/tss/identity.go | 113 - internal/crypto/tss/identity_test.go | 140 - internal/crypto/tss/signer.go | 81 - 16 files changed, 30 insertions(+), 3867 deletions(-) delete mode 100644 internal/crypto/bls/bls.go delete mode 100644 internal/crypto/bls/identity.go delete mode 100644 internal/crypto/bls/identity_test.go delete mode 100644 internal/crypto/ethereum/contracts/UnchainedStaking.go delete mode 100644 internal/crypto/ethereum/contracts/UniV3.go delete mode 100644 internal/crypto/ethereum/identity.go delete mode 100644 internal/crypto/ethereum/rpc.go delete mode 100644 internal/crypto/ethereum/rpc_mock.go delete mode 100644 internal/crypto/identity.go delete mode 100644 internal/crypto/identity_test.go delete mode 100644 internal/crypto/tss/identity.go delete mode 100644 internal/crypto/tss/identity_test.go delete mode 100644 internal/crypto/tss/signer.go diff --git a/go.mod b/go.mod index e1078689..885bfa8e 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/99designs/gqlgen v0.17.45 github.com/bnb-chain/tss-lib v1.3.5 github.com/btcsuite/btcutil v1.0.2 + github.com/bytemare/frost v0.0.0-20231127024126-bc6f7874b253 github.com/consensys/gnark-crypto v0.12.1 github.com/dgraph-io/badger/v4 v4.2.0 github.com/ethereum/go-ethereum v1.13.14 @@ -17,12 +18,10 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/ilyakaznacheev/cleanenv v1.5.0 github.com/jackc/pgx/v5 v5.5.5 - github.com/lastingasset/tss-lib v0.0.0-20221022151431-0bdbdcdfba56 github.com/lib/pq v1.10.9 github.com/lmittmann/tint v1.0.4 github.com/mattn/go-colorable v0.1.13 github.com/peterldowns/pgtestdb v0.0.14 - github.com/pkg/errors v0.9.1 github.com/pouya-eghbali/go-sia/v2 v2.1.0 github.com/puzpuzpuz/xsync/v3 v3.1.0 github.com/spf13/cobra v1.8.0 @@ -36,6 +35,8 @@ require ( require ( ariga.io/atlas v0.20.0 // indirect + filippo.io/edwards25519 v1.0.0 // indirect + filippo.io/nistec v0.0.2 // indirect github.com/BurntSushi/toml v1.3.2 // indirect github.com/DataDog/zstd v1.4.5 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect @@ -48,6 +49,11 @@ require ( github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/btcsuite/btcd v0.20.1-beta // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect + github.com/bytemare/crypto v0.5.2 // indirect + github.com/bytemare/hash v0.1.5 // indirect + github.com/bytemare/hash2curve v0.2.2 // indirect + github.com/bytemare/secp256k1 v0.1.0 // indirect + github.com/bytemare/secret-sharing v0.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cockroachdb/errors v1.8.1 // indirect github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f // indirect @@ -82,6 +88,7 @@ require ( github.com/google/flatbuffers v24.3.7+incompatible // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/gtank/ristretto255 v0.1.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-bexpr v0.1.10 // indirect github.com/hashicorp/hcl/v2 v2.20.0 // indirect @@ -110,6 +117,7 @@ require ( github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opentracing/opentracing-go v1.1.0 // indirect github.com/otiai10/primes v0.0.0-20180210170552-f6d2a1ba97c4 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.12.0 // indirect github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a // indirect diff --git a/go.sum b/go.sum index 7bcddce8..b67ecc45 100644 --- a/go.sum +++ b/go.sum @@ -39,6 +39,10 @@ entgo.io/contrib v0.4.6-0.20240215171353-eff33e4dca0b h1:jJwnBBJavk5NfJNyg8fvEVp entgo.io/contrib v0.4.6-0.20240215171353-eff33e4dca0b/go.mod h1:q8dXQCmzqpSlVdT2bWDydjgznGcy3y4zmsYmVFC9V/U= entgo.io/ent v0.13.1 h1:uD8QwN1h6SNphdCCzmkMN3feSUzNnVvV/WIkHKMbzOE= entgo.io/ent v0.13.1/go.mod h1:qCEmo+biw3ccBn9OyL4ZK5dfpwg++l1Gxwac5B1206A= +filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= +filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= +filippo.io/nistec v0.0.2 h1:/NIXTUimcHIh0E2DsYucHlICvUisgj28/XEnKSEptUs= +filippo.io/nistec v0.0.2/go.mod h1:84fxC9mi+MhC2AERXI4LSa8cmSVOzrFikg6hZ4IfCyw= github.com/99designs/gqlgen v0.17.45 h1:bH0AH67vIJo8JKNKPJP+pOPpQhZeuVRQLf53dKIpDik= github.com/99designs/gqlgen v0.17.45/go.mod h1:Bas0XQ+Jiu/Xm5E33jC8sES3G+iC2esHBMXcq0fUPs0= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= @@ -109,6 +113,18 @@ github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVa github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/bytemare/crypto v0.5.2 h1:ogvfY5mmtrPc5Uhwq4mUEUDnTVig+UEF8gwnNAPaNbU= +github.com/bytemare/crypto v0.5.2/go.mod h1:kkx4ciRQFWcjMauezZo9SHw4YmqSTolWkfOVVTOXgAY= +github.com/bytemare/frost v0.0.0-20231127024126-bc6f7874b253 h1:A7oFaTUn27NTS1quGJDBWz5wE4moUxGUD/5lcvDfGhg= +github.com/bytemare/frost v0.0.0-20231127024126-bc6f7874b253/go.mod h1:oqP0GP7rnoE2B276HqEFhrv1vR3/Zwfwf2QlRKcHLOA= +github.com/bytemare/hash v0.1.5 h1:VW+X1YQ2b3chjRFHkRUnO42uclsQjXimdBCPOgIobR4= +github.com/bytemare/hash v0.1.5/go.mod h1:+QmWXTky/2b63ngqM5IYezGydn9UTFDhpX7mLYwYxCA= +github.com/bytemare/hash2curve v0.2.2 h1:zaGx6Z4/N4Pl9B7aGNtpbZ09vu1NNJGoJRRtHHl8oTw= +github.com/bytemare/hash2curve v0.2.2/go.mod h1:Wma3DmJdn8kqiK9j120hkWvC3tQVKS1PyA8ZzyG23BI= +github.com/bytemare/secp256k1 v0.1.0 h1:kjVJ06GAHSa+EJ7Rz1LdVgE0DQWdvUT77tmcGf7epXQ= +github.com/bytemare/secp256k1 v0.1.0/go.mod h1:hzquMsr3GXhVcqL9qFX7GGjmcT5dlQldKrArd7tcXHE= +github.com/bytemare/secret-sharing v0.1.0 h1:p+5TQw40/JnSMUgSe0OdvUACo9xZuiQDL/eLRPjPd50= +github.com/bytemare/secret-sharing v0.1.0/go.mod h1:NKTAXEhsxrVi2Yr5BCKFP9uhPWDtBStAPbyqLghFG4I= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= @@ -320,6 +336,8 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= +github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -417,8 +435,6 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= -github.com/lastingasset/tss-lib v0.0.0-20221022151431-0bdbdcdfba56 h1:AaQnzJFRrI3NbWkHHN5v7KGS2n2hm7SuL81QdGRBmlQ= -github.com/lastingasset/tss-lib v0.0.0-20221022151431-0bdbdcdfba56/go.mod h1:4ZSo/Of0YmsxTaksO94Y/PcHP5kW3l9j0K95hTqVpi4= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= diff --git a/internal/consts/errors.go b/internal/consts/errors.go index a87fa315..4f7775d6 100644 --- a/internal/consts/errors.go +++ b/internal/consts/errors.go @@ -29,4 +29,6 @@ var ( ErrCrossPriceIsNotZero = errors.New("cross price is not zero") ErrAlreadySynced = errors.New("already synced") ErrSignerIsNotReady = errors.New("signer is not ready yet") + ErrCantSign = errors.New("cant sign message") + ErrCantVerify = errors.New("cant verify message") ) diff --git a/internal/crypto/bls/bls.go b/internal/crypto/bls/bls.go deleted file mode 100644 index 39ac22a0..00000000 --- a/internal/crypto/bls/bls.go +++ /dev/null @@ -1,47 +0,0 @@ -package bls - -import ( - bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" -) - -func Hash(message []byte) (bls12381.G1Affine, error) { - dst := []byte("UNCHAINED") - return bls12381.HashToG1(message, dst) -} - -func RecoverSignature(bytes [48]byte) (bls12381.G1Affine, error) { - signature := new(bls12381.G1Affine) - _, err := signature.SetBytes(bytes[:]) - return *signature, err -} - -func RecoverPublicKey(bytes [96]byte) (bls12381.G2Affine, error) { - pk := new(bls12381.G2Affine) - _, err := pk.SetBytes(bytes[:]) - return *pk, err -} - -func AggregateSignatures(signatures [][]byte) ([]byte, error) { - signaturesBls := []bls12381.G1Affine{} - - for _, signature := range signatures { - signatureBls, err := RecoverSignature([48]byte(signature)) - if err != nil { - return nil, err - } - - signaturesBls = append(signaturesBls, signatureBls) - } - - aggregated := new(bls12381.G1Jac).FromAffine(&signaturesBls[0]) - - for _, sig := range signaturesBls[1:] { - sigJac := new(bls12381.G1Jac).FromAffine(&sig) - aggregated.AddAssign(sigJac) - } - - aggregatedAffine := new(bls12381.G1Affine).FromJacobian(aggregated) - aggregatedAffineByte := aggregatedAffine.Bytes() - - return aggregatedAffineByte[:], nil -} diff --git a/internal/crypto/bls/identity.go b/internal/crypto/bls/identity.go deleted file mode 100644 index 74ed867f..00000000 --- a/internal/crypto/bls/identity.go +++ /dev/null @@ -1,130 +0,0 @@ -package bls - -import ( - "crypto/rand" - "encoding/hex" - "math/big" - - "github.com/TimeleapLabs/unchained/internal/consts" - - "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/btcsuite/btcutil/base58" - bls12381_fr "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" - - "github.com/TimeleapLabs/unchained/internal/utils/address" - - "github.com/TimeleapLabs/unchained/internal/config" - bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" -) - -// Signer represents a BLS identity. -type Signer struct { - Name string - SecretKey *big.Int - PublicKey *bls12381.G2Affine - ShortPublicKey *bls12381.G1Affine - - g2Aff bls12381.G2Affine - g1Aff bls12381.G1Affine -} - -// Sign will sign a data with bls secret and return signed data. -func (s *Signer) Sign(data []byte) ([]byte, error) { - hashedMessage, err := Hash(data) - if err != nil { - panic(err) - } - - signature := new(bls12381.G1Affine).ScalarMultiplication(&hashedMessage, s.SecretKey).Bytes() - - return signature[:], err -} - -// WriteConfigs writes the secret key, public key and address to the global config object. -func (s *Signer) WriteConfigs() { - pkBytes := s.PublicKey.Bytes() - config.App.Secret.SecretKey = hex.EncodeToString(s.SecretKey.Bytes()) - config.App.Secret.PublicKey = hex.EncodeToString(pkBytes[:]) - config.App.Secret.Address = address.Calculate(pkBytes[:]) -} - -// Verify verifies the signature of a message belongs to the public key. -func (s *Signer) Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) { - signatureBls, err := RecoverSignature([48]byte(signature)) - if err != nil { - utils.Logger.With("Err", err).Error("Can't recover bls signature") - return false, consts.ErrInternalError - } - - publicKeyBls, err := RecoverPublicKey([96]byte(publicKey)) - if err != nil { - utils.Logger.With("Err", err).Error("Can't recover pub-key") - return false, consts.ErrInternalError - } - - messageBls, err := Hash(hashedMessage) - if err != nil { - utils.Logger.With("Err", err).Error("Can't convert message to hash") - return false, consts.ErrInternalError - } - - pairingSigG2, err := bls12381.Pair( - []bls12381.G1Affine{signatureBls}, - []bls12381.G2Affine{s.g2Aff}) - if err != nil { - return false, err - } - - pairingHmPk, pairingError := bls12381.Pair( - []bls12381.G1Affine{messageBls}, - []bls12381.G2Affine{publicKeyBls}) - - ok := pairingSigG2.Equal(&pairingHmPk) - - return ok, pairingError -} - -// NewIdentity creates a new BLS identity. -func NewIdentity() *Signer { - s := &Signer{ - SecretKey: new(big.Int), - } - - if config.App.Secret.SecretKey == "" && !config.App.System.AllowGenerateSecrets { - panic("BLS secret key is not provided and secrets generation is not allowed") - } - - _, _, s.g1Aff, s.g2Aff = bls12381.Generators() - - if config.App.Secret.SecretKey != "" { - decoded, err := hex.DecodeString(config.App.Secret.SecretKey) - if err != nil { - // TODO: Backwards compatibility with base58 encoded secret keys - // Remove this after a few releases - decoded = base58.Decode(config.App.Secret.SecretKey) - } - - s.SecretKey.SetBytes(decoded) - s.PublicKey = new(bls12381.G2Affine).ScalarMultiplication(&s.g2Aff, s.SecretKey) - } else { - // generate a random point in G2 - g2Order := bls12381_fr.Modulus() - sk, err := rand.Int(rand.Reader, g2Order) - if err != nil { - panic(err) - } - - pk := new(bls12381.G2Affine).ScalarMultiplication(&s.g2Aff, sk) - - s.SecretKey = sk - s.PublicKey = pk - } - - s.ShortPublicKey = new(bls12381.G1Affine).ScalarMultiplication(&s.g1Aff, s.SecretKey) - - utils.Logger. - With("Address", s.ShortPublicKey.String()). - Info("Unchained identity initialized") - - return s -} diff --git a/internal/crypto/bls/identity_test.go b/internal/crypto/bls/identity_test.go deleted file mode 100644 index 0b530354..00000000 --- a/internal/crypto/bls/identity_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package bls - -import ( - "crypto/rand" - "testing" - - "github.com/TimeleapLabs/unchained/internal/config" - "github.com/TimeleapLabs/unchained/internal/utils" - bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" - bls12381_fr "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" -) - -var ( - testData = []byte("HELLO hello") - secondTestData = []byte("HELLO hello 2") -) - -type BlsIdentityTestSuite struct { - suite.Suite - identity *Signer -} - -func (s *BlsIdentityTestSuite) SetupTest() { - utils.SetupLogger("info") - - config.App.System.AllowGenerateSecrets = true - s.identity = NewIdentity() -} - -func (s *BlsIdentityTestSuite) TestSign() { - signedData, err := s.identity.Sign(testData) - assert.NoError(s.T(), err) - - publicKey := s.identity.PublicKey.Bytes() - - s.Run("Should verify the message correctly", func() { - isVerified, err := s.identity.Verify(signedData, testData, publicKey[:]) - assert.NoError(s.T(), err) - assert.True(s.T(), isVerified) - }) - - s.Run("Should not verify the message because of wrong data case", func() { - isVerified, err := s.identity.Verify(signedData, secondTestData, publicKey[:]) - assert.NoError(s.T(), err) - assert.False(s.T(), isVerified) - }) - - s.Run("Should not verify the message because of wrong data case", func() { - signedSecondData, err := s.identity.Sign(secondTestData) - assert.NoError(s.T(), err) - - isVerified, err := s.identity.Verify(signedSecondData, testData, publicKey[:]) - assert.NoError(s.T(), err) - assert.False(s.T(), isVerified) - }) - - s.Run("Should not verify the message because publicKey is not belong to this message", func() { - _, _, _, g2Aff := bls12381.Generators() - g2Order := bls12381_fr.Modulus() - sk, err := rand.Int(rand.Reader, g2Order) - if err != nil { - panic(err) - } - - pk := new(bls12381.G2Affine).ScalarMultiplication(&g2Aff, sk).Bytes() - - isVerified, err := s.identity.Verify(signedData, secondTestData, pk[:]) - assert.NoError(s.T(), err) - assert.False(s.T(), isVerified) - }) -} - -func TestBlsIdentitySuite(t *testing.T) { - suite.Run(t, new(BlsIdentityTestSuite)) -} diff --git a/internal/crypto/ethereum/contracts/UnchainedStaking.go b/internal/crypto/ethereum/contracts/UnchainedStaking.go deleted file mode 100644 index ed3fa3c4..00000000 --- a/internal/crypto/ethereum/contracts/UnchainedStaking.go +++ /dev/null @@ -1,2644 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package contracts - -import ( - "errors" - "math/big" - "strings" - - 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" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -// UnchainedStakingEIP712SetNftPrice is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingEIP712SetNftPrice struct { - Requester common.Address - NftId *big.Int - Price *big.Int - Nonce *big.Int -} - -// UnchainedStakingEIP712SetNftPriceKey is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingEIP712SetNftPriceKey struct { - NftId *big.Int - Price *big.Int - Nonce *big.Int -} - -// UnchainedStakingEIP712SetParams is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingEIP712SetParams struct { - Requester common.Address - Token common.Address - Nft common.Address - NftTracker common.Address - Threshold *big.Int - Expiration *big.Int - Nonce *big.Int -} - -// UnchainedStakingEIP712SetParamsKey is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingEIP712SetParamsKey struct { - Token common.Address - Nft common.Address - NftTracker common.Address - Threshold *big.Int - Expiration *big.Int - Nonce *big.Int -} - -// UnchainedStakingEIP712SetSigner is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingEIP712SetSigner struct { - Staker common.Address - Signer common.Address -} - -// UnchainedStakingEIP712Transfer is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingEIP712Transfer struct { - Signer common.Address - From common.Address - To common.Address - Amount *big.Int - NftIds []*big.Int - Nonces []*big.Int -} - -// UnchainedStakingEIP712TransferKey is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingEIP712TransferKey struct { - From common.Address - To common.Address - Amount *big.Int - NftIds []*big.Int - Nonces []*big.Int -} - -// UnchainedStakingNftPriceInfo is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingNftPriceInfo struct { - NftId *big.Int - Price *big.Int - Voted *big.Int - Accepted bool -} - -// UnchainedStakingParamsInfo is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingParamsInfo struct { - Token common.Address - Nft common.Address - NftTracker common.Address - Threshold *big.Int - Expiration *big.Int - Voted *big.Int - Nonce *big.Int - Accepted bool -} - -// UnchainedStakingSignature is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingSignature struct { - V uint8 - R [32]byte - S [32]byte -} - -// UnchainedStakingStake is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingStake struct { - Amount *big.Int - Unlock *big.Int - NftIds []*big.Int -} - -// UnchainedStakingTransferInfo is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingTransferInfo struct { - From common.Address - To common.Address - Amount *big.Int - NftIds []*big.Int - Voted *big.Int - Accepted bool - Nonces []*big.Int -} - -// UnchainedStakingMetaData contains all meta data concerning the UnchainedStaking contract. -var UnchainedStakingMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTrackerAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"consensusLock\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AddressInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyStaked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AmountZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BlsNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DurationZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ECDSAInvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"ECDSAInvalidSignatureLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"ECDSAInvalidSignatureS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Forbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"NonceUsed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotUnlocked\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"StakeExpiresBeforeVote\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StakeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"TopicExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"VotingPowerZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNFT\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"from\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"to\",\"type\":\"bytes32\"}],\"name\":\"BlsAddressChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unlock\",\"type\":\"uint256\"}],\"name\":\"Extended\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"ParamsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"SignerChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"StakeIncreased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"Staked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"UnStaked\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"evm\",\"type\":\"address\"}],\"name\":\"blsAddressOf\",\"outputs\":[{\"internalType\":\"bytes20\",\"name\":\"\",\"type\":\"bytes20\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"bls\",\"type\":\"bytes20\"}],\"name\":\"evmAddressOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"}],\"name\":\"extend\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConsensusThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"}],\"name\":\"getNftPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getParams\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"accepted\",\"type\":\"bool\"}],\"internalType\":\"structUnchainedStaking.ParamsInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetNftPriceKey\",\"name\":\"key\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"getRequestedSetNftPrice\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetParamsKey\",\"name\":\"key\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"getRequestedSetParams\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.EIP712TransferKey\",\"name\":\"key\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"transferer\",\"type\":\"address\"}],\"name\":\"getRequestedTransfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetNftPriceKey\",\"name\":\"key\",\"type\":\"tuple\"}],\"name\":\"getSetNftPriceData\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"accepted\",\"type\":\"bool\"}],\"internalType\":\"structUnchainedStaking.NftPriceInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetParamsKey\",\"name\":\"key\",\"type\":\"tuple\"}],\"name\":\"getSetParamsData\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"accepted\",\"type\":\"bool\"}],\"internalType\":\"structUnchainedStaking.ParamsInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"evm\",\"type\":\"address\"}],\"name\":\"getStake\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.Stake\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"bls\",\"type\":\"bytes20\"}],\"name\":\"getStake\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.Stake\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalVotingPower\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.EIP712TransferKey\",\"name\":\"key\",\"type\":\"tuple\"}],\"name\":\"getTransferData\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"accepted\",\"type\":\"bool\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.TransferInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"bls\",\"type\":\"bytes20\"}],\"name\":\"getVotingPower\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"evm\",\"type\":\"address\"}],\"name\":\"getVotingPower\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"increaseStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"blsAddress\",\"type\":\"bytes20\"}],\"name\":\"setBlsAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetNftPrice[]\",\"name\":\"eip712SetNftPrices\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"}],\"name\":\"setNftPrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetParams[]\",\"name\":\"eip712SetParams\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"}],\"name\":\"setParams\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"internalType\":\"structUnchainedStaking.EIP712SetSigner\",\"name\":\"eip712SetSigner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"stakerSignature\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signerSignature\",\"type\":\"tuple\"}],\"name\":\"setSigner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"signerToStaker\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"stake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"}],\"name\":\"stakerToSigner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.EIP712Transfer[]\",\"name\":\"eip712Transferes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unstake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetParams\",\"name\":\"eip712SetParam\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signature\",\"type\":\"tuple\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetNftPrice\",\"name\":\"eip712SetNftPrice\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signature\",\"type\":\"tuple\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"internalType\":\"structUnchainedStaking.EIP712SetSigner\",\"name\":\"eip712SetSigner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"stakerSignature\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signerSignature\",\"type\":\"tuple\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.EIP712Transfer\",\"name\":\"eip712Transfer\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signature\",\"type\":\"tuple\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", -} - -// UnchainedStakingABI is the input ABI used to generate the binding from. -// Deprecated: Use UnchainedStakingMetaData.ABI instead. -var UnchainedStakingABI = UnchainedStakingMetaData.ABI - -// UnchainedStaking is an auto generated Go binding around an Ethereum contract. -type UnchainedStaking struct { - UnchainedStakingCaller // Read-only binding to the contract - UnchainedStakingTransactor // Write-only binding to the contract - UnchainedStakingFilterer // Log filterer for contract events -} - -// UnchainedStakingCaller is an auto generated read-only Go binding around an Ethereum contract. -type UnchainedStakingCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// UnchainedStakingTransactor is an auto generated write-only Go binding around an Ethereum contract. -type UnchainedStakingTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// UnchainedStakingFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type UnchainedStakingFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// UnchainedStakingSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type UnchainedStakingSession struct { - Contract *UnchainedStaking // 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 -} - -// UnchainedStakingCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type UnchainedStakingCallerSession struct { - Contract *UnchainedStakingCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// UnchainedStakingTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type UnchainedStakingTransactorSession struct { - Contract *UnchainedStakingTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// UnchainedStakingRaw is an auto generated low-level Go binding around an Ethereum contract. -type UnchainedStakingRaw struct { - Contract *UnchainedStaking // Generic contract binding to access the raw methods on -} - -// UnchainedStakingCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type UnchainedStakingCallerRaw struct { - Contract *UnchainedStakingCaller // Generic read-only contract binding to access the raw methods on -} - -// UnchainedStakingTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type UnchainedStakingTransactorRaw struct { - Contract *UnchainedStakingTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewUnchainedStaking creates a new instance of UnchainedStaking, bound to a specific deployed contract. -func NewUnchainedStaking(address common.Address, backend bind.ContractBackend) (*UnchainedStaking, error) { - contract, err := bindUnchainedStaking(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &UnchainedStaking{UnchainedStakingCaller: UnchainedStakingCaller{contract: contract}, UnchainedStakingTransactor: UnchainedStakingTransactor{contract: contract}, UnchainedStakingFilterer: UnchainedStakingFilterer{contract: contract}}, nil -} - -// NewUnchainedStakingCaller creates a new read-only instance of UnchainedStaking, bound to a specific deployed contract. -func NewUnchainedStakingCaller(address common.Address, caller bind.ContractCaller) (*UnchainedStakingCaller, error) { - contract, err := bindUnchainedStaking(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &UnchainedStakingCaller{contract: contract}, nil -} - -// NewUnchainedStakingTransactor creates a new write-only instance of UnchainedStaking, bound to a specific deployed contract. -func NewUnchainedStakingTransactor(address common.Address, transactor bind.ContractTransactor) (*UnchainedStakingTransactor, error) { - contract, err := bindUnchainedStaking(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &UnchainedStakingTransactor{contract: contract}, nil -} - -// NewUnchainedStakingFilterer creates a new log filterer instance of UnchainedStaking, bound to a specific deployed contract. -func NewUnchainedStakingFilterer(address common.Address, filterer bind.ContractFilterer) (*UnchainedStakingFilterer, error) { - contract, err := bindUnchainedStaking(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &UnchainedStakingFilterer{contract: contract}, nil -} - -// bindUnchainedStaking binds a generic wrapper to an already deployed contract. -func bindUnchainedStaking(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := UnchainedStakingMetaData.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 (_UnchainedStaking *UnchainedStakingRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UnchainedStaking.Contract.UnchainedStakingCaller.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 (_UnchainedStaking *UnchainedStakingRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UnchainedStaking.Contract.UnchainedStakingTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_UnchainedStaking *UnchainedStakingRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UnchainedStaking.Contract.UnchainedStakingTransactor.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 (_UnchainedStaking *UnchainedStakingCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UnchainedStaking.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 (_UnchainedStaking *UnchainedStakingTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UnchainedStaking.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_UnchainedStaking *UnchainedStakingTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UnchainedStaking.Contract.contract.Transact(opts, method, params...) -} - -// BlsAddressOf is a free data retrieval call binding the contract method 0x9e95a1a5. -// -// Solidity: function blsAddressOf(address evm) view returns(bytes20) -func (_UnchainedStaking *UnchainedStakingCaller) BlsAddressOf(opts *bind.CallOpts, evm common.Address) ([20]byte, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "blsAddressOf", evm) - - if err != nil { - return *new([20]byte), err - } - - out0 := *abi.ConvertType(out[0], new([20]byte)).(*[20]byte) - - return out0, err - -} - -// BlsAddressOf is a free data retrieval call binding the contract method 0x9e95a1a5. -// -// Solidity: function blsAddressOf(address evm) view returns(bytes20) -func (_UnchainedStaking *UnchainedStakingSession) BlsAddressOf(evm common.Address) ([20]byte, error) { - return _UnchainedStaking.Contract.BlsAddressOf(&_UnchainedStaking.CallOpts, evm) -} - -// BlsAddressOf is a free data retrieval call binding the contract method 0x9e95a1a5. -// -// Solidity: function blsAddressOf(address evm) view returns(bytes20) -func (_UnchainedStaking *UnchainedStakingCallerSession) BlsAddressOf(evm common.Address) ([20]byte, error) { - return _UnchainedStaking.Contract.BlsAddressOf(&_UnchainedStaking.CallOpts, evm) -} - -// EvmAddressOf is a free data retrieval call binding the contract method 0x40043ead. -// -// Solidity: function evmAddressOf(bytes20 bls) view returns(address) -func (_UnchainedStaking *UnchainedStakingCaller) EvmAddressOf(opts *bind.CallOpts, bls [20]byte) (common.Address, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "evmAddressOf", bls) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// EvmAddressOf is a free data retrieval call binding the contract method 0x40043ead. -// -// Solidity: function evmAddressOf(bytes20 bls) view returns(address) -func (_UnchainedStaking *UnchainedStakingSession) EvmAddressOf(bls [20]byte) (common.Address, error) { - return _UnchainedStaking.Contract.EvmAddressOf(&_UnchainedStaking.CallOpts, bls) -} - -// EvmAddressOf is a free data retrieval call binding the contract method 0x40043ead. -// -// Solidity: function evmAddressOf(bytes20 bls) view returns(address) -func (_UnchainedStaking *UnchainedStakingCallerSession) EvmAddressOf(bls [20]byte) (common.Address, error) { - return _UnchainedStaking.Contract.EvmAddressOf(&_UnchainedStaking.CallOpts, bls) -} - -// GetChainId is a free data retrieval call binding the contract method 0x3408e470. -// -// Solidity: function getChainId() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCaller) GetChainId(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getChainId") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetChainId is a free data retrieval call binding the contract method 0x3408e470. -// -// Solidity: function getChainId() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingSession) GetChainId() (*big.Int, error) { - return _UnchainedStaking.Contract.GetChainId(&_UnchainedStaking.CallOpts) -} - -// GetChainId is a free data retrieval call binding the contract method 0x3408e470. -// -// Solidity: function getChainId() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetChainId() (*big.Int, error) { - return _UnchainedStaking.Contract.GetChainId(&_UnchainedStaking.CallOpts) -} - -// GetConsensusThreshold is a free data retrieval call binding the contract method 0xd42791e1. -// -// Solidity: function getConsensusThreshold() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCaller) GetConsensusThreshold(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getConsensusThreshold") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetConsensusThreshold is a free data retrieval call binding the contract method 0xd42791e1. -// -// Solidity: function getConsensusThreshold() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingSession) GetConsensusThreshold() (*big.Int, error) { - return _UnchainedStaking.Contract.GetConsensusThreshold(&_UnchainedStaking.CallOpts) -} - -// GetConsensusThreshold is a free data retrieval call binding the contract method 0xd42791e1. -// -// Solidity: function getConsensusThreshold() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetConsensusThreshold() (*big.Int, error) { - return _UnchainedStaking.Contract.GetConsensusThreshold(&_UnchainedStaking.CallOpts) -} - -// GetNftPrice is a free data retrieval call binding the contract method 0x7bf0989a. -// -// Solidity: function getNftPrice(uint256 nftId) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCaller) GetNftPrice(opts *bind.CallOpts, nftId *big.Int) (*big.Int, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getNftPrice", nftId) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetNftPrice is a free data retrieval call binding the contract method 0x7bf0989a. -// -// Solidity: function getNftPrice(uint256 nftId) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingSession) GetNftPrice(nftId *big.Int) (*big.Int, error) { - return _UnchainedStaking.Contract.GetNftPrice(&_UnchainedStaking.CallOpts, nftId) -} - -// GetNftPrice is a free data retrieval call binding the contract method 0x7bf0989a. -// -// Solidity: function getNftPrice(uint256 nftId) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetNftPrice(nftId *big.Int) (*big.Int, error) { - return _UnchainedStaking.Contract.GetNftPrice(&_UnchainedStaking.CallOpts, nftId) -} - -// GetParams is a free data retrieval call binding the contract method 0x5e615a6b. -// -// Solidity: function getParams() view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingCaller) GetParams(opts *bind.CallOpts) (UnchainedStakingParamsInfo, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getParams") - - if err != nil { - return *new(UnchainedStakingParamsInfo), err - } - - out0 := *abi.ConvertType(out[0], new(UnchainedStakingParamsInfo)).(*UnchainedStakingParamsInfo) - - return out0, err - -} - -// GetParams is a free data retrieval call binding the contract method 0x5e615a6b. -// -// Solidity: function getParams() view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingSession) GetParams() (UnchainedStakingParamsInfo, error) { - return _UnchainedStaking.Contract.GetParams(&_UnchainedStaking.CallOpts) -} - -// GetParams is a free data retrieval call binding the contract method 0x5e615a6b. -// -// Solidity: function getParams() view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetParams() (UnchainedStakingParamsInfo, error) { - return _UnchainedStaking.Contract.GetParams(&_UnchainedStaking.CallOpts) -} - -// GetRequestedSetNftPrice is a free data retrieval call binding the contract method 0x45a6e62f. -// -// Solidity: function getRequestedSetNftPrice((uint256,uint256,uint256) key, address requester) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCaller) GetRequestedSetNftPrice(opts *bind.CallOpts, key UnchainedStakingEIP712SetNftPriceKey, requester common.Address) (bool, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getRequestedSetNftPrice", key, requester) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// GetRequestedSetNftPrice is a free data retrieval call binding the contract method 0x45a6e62f. -// -// Solidity: function getRequestedSetNftPrice((uint256,uint256,uint256) key, address requester) view returns(bool) -func (_UnchainedStaking *UnchainedStakingSession) GetRequestedSetNftPrice(key UnchainedStakingEIP712SetNftPriceKey, requester common.Address) (bool, error) { - return _UnchainedStaking.Contract.GetRequestedSetNftPrice(&_UnchainedStaking.CallOpts, key, requester) -} - -// GetRequestedSetNftPrice is a free data retrieval call binding the contract method 0x45a6e62f. -// -// Solidity: function getRequestedSetNftPrice((uint256,uint256,uint256) key, address requester) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetRequestedSetNftPrice(key UnchainedStakingEIP712SetNftPriceKey, requester common.Address) (bool, error) { - return _UnchainedStaking.Contract.GetRequestedSetNftPrice(&_UnchainedStaking.CallOpts, key, requester) -} - -// GetRequestedSetParams is a free data retrieval call binding the contract method 0x984d92e8. -// -// Solidity: function getRequestedSetParams((address,address,address,uint256,uint256,uint256) key, address requester) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCaller) GetRequestedSetParams(opts *bind.CallOpts, key UnchainedStakingEIP712SetParamsKey, requester common.Address) (bool, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getRequestedSetParams", key, requester) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// GetRequestedSetParams is a free data retrieval call binding the contract method 0x984d92e8. -// -// Solidity: function getRequestedSetParams((address,address,address,uint256,uint256,uint256) key, address requester) view returns(bool) -func (_UnchainedStaking *UnchainedStakingSession) GetRequestedSetParams(key UnchainedStakingEIP712SetParamsKey, requester common.Address) (bool, error) { - return _UnchainedStaking.Contract.GetRequestedSetParams(&_UnchainedStaking.CallOpts, key, requester) -} - -// GetRequestedSetParams is a free data retrieval call binding the contract method 0x984d92e8. -// -// Solidity: function getRequestedSetParams((address,address,address,uint256,uint256,uint256) key, address requester) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetRequestedSetParams(key UnchainedStakingEIP712SetParamsKey, requester common.Address) (bool, error) { - return _UnchainedStaking.Contract.GetRequestedSetParams(&_UnchainedStaking.CallOpts, key, requester) -} - -// GetRequestedTransfer is a free data retrieval call binding the contract method 0xf8560edb. -// -// Solidity: function getRequestedTransfer((address,address,uint256,uint256[],uint256[]) key, address transferer) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCaller) GetRequestedTransfer(opts *bind.CallOpts, key UnchainedStakingEIP712TransferKey, transferer common.Address) (bool, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getRequestedTransfer", key, transferer) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// GetRequestedTransfer is a free data retrieval call binding the contract method 0xf8560edb. -// -// Solidity: function getRequestedTransfer((address,address,uint256,uint256[],uint256[]) key, address transferer) view returns(bool) -func (_UnchainedStaking *UnchainedStakingSession) GetRequestedTransfer(key UnchainedStakingEIP712TransferKey, transferer common.Address) (bool, error) { - return _UnchainedStaking.Contract.GetRequestedTransfer(&_UnchainedStaking.CallOpts, key, transferer) -} - -// GetRequestedTransfer is a free data retrieval call binding the contract method 0xf8560edb. -// -// Solidity: function getRequestedTransfer((address,address,uint256,uint256[],uint256[]) key, address transferer) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetRequestedTransfer(key UnchainedStakingEIP712TransferKey, transferer common.Address) (bool, error) { - return _UnchainedStaking.Contract.GetRequestedTransfer(&_UnchainedStaking.CallOpts, key, transferer) -} - -// GetSetNftPriceData is a free data retrieval call binding the contract method 0xbbb5b849. -// -// Solidity: function getSetNftPriceData((uint256,uint256,uint256) key) view returns((uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingCaller) GetSetNftPriceData(opts *bind.CallOpts, key UnchainedStakingEIP712SetNftPriceKey) (UnchainedStakingNftPriceInfo, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getSetNftPriceData", key) - - if err != nil { - return *new(UnchainedStakingNftPriceInfo), err - } - - out0 := *abi.ConvertType(out[0], new(UnchainedStakingNftPriceInfo)).(*UnchainedStakingNftPriceInfo) - - return out0, err - -} - -// GetSetNftPriceData is a free data retrieval call binding the contract method 0xbbb5b849. -// -// Solidity: function getSetNftPriceData((uint256,uint256,uint256) key) view returns((uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingSession) GetSetNftPriceData(key UnchainedStakingEIP712SetNftPriceKey) (UnchainedStakingNftPriceInfo, error) { - return _UnchainedStaking.Contract.GetSetNftPriceData(&_UnchainedStaking.CallOpts, key) -} - -// GetSetNftPriceData is a free data retrieval call binding the contract method 0xbbb5b849. -// -// Solidity: function getSetNftPriceData((uint256,uint256,uint256) key) view returns((uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetSetNftPriceData(key UnchainedStakingEIP712SetNftPriceKey) (UnchainedStakingNftPriceInfo, error) { - return _UnchainedStaking.Contract.GetSetNftPriceData(&_UnchainedStaking.CallOpts, key) -} - -// GetSetParamsData is a free data retrieval call binding the contract method 0x300fab4f. -// -// Solidity: function getSetParamsData((address,address,address,uint256,uint256,uint256) key) view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingCaller) GetSetParamsData(opts *bind.CallOpts, key UnchainedStakingEIP712SetParamsKey) (UnchainedStakingParamsInfo, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getSetParamsData", key) - - if err != nil { - return *new(UnchainedStakingParamsInfo), err - } - - out0 := *abi.ConvertType(out[0], new(UnchainedStakingParamsInfo)).(*UnchainedStakingParamsInfo) - - return out0, err - -} - -// GetSetParamsData is a free data retrieval call binding the contract method 0x300fab4f. -// -// Solidity: function getSetParamsData((address,address,address,uint256,uint256,uint256) key) view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingSession) GetSetParamsData(key UnchainedStakingEIP712SetParamsKey) (UnchainedStakingParamsInfo, error) { - return _UnchainedStaking.Contract.GetSetParamsData(&_UnchainedStaking.CallOpts, key) -} - -// GetSetParamsData is a free data retrieval call binding the contract method 0x300fab4f. -// -// Solidity: function getSetParamsData((address,address,address,uint256,uint256,uint256) key) view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetSetParamsData(key UnchainedStakingEIP712SetParamsKey) (UnchainedStakingParamsInfo, error) { - return _UnchainedStaking.Contract.GetSetParamsData(&_UnchainedStaking.CallOpts, key) -} - -// GetStake is a free data retrieval call binding the contract method 0x7a766460. -// -// Solidity: function getStake(address evm) view returns((uint256,uint256,uint256[])) -func (_UnchainedStaking *UnchainedStakingCaller) GetStake(opts *bind.CallOpts, evm common.Address) (UnchainedStakingStake, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getStake", evm) - - if err != nil { - return *new(UnchainedStakingStake), err - } - - out0 := *abi.ConvertType(out[0], new(UnchainedStakingStake)).(*UnchainedStakingStake) - - return out0, err - -} - -// GetStake is a free data retrieval call binding the contract method 0x7a766460. -// -// Solidity: function getStake(address evm) view returns((uint256,uint256,uint256[])) -func (_UnchainedStaking *UnchainedStakingSession) GetStake(evm common.Address) (UnchainedStakingStake, error) { - return _UnchainedStaking.Contract.GetStake(&_UnchainedStaking.CallOpts, evm) -} - -// GetStake is a free data retrieval call binding the contract method 0x7a766460. -// -// Solidity: function getStake(address evm) view returns((uint256,uint256,uint256[])) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetStake(evm common.Address) (UnchainedStakingStake, error) { - return _UnchainedStaking.Contract.GetStake(&_UnchainedStaking.CallOpts, evm) -} - -// GetStake0 is a free data retrieval call binding the contract method 0xf86fec69. -// -// Solidity: function getStake(bytes20 bls) view returns((uint256,uint256,uint256[])) -func (_UnchainedStaking *UnchainedStakingCaller) GetStake0(opts *bind.CallOpts, bls [20]byte) (UnchainedStakingStake, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getStake0", bls) - - if err != nil { - return *new(UnchainedStakingStake), err - } - - out0 := *abi.ConvertType(out[0], new(UnchainedStakingStake)).(*UnchainedStakingStake) - - return out0, err - -} - -// GetStake0 is a free data retrieval call binding the contract method 0xf86fec69. -// -// Solidity: function getStake(bytes20 bls) view returns((uint256,uint256,uint256[])) -func (_UnchainedStaking *UnchainedStakingSession) GetStake0(bls [20]byte) (UnchainedStakingStake, error) { - return _UnchainedStaking.Contract.GetStake0(&_UnchainedStaking.CallOpts, bls) -} - -// GetStake0 is a free data retrieval call binding the contract method 0xf86fec69. -// -// Solidity: function getStake(bytes20 bls) view returns((uint256,uint256,uint256[])) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetStake0(bls [20]byte) (UnchainedStakingStake, error) { - return _UnchainedStaking.Contract.GetStake0(&_UnchainedStaking.CallOpts, bls) -} - -// GetTotalVotingPower is a free data retrieval call binding the contract method 0x11acc1a7. -// -// Solidity: function getTotalVotingPower() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCaller) GetTotalVotingPower(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getTotalVotingPower") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetTotalVotingPower is a free data retrieval call binding the contract method 0x11acc1a7. -// -// Solidity: function getTotalVotingPower() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingSession) GetTotalVotingPower() (*big.Int, error) { - return _UnchainedStaking.Contract.GetTotalVotingPower(&_UnchainedStaking.CallOpts) -} - -// GetTotalVotingPower is a free data retrieval call binding the contract method 0x11acc1a7. -// -// Solidity: function getTotalVotingPower() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetTotalVotingPower() (*big.Int, error) { - return _UnchainedStaking.Contract.GetTotalVotingPower(&_UnchainedStaking.CallOpts) -} - -// GetTransferData is a free data retrieval call binding the contract method 0x865e1281. -// -// Solidity: function getTransferData((address,address,uint256,uint256[],uint256[]) key) view returns((address,address,uint256,uint256[],uint256,bool,uint256[])) -func (_UnchainedStaking *UnchainedStakingCaller) GetTransferData(opts *bind.CallOpts, key UnchainedStakingEIP712TransferKey) (UnchainedStakingTransferInfo, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getTransferData", key) - - if err != nil { - return *new(UnchainedStakingTransferInfo), err - } - - out0 := *abi.ConvertType(out[0], new(UnchainedStakingTransferInfo)).(*UnchainedStakingTransferInfo) - - return out0, err - -} - -// GetTransferData is a free data retrieval call binding the contract method 0x865e1281. -// -// Solidity: function getTransferData((address,address,uint256,uint256[],uint256[]) key) view returns((address,address,uint256,uint256[],uint256,bool,uint256[])) -func (_UnchainedStaking *UnchainedStakingSession) GetTransferData(key UnchainedStakingEIP712TransferKey) (UnchainedStakingTransferInfo, error) { - return _UnchainedStaking.Contract.GetTransferData(&_UnchainedStaking.CallOpts, key) -} - -// GetTransferData is a free data retrieval call binding the contract method 0x865e1281. -// -// Solidity: function getTransferData((address,address,uint256,uint256[],uint256[]) key) view returns((address,address,uint256,uint256[],uint256,bool,uint256[])) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetTransferData(key UnchainedStakingEIP712TransferKey) (UnchainedStakingTransferInfo, error) { - return _UnchainedStaking.Contract.GetTransferData(&_UnchainedStaking.CallOpts, key) -} - -// GetVotingPower is a free data retrieval call binding the contract method 0x68eacf93. -// -// Solidity: function getVotingPower(bytes20 bls) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCaller) GetVotingPower(opts *bind.CallOpts, bls [20]byte) (*big.Int, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getVotingPower", bls) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetVotingPower is a free data retrieval call binding the contract method 0x68eacf93. -// -// Solidity: function getVotingPower(bytes20 bls) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingSession) GetVotingPower(bls [20]byte) (*big.Int, error) { - return _UnchainedStaking.Contract.GetVotingPower(&_UnchainedStaking.CallOpts, bls) -} - -// GetVotingPower is a free data retrieval call binding the contract method 0x68eacf93. -// -// Solidity: function getVotingPower(bytes20 bls) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetVotingPower(bls [20]byte) (*big.Int, error) { - return _UnchainedStaking.Contract.GetVotingPower(&_UnchainedStaking.CallOpts, bls) -} - -// GetVotingPower0 is a free data retrieval call binding the contract method 0xbb4d4436. -// -// Solidity: function getVotingPower(address evm) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCaller) GetVotingPower0(opts *bind.CallOpts, evm common.Address) (*big.Int, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getVotingPower0", evm) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetVotingPower0 is a free data retrieval call binding the contract method 0xbb4d4436. -// -// Solidity: function getVotingPower(address evm) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingSession) GetVotingPower0(evm common.Address) (*big.Int, error) { - return _UnchainedStaking.Contract.GetVotingPower0(&_UnchainedStaking.CallOpts, evm) -} - -// GetVotingPower0 is a free data retrieval call binding the contract method 0xbb4d4436. -// -// Solidity: function getVotingPower(address evm) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetVotingPower0(evm common.Address) (*big.Int, error) { - return _UnchainedStaking.Contract.GetVotingPower0(&_UnchainedStaking.CallOpts, evm) -} - -// OnERC721Received is a free data retrieval call binding the contract method 0x150b7a02. -// -// Solidity: function onERC721Received(address , address , uint256 , bytes ) view returns(bytes4) -func (_UnchainedStaking *UnchainedStakingCaller) OnERC721Received(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 []byte) ([4]byte, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "onERC721Received", arg0, arg1, arg2, arg3) - - if err != nil { - return *new([4]byte), err - } - - out0 := *abi.ConvertType(out[0], new([4]byte)).(*[4]byte) - - return out0, err - -} - -// OnERC721Received is a free data retrieval call binding the contract method 0x150b7a02. -// -// Solidity: function onERC721Received(address , address , uint256 , bytes ) view returns(bytes4) -func (_UnchainedStaking *UnchainedStakingSession) OnERC721Received(arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 []byte) ([4]byte, error) { - return _UnchainedStaking.Contract.OnERC721Received(&_UnchainedStaking.CallOpts, arg0, arg1, arg2, arg3) -} - -// OnERC721Received is a free data retrieval call binding the contract method 0x150b7a02. -// -// Solidity: function onERC721Received(address , address , uint256 , bytes ) view returns(bytes4) -func (_UnchainedStaking *UnchainedStakingCallerSession) OnERC721Received(arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 []byte) ([4]byte, error) { - return _UnchainedStaking.Contract.OnERC721Received(&_UnchainedStaking.CallOpts, arg0, arg1, arg2, arg3) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UnchainedStaking *UnchainedStakingCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _UnchainedStaking.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 (_UnchainedStaking *UnchainedStakingSession) Owner() (common.Address, error) { - return _UnchainedStaking.Contract.Owner(&_UnchainedStaking.CallOpts) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UnchainedStaking *UnchainedStakingCallerSession) Owner() (common.Address, error) { - return _UnchainedStaking.Contract.Owner(&_UnchainedStaking.CallOpts) -} - -// SignerToStaker is a free data retrieval call binding the contract method 0xad5a98c5. -// -// Solidity: function signerToStaker(address signer) view returns(address) -func (_UnchainedStaking *UnchainedStakingCaller) SignerToStaker(opts *bind.CallOpts, signer common.Address) (common.Address, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "signerToStaker", signer) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// SignerToStaker is a free data retrieval call binding the contract method 0xad5a98c5. -// -// Solidity: function signerToStaker(address signer) view returns(address) -func (_UnchainedStaking *UnchainedStakingSession) SignerToStaker(signer common.Address) (common.Address, error) { - return _UnchainedStaking.Contract.SignerToStaker(&_UnchainedStaking.CallOpts, signer) -} - -// SignerToStaker is a free data retrieval call binding the contract method 0xad5a98c5. -// -// Solidity: function signerToStaker(address signer) view returns(address) -func (_UnchainedStaking *UnchainedStakingCallerSession) SignerToStaker(signer common.Address) (common.Address, error) { - return _UnchainedStaking.Contract.SignerToStaker(&_UnchainedStaking.CallOpts, signer) -} - -// StakerToSigner is a free data retrieval call binding the contract method 0xc7bcae78. -// -// Solidity: function stakerToSigner(address staker) view returns(address) -func (_UnchainedStaking *UnchainedStakingCaller) StakerToSigner(opts *bind.CallOpts, staker common.Address) (common.Address, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "stakerToSigner", staker) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// StakerToSigner is a free data retrieval call binding the contract method 0xc7bcae78. -// -// Solidity: function stakerToSigner(address staker) view returns(address) -func (_UnchainedStaking *UnchainedStakingSession) StakerToSigner(staker common.Address) (common.Address, error) { - return _UnchainedStaking.Contract.StakerToSigner(&_UnchainedStaking.CallOpts, staker) -} - -// StakerToSigner is a free data retrieval call binding the contract method 0xc7bcae78. -// -// Solidity: function stakerToSigner(address staker) view returns(address) -func (_UnchainedStaking *UnchainedStakingCallerSession) StakerToSigner(staker common.Address) (common.Address, error) { - return _UnchainedStaking.Contract.StakerToSigner(&_UnchainedStaking.CallOpts, staker) -} - -// Verify is a free data retrieval call binding the contract method 0x6e0b9e40. -// -// Solidity: function verify((address,address,address,address,uint256,uint256,uint256) eip712SetParam, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCaller) Verify(opts *bind.CallOpts, eip712SetParam UnchainedStakingEIP712SetParams, signature UnchainedStakingSignature) (bool, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "verify", eip712SetParam, signature) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// Verify is a free data retrieval call binding the contract method 0x6e0b9e40. -// -// Solidity: function verify((address,address,address,address,uint256,uint256,uint256) eip712SetParam, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingSession) Verify(eip712SetParam UnchainedStakingEIP712SetParams, signature UnchainedStakingSignature) (bool, error) { - return _UnchainedStaking.Contract.Verify(&_UnchainedStaking.CallOpts, eip712SetParam, signature) -} - -// Verify is a free data retrieval call binding the contract method 0x6e0b9e40. -// -// Solidity: function verify((address,address,address,address,uint256,uint256,uint256) eip712SetParam, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCallerSession) Verify(eip712SetParam UnchainedStakingEIP712SetParams, signature UnchainedStakingSignature) (bool, error) { - return _UnchainedStaking.Contract.Verify(&_UnchainedStaking.CallOpts, eip712SetParam, signature) -} - -// Verify0 is a free data retrieval call binding the contract method 0x709eb01b. -// -// Solidity: function verify((address,uint256,uint256,uint256) eip712SetNftPrice, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCaller) Verify0(opts *bind.CallOpts, eip712SetNftPrice UnchainedStakingEIP712SetNftPrice, signature UnchainedStakingSignature) (bool, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "verify0", eip712SetNftPrice, signature) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// Verify0 is a free data retrieval call binding the contract method 0x709eb01b. -// -// Solidity: function verify((address,uint256,uint256,uint256) eip712SetNftPrice, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingSession) Verify0(eip712SetNftPrice UnchainedStakingEIP712SetNftPrice, signature UnchainedStakingSignature) (bool, error) { - return _UnchainedStaking.Contract.Verify0(&_UnchainedStaking.CallOpts, eip712SetNftPrice, signature) -} - -// Verify0 is a free data retrieval call binding the contract method 0x709eb01b. -// -// Solidity: function verify((address,uint256,uint256,uint256) eip712SetNftPrice, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCallerSession) Verify0(eip712SetNftPrice UnchainedStakingEIP712SetNftPrice, signature UnchainedStakingSignature) (bool, error) { - return _UnchainedStaking.Contract.Verify0(&_UnchainedStaking.CallOpts, eip712SetNftPrice, signature) -} - -// Verify1 is a free data retrieval call binding the contract method 0x7856cc70. -// -// Solidity: function verify((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCaller) Verify1(opts *bind.CallOpts, eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (bool, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "verify1", eip712SetSigner, stakerSignature, signerSignature) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// Verify1 is a free data retrieval call binding the contract method 0x7856cc70. -// -// Solidity: function verify((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingSession) Verify1(eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (bool, error) { - return _UnchainedStaking.Contract.Verify1(&_UnchainedStaking.CallOpts, eip712SetSigner, stakerSignature, signerSignature) -} - -// Verify1 is a free data retrieval call binding the contract method 0x7856cc70. -// -// Solidity: function verify((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCallerSession) Verify1(eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (bool, error) { - return _UnchainedStaking.Contract.Verify1(&_UnchainedStaking.CallOpts, eip712SetSigner, stakerSignature, signerSignature) -} - -// Verify2 is a free data retrieval call binding the contract method 0xb7543d3e. -// -// Solidity: function verify((address,address,address,uint256,uint256[],uint256[]) eip712Transfer, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCaller) Verify2(opts *bind.CallOpts, eip712Transfer UnchainedStakingEIP712Transfer, signature UnchainedStakingSignature) (bool, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "verify2", eip712Transfer, signature) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// Verify2 is a free data retrieval call binding the contract method 0xb7543d3e. -// -// Solidity: function verify((address,address,address,uint256,uint256[],uint256[]) eip712Transfer, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingSession) Verify2(eip712Transfer UnchainedStakingEIP712Transfer, signature UnchainedStakingSignature) (bool, error) { - return _UnchainedStaking.Contract.Verify2(&_UnchainedStaking.CallOpts, eip712Transfer, signature) -} - -// Verify2 is a free data retrieval call binding the contract method 0xb7543d3e. -// -// Solidity: function verify((address,address,address,uint256,uint256[],uint256[]) eip712Transfer, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCallerSession) Verify2(eip712Transfer UnchainedStakingEIP712Transfer, signature UnchainedStakingSignature) (bool, error) { - return _UnchainedStaking.Contract.Verify2(&_UnchainedStaking.CallOpts, eip712Transfer, signature) -} - -// Extend is a paid mutator transaction binding the contract method 0x9714378c. -// -// Solidity: function extend(uint256 duration) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) Extend(opts *bind.TransactOpts, duration *big.Int) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "extend", duration) -} - -// Extend is a paid mutator transaction binding the contract method 0x9714378c. -// -// Solidity: function extend(uint256 duration) returns() -func (_UnchainedStaking *UnchainedStakingSession) Extend(duration *big.Int) (*types.Transaction, error) { - return _UnchainedStaking.Contract.Extend(&_UnchainedStaking.TransactOpts, duration) -} - -// Extend is a paid mutator transaction binding the contract method 0x9714378c. -// -// Solidity: function extend(uint256 duration) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) Extend(duration *big.Int) (*types.Transaction, error) { - return _UnchainedStaking.Contract.Extend(&_UnchainedStaking.TransactOpts, duration) -} - -// IncreaseStake is a paid mutator transaction binding the contract method 0x0062ad9d. -// -// Solidity: function increaseStake(uint256 amount, uint256[] nftIds) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) IncreaseStake(opts *bind.TransactOpts, amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "increaseStake", amount, nftIds) -} - -// IncreaseStake is a paid mutator transaction binding the contract method 0x0062ad9d. -// -// Solidity: function increaseStake(uint256 amount, uint256[] nftIds) returns() -func (_UnchainedStaking *UnchainedStakingSession) IncreaseStake(amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { - return _UnchainedStaking.Contract.IncreaseStake(&_UnchainedStaking.TransactOpts, amount, nftIds) -} - -// IncreaseStake is a paid mutator transaction binding the contract method 0x0062ad9d. -// -// Solidity: function increaseStake(uint256 amount, uint256[] nftIds) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) IncreaseStake(amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { - return _UnchainedStaking.Contract.IncreaseStake(&_UnchainedStaking.TransactOpts, amount, nftIds) -} - -// RecoverERC20 is a paid mutator transaction binding the contract method 0x1171bda9. -// -// Solidity: function recoverERC20(address token, address recipient, uint256 amount) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) RecoverERC20(opts *bind.TransactOpts, token common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "recoverERC20", token, recipient, amount) -} - -// RecoverERC20 is a paid mutator transaction binding the contract method 0x1171bda9. -// -// Solidity: function recoverERC20(address token, address recipient, uint256 amount) returns() -func (_UnchainedStaking *UnchainedStakingSession) RecoverERC20(token common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _UnchainedStaking.Contract.RecoverERC20(&_UnchainedStaking.TransactOpts, token, recipient, amount) -} - -// RecoverERC20 is a paid mutator transaction binding the contract method 0x1171bda9. -// -// Solidity: function recoverERC20(address token, address recipient, uint256 amount) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) RecoverERC20(token common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _UnchainedStaking.Contract.RecoverERC20(&_UnchainedStaking.TransactOpts, token, recipient, amount) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UnchainedStaking *UnchainedStakingTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "renounceOwnership") -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UnchainedStaking *UnchainedStakingSession) RenounceOwnership() (*types.Transaction, error) { - return _UnchainedStaking.Contract.RenounceOwnership(&_UnchainedStaking.TransactOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _UnchainedStaking.Contract.RenounceOwnership(&_UnchainedStaking.TransactOpts) -} - -// SetBlsAddress is a paid mutator transaction binding the contract method 0x3e5d4675. -// -// Solidity: function setBlsAddress(bytes20 blsAddress) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) SetBlsAddress(opts *bind.TransactOpts, blsAddress [20]byte) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "setBlsAddress", blsAddress) -} - -// SetBlsAddress is a paid mutator transaction binding the contract method 0x3e5d4675. -// -// Solidity: function setBlsAddress(bytes20 blsAddress) returns() -func (_UnchainedStaking *UnchainedStakingSession) SetBlsAddress(blsAddress [20]byte) (*types.Transaction, error) { - return _UnchainedStaking.Contract.SetBlsAddress(&_UnchainedStaking.TransactOpts, blsAddress) -} - -// SetBlsAddress is a paid mutator transaction binding the contract method 0x3e5d4675. -// -// Solidity: function setBlsAddress(bytes20 blsAddress) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) SetBlsAddress(blsAddress [20]byte) (*types.Transaction, error) { - return _UnchainedStaking.Contract.SetBlsAddress(&_UnchainedStaking.TransactOpts, blsAddress) -} - -// SetNftPrices is a paid mutator transaction binding the contract method 0xd43d8d1e. -// -// Solidity: function setNftPrices((address,uint256,uint256,uint256)[] eip712SetNftPrices, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) SetNftPrices(opts *bind.TransactOpts, eip712SetNftPrices []UnchainedStakingEIP712SetNftPrice, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "setNftPrices", eip712SetNftPrices, signatures) -} - -// SetNftPrices is a paid mutator transaction binding the contract method 0xd43d8d1e. -// -// Solidity: function setNftPrices((address,uint256,uint256,uint256)[] eip712SetNftPrices, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingSession) SetNftPrices(eip712SetNftPrices []UnchainedStakingEIP712SetNftPrice, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.Contract.SetNftPrices(&_UnchainedStaking.TransactOpts, eip712SetNftPrices, signatures) -} - -// SetNftPrices is a paid mutator transaction binding the contract method 0xd43d8d1e. -// -// Solidity: function setNftPrices((address,uint256,uint256,uint256)[] eip712SetNftPrices, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) SetNftPrices(eip712SetNftPrices []UnchainedStakingEIP712SetNftPrice, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.Contract.SetNftPrices(&_UnchainedStaking.TransactOpts, eip712SetNftPrices, signatures) -} - -// SetParams is a paid mutator transaction binding the contract method 0x642ca50f. -// -// Solidity: function setParams((address,address,address,address,uint256,uint256,uint256)[] eip712SetParams, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) SetParams(opts *bind.TransactOpts, eip712SetParams []UnchainedStakingEIP712SetParams, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "setParams", eip712SetParams, signatures) -} - -// SetParams is a paid mutator transaction binding the contract method 0x642ca50f. -// -// Solidity: function setParams((address,address,address,address,uint256,uint256,uint256)[] eip712SetParams, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingSession) SetParams(eip712SetParams []UnchainedStakingEIP712SetParams, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.Contract.SetParams(&_UnchainedStaking.TransactOpts, eip712SetParams, signatures) -} - -// SetParams is a paid mutator transaction binding the contract method 0x642ca50f. -// -// Solidity: function setParams((address,address,address,address,uint256,uint256,uint256)[] eip712SetParams, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) SetParams(eip712SetParams []UnchainedStakingEIP712SetParams, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.Contract.SetParams(&_UnchainedStaking.TransactOpts, eip712SetParams, signatures) -} - -// SetSigner is a paid mutator transaction binding the contract method 0xd9d35a4d. -// -// Solidity: function setSigner((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) SetSigner(opts *bind.TransactOpts, eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "setSigner", eip712SetSigner, stakerSignature, signerSignature) -} - -// SetSigner is a paid mutator transaction binding the contract method 0xd9d35a4d. -// -// Solidity: function setSigner((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) returns() -func (_UnchainedStaking *UnchainedStakingSession) SetSigner(eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.Contract.SetSigner(&_UnchainedStaking.TransactOpts, eip712SetSigner, stakerSignature, signerSignature) -} - -// SetSigner is a paid mutator transaction binding the contract method 0xd9d35a4d. -// -// Solidity: function setSigner((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) SetSigner(eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.Contract.SetSigner(&_UnchainedStaking.TransactOpts, eip712SetSigner, stakerSignature, signerSignature) -} - -// Stake is a paid mutator transaction binding the contract method 0x9debdddc. -// -// Solidity: function stake(uint256 duration, uint256 amount, uint256[] nftIds) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) Stake(opts *bind.TransactOpts, duration *big.Int, amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "stake", duration, amount, nftIds) -} - -// Stake is a paid mutator transaction binding the contract method 0x9debdddc. -// -// Solidity: function stake(uint256 duration, uint256 amount, uint256[] nftIds) returns() -func (_UnchainedStaking *UnchainedStakingSession) Stake(duration *big.Int, amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { - return _UnchainedStaking.Contract.Stake(&_UnchainedStaking.TransactOpts, duration, amount, nftIds) -} - -// Stake is a paid mutator transaction binding the contract method 0x9debdddc. -// -// Solidity: function stake(uint256 duration, uint256 amount, uint256[] nftIds) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) Stake(duration *big.Int, amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { - return _UnchainedStaking.Contract.Stake(&_UnchainedStaking.TransactOpts, duration, amount, nftIds) -} - -// Transfer is a paid mutator transaction binding the contract method 0xdc668266. -// -// Solidity: function transfer((address,address,address,uint256,uint256[],uint256[])[] eip712Transferes, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) Transfer(opts *bind.TransactOpts, eip712Transferes []UnchainedStakingEIP712Transfer, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "transfer", eip712Transferes, signatures) -} - -// Transfer is a paid mutator transaction binding the contract method 0xdc668266. -// -// Solidity: function transfer((address,address,address,uint256,uint256[],uint256[])[] eip712Transferes, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingSession) Transfer(eip712Transferes []UnchainedStakingEIP712Transfer, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.Contract.Transfer(&_UnchainedStaking.TransactOpts, eip712Transferes, signatures) -} - -// Transfer is a paid mutator transaction binding the contract method 0xdc668266. -// -// Solidity: function transfer((address,address,address,uint256,uint256[],uint256[])[] eip712Transferes, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) Transfer(eip712Transferes []UnchainedStakingEIP712Transfer, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.Contract.Transfer(&_UnchainedStaking.TransactOpts, eip712Transferes, signatures) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "transferOwnership", newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UnchainedStaking *UnchainedStakingSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _UnchainedStaking.Contract.TransferOwnership(&_UnchainedStaking.TransactOpts, newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _UnchainedStaking.Contract.TransferOwnership(&_UnchainedStaking.TransactOpts, newOwner) -} - -// Unstake is a paid mutator transaction binding the contract method 0x2def6620. -// -// Solidity: function unstake() returns() -func (_UnchainedStaking *UnchainedStakingTransactor) Unstake(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "unstake") -} - -// Unstake is a paid mutator transaction binding the contract method 0x2def6620. -// -// Solidity: function unstake() returns() -func (_UnchainedStaking *UnchainedStakingSession) Unstake() (*types.Transaction, error) { - return _UnchainedStaking.Contract.Unstake(&_UnchainedStaking.TransactOpts) -} - -// Unstake is a paid mutator transaction binding the contract method 0x2def6620. -// -// Solidity: function unstake() returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) Unstake() (*types.Transaction, error) { - return _UnchainedStaking.Contract.Unstake(&_UnchainedStaking.TransactOpts) -} - -// UnchainedStakingBlsAddressChangedIterator is returned from FilterBlsAddressChanged and is used to iterate over the raw logs and unpacked data for BlsAddressChanged events raised by the UnchainedStaking contract. -type UnchainedStakingBlsAddressChangedIterator struct { - Event *UnchainedStakingBlsAddressChanged // 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 *UnchainedStakingBlsAddressChangedIterator) 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(UnchainedStakingBlsAddressChanged) - 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(UnchainedStakingBlsAddressChanged) - 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 *UnchainedStakingBlsAddressChangedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingBlsAddressChangedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingBlsAddressChanged represents a BlsAddressChanged event raised by the UnchainedStaking contract. -type UnchainedStakingBlsAddressChanged struct { - User common.Address - From [32]byte - To [32]byte - Raw types.Log // Blockchain specific contextual infos -} - -// FilterBlsAddressChanged is a free log retrieval operation binding the contract event 0xa5c20a3e40dbfce0ccdadcb27e2f561e84ddf0618a41338cc1acb1524780ff39. -// -// Solidity: event BlsAddressChanged(address indexed user, bytes32 indexed from, bytes32 indexed to) -func (_UnchainedStaking *UnchainedStakingFilterer) FilterBlsAddressChanged(opts *bind.FilterOpts, user []common.Address, from [][32]byte, to [][32]byte) (*UnchainedStakingBlsAddressChangedIterator, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } - - logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "BlsAddressChanged", userRule, fromRule, toRule) - if err != nil { - return nil, err - } - return &UnchainedStakingBlsAddressChangedIterator{contract: _UnchainedStaking.contract, event: "BlsAddressChanged", logs: logs, sub: sub}, nil -} - -// WatchBlsAddressChanged is a free log subscription operation binding the contract event 0xa5c20a3e40dbfce0ccdadcb27e2f561e84ddf0618a41338cc1acb1524780ff39. -// -// Solidity: event BlsAddressChanged(address indexed user, bytes32 indexed from, bytes32 indexed to) -func (_UnchainedStaking *UnchainedStakingFilterer) WatchBlsAddressChanged(opts *bind.WatchOpts, sink chan<- *UnchainedStakingBlsAddressChanged, user []common.Address, from [][32]byte, to [][32]byte) (event.Subscription, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } - - logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "BlsAddressChanged", userRule, fromRule, toRule) - 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(UnchainedStakingBlsAddressChanged) - if err := _UnchainedStaking.contract.UnpackLog(event, "BlsAddressChanged", 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 -} - -// ParseBlsAddressChanged is a log parse operation binding the contract event 0xa5c20a3e40dbfce0ccdadcb27e2f561e84ddf0618a41338cc1acb1524780ff39. -// -// Solidity: event BlsAddressChanged(address indexed user, bytes32 indexed from, bytes32 indexed to) -func (_UnchainedStaking *UnchainedStakingFilterer) ParseBlsAddressChanged(log types.Log) (*UnchainedStakingBlsAddressChanged, error) { - event := new(UnchainedStakingBlsAddressChanged) - if err := _UnchainedStaking.contract.UnpackLog(event, "BlsAddressChanged", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// UnchainedStakingExtendedIterator is returned from FilterExtended and is used to iterate over the raw logs and unpacked data for Extended events raised by the UnchainedStaking contract. -type UnchainedStakingExtendedIterator struct { - Event *UnchainedStakingExtended // 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 *UnchainedStakingExtendedIterator) 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(UnchainedStakingExtended) - 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(UnchainedStakingExtended) - 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 *UnchainedStakingExtendedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingExtendedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingExtended represents a Extended event raised by the UnchainedStaking contract. -type UnchainedStakingExtended struct { - User common.Address - Unlock *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterExtended is a free log retrieval operation binding the contract event 0xa29fc12cda82ff659de006abb10fa5ee256d922af1661e395e5f2fb6b004387e. -// -// Solidity: event Extended(address indexed user, uint256 unlock) -func (_UnchainedStaking *UnchainedStakingFilterer) FilterExtended(opts *bind.FilterOpts, user []common.Address) (*UnchainedStakingExtendedIterator, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - - logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "Extended", userRule) - if err != nil { - return nil, err - } - return &UnchainedStakingExtendedIterator{contract: _UnchainedStaking.contract, event: "Extended", logs: logs, sub: sub}, nil -} - -// WatchExtended is a free log subscription operation binding the contract event 0xa29fc12cda82ff659de006abb10fa5ee256d922af1661e395e5f2fb6b004387e. -// -// Solidity: event Extended(address indexed user, uint256 unlock) -func (_UnchainedStaking *UnchainedStakingFilterer) WatchExtended(opts *bind.WatchOpts, sink chan<- *UnchainedStakingExtended, user []common.Address) (event.Subscription, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - - logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "Extended", userRule) - 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(UnchainedStakingExtended) - if err := _UnchainedStaking.contract.UnpackLog(event, "Extended", 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 -} - -// ParseExtended is a log parse operation binding the contract event 0xa29fc12cda82ff659de006abb10fa5ee256d922af1661e395e5f2fb6b004387e. -// -// Solidity: event Extended(address indexed user, uint256 unlock) -func (_UnchainedStaking *UnchainedStakingFilterer) ParseExtended(log types.Log) (*UnchainedStakingExtended, error) { - event := new(UnchainedStakingExtended) - if err := _UnchainedStaking.contract.UnpackLog(event, "Extended", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// UnchainedStakingOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the UnchainedStaking contract. -type UnchainedStakingOwnershipTransferredIterator struct { - Event *UnchainedStakingOwnershipTransferred // 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 *UnchainedStakingOwnershipTransferredIterator) 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(UnchainedStakingOwnershipTransferred) - 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(UnchainedStakingOwnershipTransferred) - 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 *UnchainedStakingOwnershipTransferredIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingOwnershipTransferred represents a OwnershipTransferred event raised by the UnchainedStaking contract. -type UnchainedStakingOwnershipTransferred 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 (_UnchainedStaking *UnchainedStakingFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*UnchainedStakingOwnershipTransferredIterator, 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 := _UnchainedStaking.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) - if err != nil { - return nil, err - } - return &UnchainedStakingOwnershipTransferredIterator{contract: _UnchainedStaking.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 (_UnchainedStaking *UnchainedStakingFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *UnchainedStakingOwnershipTransferred, 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 := _UnchainedStaking.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(UnchainedStakingOwnershipTransferred) - if err := _UnchainedStaking.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 (_UnchainedStaking *UnchainedStakingFilterer) ParseOwnershipTransferred(log types.Log) (*UnchainedStakingOwnershipTransferred, error) { - event := new(UnchainedStakingOwnershipTransferred) - if err := _UnchainedStaking.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// UnchainedStakingParamsChangedIterator is returned from FilterParamsChanged and is used to iterate over the raw logs and unpacked data for ParamsChanged events raised by the UnchainedStaking contract. -type UnchainedStakingParamsChangedIterator struct { - Event *UnchainedStakingParamsChanged // 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 *UnchainedStakingParamsChangedIterator) 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(UnchainedStakingParamsChanged) - 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(UnchainedStakingParamsChanged) - 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 *UnchainedStakingParamsChangedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingParamsChangedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingParamsChanged represents a ParamsChanged event raised by the UnchainedStaking contract. -type UnchainedStakingParamsChanged struct { - Token common.Address - Nft common.Address - NftTracker common.Address - Threshold *big.Int - Expiration *big.Int - Voted *big.Int - Nonce *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterParamsChanged is a free log retrieval operation binding the contract event 0xcccaeb9d161525e3f31950313467c2e9a945a55a1ff09658479fe753054fafe0. -// -// Solidity: event ParamsChanged(address token, address nft, address nftTracker, uint256 threshold, uint256 expiration, uint256 voted, uint256 nonce) -func (_UnchainedStaking *UnchainedStakingFilterer) FilterParamsChanged(opts *bind.FilterOpts) (*UnchainedStakingParamsChangedIterator, error) { - - logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "ParamsChanged") - if err != nil { - return nil, err - } - return &UnchainedStakingParamsChangedIterator{contract: _UnchainedStaking.contract, event: "ParamsChanged", logs: logs, sub: sub}, nil -} - -// WatchParamsChanged is a free log subscription operation binding the contract event 0xcccaeb9d161525e3f31950313467c2e9a945a55a1ff09658479fe753054fafe0. -// -// Solidity: event ParamsChanged(address token, address nft, address nftTracker, uint256 threshold, uint256 expiration, uint256 voted, uint256 nonce) -func (_UnchainedStaking *UnchainedStakingFilterer) WatchParamsChanged(opts *bind.WatchOpts, sink chan<- *UnchainedStakingParamsChanged) (event.Subscription, error) { - - logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "ParamsChanged") - 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(UnchainedStakingParamsChanged) - if err := _UnchainedStaking.contract.UnpackLog(event, "ParamsChanged", 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 -} - -// ParseParamsChanged is a log parse operation binding the contract event 0xcccaeb9d161525e3f31950313467c2e9a945a55a1ff09658479fe753054fafe0. -// -// Solidity: event ParamsChanged(address token, address nft, address nftTracker, uint256 threshold, uint256 expiration, uint256 voted, uint256 nonce) -func (_UnchainedStaking *UnchainedStakingFilterer) ParseParamsChanged(log types.Log) (*UnchainedStakingParamsChanged, error) { - event := new(UnchainedStakingParamsChanged) - if err := _UnchainedStaking.contract.UnpackLog(event, "ParamsChanged", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// UnchainedStakingSignerChangedIterator is returned from FilterSignerChanged and is used to iterate over the raw logs and unpacked data for SignerChanged events raised by the UnchainedStaking contract. -type UnchainedStakingSignerChangedIterator struct { - Event *UnchainedStakingSignerChanged // 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 *UnchainedStakingSignerChangedIterator) 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(UnchainedStakingSignerChanged) - 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(UnchainedStakingSignerChanged) - 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 *UnchainedStakingSignerChangedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingSignerChangedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingSignerChanged represents a SignerChanged event raised by the UnchainedStaking contract. -type UnchainedStakingSignerChanged struct { - Staker common.Address - Signer common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterSignerChanged is a free log retrieval operation binding the contract event 0xeeb293e1f8f3a9db91ade748726387ed1352ca78f5430c5f06fe3d1e1ad50579. -// -// Solidity: event SignerChanged(address indexed staker, address indexed signer) -func (_UnchainedStaking *UnchainedStakingFilterer) FilterSignerChanged(opts *bind.FilterOpts, staker []common.Address, signer []common.Address) (*UnchainedStakingSignerChangedIterator, error) { - - var stakerRule []interface{} - for _, stakerItem := range staker { - stakerRule = append(stakerRule, stakerItem) - } - var signerRule []interface{} - for _, signerItem := range signer { - signerRule = append(signerRule, signerItem) - } - - logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "SignerChanged", stakerRule, signerRule) - if err != nil { - return nil, err - } - return &UnchainedStakingSignerChangedIterator{contract: _UnchainedStaking.contract, event: "SignerChanged", logs: logs, sub: sub}, nil -} - -// WatchSignerChanged is a free log subscription operation binding the contract event 0xeeb293e1f8f3a9db91ade748726387ed1352ca78f5430c5f06fe3d1e1ad50579. -// -// Solidity: event SignerChanged(address indexed staker, address indexed signer) -func (_UnchainedStaking *UnchainedStakingFilterer) WatchSignerChanged(opts *bind.WatchOpts, sink chan<- *UnchainedStakingSignerChanged, staker []common.Address, signer []common.Address) (event.Subscription, error) { - - var stakerRule []interface{} - for _, stakerItem := range staker { - stakerRule = append(stakerRule, stakerItem) - } - var signerRule []interface{} - for _, signerItem := range signer { - signerRule = append(signerRule, signerItem) - } - - logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "SignerChanged", stakerRule, signerRule) - 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(UnchainedStakingSignerChanged) - if err := _UnchainedStaking.contract.UnpackLog(event, "SignerChanged", 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 -} - -// ParseSignerChanged is a log parse operation binding the contract event 0xeeb293e1f8f3a9db91ade748726387ed1352ca78f5430c5f06fe3d1e1ad50579. -// -// Solidity: event SignerChanged(address indexed staker, address indexed signer) -func (_UnchainedStaking *UnchainedStakingFilterer) ParseSignerChanged(log types.Log) (*UnchainedStakingSignerChanged, error) { - event := new(UnchainedStakingSignerChanged) - if err := _UnchainedStaking.contract.UnpackLog(event, "SignerChanged", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// UnchainedStakingStakeIncreasedIterator is returned from FilterStakeIncreased and is used to iterate over the raw logs and unpacked data for StakeIncreased events raised by the UnchainedStaking contract. -type UnchainedStakingStakeIncreasedIterator struct { - Event *UnchainedStakingStakeIncreased // 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 *UnchainedStakingStakeIncreasedIterator) 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(UnchainedStakingStakeIncreased) - 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(UnchainedStakingStakeIncreased) - 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 *UnchainedStakingStakeIncreasedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingStakeIncreasedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingStakeIncreased represents a StakeIncreased event raised by the UnchainedStaking contract. -type UnchainedStakingStakeIncreased struct { - User common.Address - Amount *big.Int - NftIds []*big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterStakeIncreased is a free log retrieval operation binding the contract event 0x26e4d06799c60ba22ec168ee4a9314ed451cf9c78dbf6a5f7bfeaf3c84688f58. -// -// Solidity: event StakeIncreased(address indexed user, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) FilterStakeIncreased(opts *bind.FilterOpts, user []common.Address) (*UnchainedStakingStakeIncreasedIterator, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - - logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "StakeIncreased", userRule) - if err != nil { - return nil, err - } - return &UnchainedStakingStakeIncreasedIterator{contract: _UnchainedStaking.contract, event: "StakeIncreased", logs: logs, sub: sub}, nil -} - -// WatchStakeIncreased is a free log subscription operation binding the contract event 0x26e4d06799c60ba22ec168ee4a9314ed451cf9c78dbf6a5f7bfeaf3c84688f58. -// -// Solidity: event StakeIncreased(address indexed user, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) WatchStakeIncreased(opts *bind.WatchOpts, sink chan<- *UnchainedStakingStakeIncreased, user []common.Address) (event.Subscription, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - - logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "StakeIncreased", userRule) - 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(UnchainedStakingStakeIncreased) - if err := _UnchainedStaking.contract.UnpackLog(event, "StakeIncreased", 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 -} - -// ParseStakeIncreased is a log parse operation binding the contract event 0x26e4d06799c60ba22ec168ee4a9314ed451cf9c78dbf6a5f7bfeaf3c84688f58. -// -// Solidity: event StakeIncreased(address indexed user, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) ParseStakeIncreased(log types.Log) (*UnchainedStakingStakeIncreased, error) { - event := new(UnchainedStakingStakeIncreased) - if err := _UnchainedStaking.contract.UnpackLog(event, "StakeIncreased", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// UnchainedStakingStakedIterator is returned from FilterStaked and is used to iterate over the raw logs and unpacked data for Staked events raised by the UnchainedStaking contract. -type UnchainedStakingStakedIterator struct { - Event *UnchainedStakingStaked // 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 *UnchainedStakingStakedIterator) 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(UnchainedStakingStaked) - 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(UnchainedStakingStaked) - 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 *UnchainedStakingStakedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingStakedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingStaked represents a Staked event raised by the UnchainedStaking contract. -type UnchainedStakingStaked struct { - User common.Address - Unlock *big.Int - Amount *big.Int - NftIds []*big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterStaked is a free log retrieval operation binding the contract event 0x5df5de9ccb680fe3d60088f6d4c3b6d535074c704699377046c743a5b276e171. -// -// Solidity: event Staked(address indexed user, uint256 unlock, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) FilterStaked(opts *bind.FilterOpts, user []common.Address) (*UnchainedStakingStakedIterator, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - - logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "Staked", userRule) - if err != nil { - return nil, err - } - return &UnchainedStakingStakedIterator{contract: _UnchainedStaking.contract, event: "Staked", logs: logs, sub: sub}, nil -} - -// WatchStaked is a free log subscription operation binding the contract event 0x5df5de9ccb680fe3d60088f6d4c3b6d535074c704699377046c743a5b276e171. -// -// Solidity: event Staked(address indexed user, uint256 unlock, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) WatchStaked(opts *bind.WatchOpts, sink chan<- *UnchainedStakingStaked, user []common.Address) (event.Subscription, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - - logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "Staked", userRule) - 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(UnchainedStakingStaked) - if err := _UnchainedStaking.contract.UnpackLog(event, "Staked", 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 -} - -// ParseStaked is a log parse operation binding the contract event 0x5df5de9ccb680fe3d60088f6d4c3b6d535074c704699377046c743a5b276e171. -// -// Solidity: event Staked(address indexed user, uint256 unlock, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) ParseStaked(log types.Log) (*UnchainedStakingStaked, error) { - event := new(UnchainedStakingStaked) - if err := _UnchainedStaking.contract.UnpackLog(event, "Staked", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// UnchainedStakingTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the UnchainedStaking contract. -type UnchainedStakingTransferIterator struct { - Event *UnchainedStakingTransfer // 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 *UnchainedStakingTransferIterator) 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(UnchainedStakingTransfer) - 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(UnchainedStakingTransfer) - 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 *UnchainedStakingTransferIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingTransferIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingTransfer represents a Transfer event raised by the UnchainedStaking contract. -type UnchainedStakingTransfer struct { - From common.Address - To common.Address - Amount *big.Int - NftIds []*big.Int - Nonces []*big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterTransfer is a free log retrieval operation binding the contract event 0x26a79d74e745222aa0f380aabeac7f0a270b037daf3b5fb1b1b66ff7f4c3144f. -// -// Solidity: event Transfer(address from, address to, uint256 amount, uint256[] nftIds, uint256[] nonces) -func (_UnchainedStaking *UnchainedStakingFilterer) FilterTransfer(opts *bind.FilterOpts) (*UnchainedStakingTransferIterator, error) { - - logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "Transfer") - if err != nil { - return nil, err - } - return &UnchainedStakingTransferIterator{contract: _UnchainedStaking.contract, event: "Transfer", logs: logs, sub: sub}, nil -} - -// WatchTransfer is a free log subscription operation binding the contract event 0x26a79d74e745222aa0f380aabeac7f0a270b037daf3b5fb1b1b66ff7f4c3144f. -// -// Solidity: event Transfer(address from, address to, uint256 amount, uint256[] nftIds, uint256[] nonces) -func (_UnchainedStaking *UnchainedStakingFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *UnchainedStakingTransfer) (event.Subscription, error) { - - logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "Transfer") - 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(UnchainedStakingTransfer) - if err := _UnchainedStaking.contract.UnpackLog(event, "Transfer", 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 -} - -// ParseTransfer is a log parse operation binding the contract event 0x26a79d74e745222aa0f380aabeac7f0a270b037daf3b5fb1b1b66ff7f4c3144f. -// -// Solidity: event Transfer(address from, address to, uint256 amount, uint256[] nftIds, uint256[] nonces) -func (_UnchainedStaking *UnchainedStakingFilterer) ParseTransfer(log types.Log) (*UnchainedStakingTransfer, error) { - event := new(UnchainedStakingTransfer) - if err := _UnchainedStaking.contract.UnpackLog(event, "Transfer", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// UnchainedStakingUnStakedIterator is returned from FilterUnStaked and is used to iterate over the raw logs and unpacked data for UnStaked events raised by the UnchainedStaking contract. -type UnchainedStakingUnStakedIterator struct { - Event *UnchainedStakingUnStaked // 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 *UnchainedStakingUnStakedIterator) 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(UnchainedStakingUnStaked) - 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(UnchainedStakingUnStaked) - 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 *UnchainedStakingUnStakedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingUnStakedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingUnStaked represents a UnStaked event raised by the UnchainedStaking contract. -type UnchainedStakingUnStaked struct { - User common.Address - Amount *big.Int - NftIds []*big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterUnStaked is a free log retrieval operation binding the contract event 0xef4ce4a0205d268e0effbc76aaabb2ad2509ec58a2e9013645347d3c3cd9be42. -// -// Solidity: event UnStaked(address indexed user, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) FilterUnStaked(opts *bind.FilterOpts, user []common.Address) (*UnchainedStakingUnStakedIterator, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - - logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "UnStaked", userRule) - if err != nil { - return nil, err - } - return &UnchainedStakingUnStakedIterator{contract: _UnchainedStaking.contract, event: "UnStaked", logs: logs, sub: sub}, nil -} - -// WatchUnStaked is a free log subscription operation binding the contract event 0xef4ce4a0205d268e0effbc76aaabb2ad2509ec58a2e9013645347d3c3cd9be42. -// -// Solidity: event UnStaked(address indexed user, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) WatchUnStaked(opts *bind.WatchOpts, sink chan<- *UnchainedStakingUnStaked, user []common.Address) (event.Subscription, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - - logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "UnStaked", userRule) - 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(UnchainedStakingUnStaked) - if err := _UnchainedStaking.contract.UnpackLog(event, "UnStaked", 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 -} - -// ParseUnStaked is a log parse operation binding the contract event 0xef4ce4a0205d268e0effbc76aaabb2ad2509ec58a2e9013645347d3c3cd9be42. -// -// Solidity: event UnStaked(address indexed user, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) ParseUnStaked(log types.Log) (*UnchainedStakingUnStaked, error) { - event := new(UnchainedStakingUnStaked) - if err := _UnchainedStaking.contract.UnpackLog(event, "UnStaked", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} diff --git a/internal/crypto/ethereum/contracts/UniV3.go b/internal/crypto/ethereum/contracts/UniV3.go deleted file mode 100644 index 087ab06e..00000000 --- a/internal/crypto/ethereum/contracts/UniV3.go +++ /dev/null @@ -1,251 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package contracts - -import ( - "errors" - "math/big" - "strings" - - 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" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -// UniV3MetaData contains all meta data concerning the UniV3 contract. -var UniV3MetaData = &bind.MetaData{ - ABI: "[{\"type\":\"function\",\"name\":\"slot0\",\"constant\":true,\"stateMutability\":\"view\",\"payable\":false,\"inputs\":[],\"outputs\":[{\"type\":\"uint160\",\"name\":\"sqrtPriceX96\"},{\"type\":\"int24\",\"name\":\"tick\"},{\"type\":\"uint16\",\"name\":\"observationIndex\"},{\"type\":\"uint16\",\"name\":\"observationCardinality\"},{\"type\":\"uint16\",\"name\":\"observationCardinalityNext\"},{\"type\":\"uint8\",\"name\":\"feeProtocol\"},{\"type\":\"bool\",\"name\":\"unlocked\"}]}]", -} - -// UniV3ABI is the input ABI used to generate the binding from. -// Deprecated: Use UniV3MetaData.ABI instead. -var UniV3ABI = UniV3MetaData.ABI - -// UniV3 is an auto generated Go binding around an Ethereum contract. -type UniV3 struct { - UniV3Caller // Read-only binding to the contract - UniV3Transactor // Write-only binding to the contract - UniV3Filterer // Log filterer for contract events -} - -// UniV3Caller is an auto generated read-only Go binding around an Ethereum contract. -type UniV3Caller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// UniV3Transactor is an auto generated write-only Go binding around an Ethereum contract. -type UniV3Transactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// UniV3Filterer is an auto generated log filtering Go binding around an Ethereum contract events. -type UniV3Filterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// UniV3Session is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type UniV3Session struct { - Contract *UniV3 // 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 -} - -// UniV3CallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type UniV3CallerSession struct { - Contract *UniV3Caller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// UniV3TransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type UniV3TransactorSession struct { - Contract *UniV3Transactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// UniV3Raw is an auto generated low-level Go binding around an Ethereum contract. -type UniV3Raw struct { - Contract *UniV3 // Generic contract binding to access the raw methods on -} - -// UniV3CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type UniV3CallerRaw struct { - Contract *UniV3Caller // Generic read-only contract binding to access the raw methods on -} - -// UniV3TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type UniV3TransactorRaw struct { - Contract *UniV3Transactor // Generic write-only contract binding to access the raw methods on -} - -// NewUniV3 creates a new instance of UniV3, bound to a specific deployed contract. -func NewUniV3(address common.Address, backend bind.ContractBackend) (*UniV3, error) { - contract, err := bindUniV3(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &UniV3{UniV3Caller: UniV3Caller{contract: contract}, UniV3Transactor: UniV3Transactor{contract: contract}, UniV3Filterer: UniV3Filterer{contract: contract}}, nil -} - -// NewUniV3Caller creates a new read-only instance of UniV3, bound to a specific deployed contract. -func NewUniV3Caller(address common.Address, caller bind.ContractCaller) (*UniV3Caller, error) { - contract, err := bindUniV3(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &UniV3Caller{contract: contract}, nil -} - -// NewUniV3Transactor creates a new write-only instance of UniV3, bound to a specific deployed contract. -func NewUniV3Transactor(address common.Address, transactor bind.ContractTransactor) (*UniV3Transactor, error) { - contract, err := bindUniV3(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &UniV3Transactor{contract: contract}, nil -} - -// NewUniV3Filterer creates a new log filterer instance of UniV3, bound to a specific deployed contract. -func NewUniV3Filterer(address common.Address, filterer bind.ContractFilterer) (*UniV3Filterer, error) { - contract, err := bindUniV3(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &UniV3Filterer{contract: contract}, nil -} - -// bindUniV3 binds a generic wrapper to an already deployed contract. -func bindUniV3(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := UniV3MetaData.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 (_UniV3 *UniV3Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UniV3.Contract.UniV3Caller.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 (_UniV3 *UniV3Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UniV3.Contract.UniV3Transactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_UniV3 *UniV3Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UniV3.Contract.UniV3Transactor.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 (_UniV3 *UniV3CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UniV3.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 (_UniV3 *UniV3TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UniV3.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_UniV3 *UniV3TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UniV3.Contract.contract.Transact(opts, method, params...) -} - -// Slot0 is a free data retrieval call binding the contract method 0x3850c7bd. -// -// Solidity: function slot0() view returns(uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked) -func (_UniV3 *UniV3Caller) Slot0(opts *bind.CallOpts) (struct { - SqrtPriceX96 *big.Int - Tick *big.Int - ObservationIndex uint16 - ObservationCardinality uint16 - ObservationCardinalityNext uint16 - FeeProtocol uint8 - Unlocked bool -}, error) { - var out []interface{} - err := _UniV3.contract.Call(opts, &out, "slot0") - - outstruct := new(struct { - SqrtPriceX96 *big.Int - Tick *big.Int - ObservationIndex uint16 - ObservationCardinality uint16 - ObservationCardinalityNext uint16 - FeeProtocol uint8 - Unlocked bool - }) - if err != nil { - return *outstruct, err - } - - outstruct.SqrtPriceX96 = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.Tick = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.ObservationIndex = *abi.ConvertType(out[2], new(uint16)).(*uint16) - outstruct.ObservationCardinality = *abi.ConvertType(out[3], new(uint16)).(*uint16) - outstruct.ObservationCardinalityNext = *abi.ConvertType(out[4], new(uint16)).(*uint16) - outstruct.FeeProtocol = *abi.ConvertType(out[5], new(uint8)).(*uint8) - outstruct.Unlocked = *abi.ConvertType(out[6], new(bool)).(*bool) - - return *outstruct, err - -} - -// Slot0 is a free data retrieval call binding the contract method 0x3850c7bd. -// -// Solidity: function slot0() view returns(uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked) -func (_UniV3 *UniV3Session) Slot0() (struct { - SqrtPriceX96 *big.Int - Tick *big.Int - ObservationIndex uint16 - ObservationCardinality uint16 - ObservationCardinalityNext uint16 - FeeProtocol uint8 - Unlocked bool -}, error) { - return _UniV3.Contract.Slot0(&_UniV3.CallOpts) -} - -// Slot0 is a free data retrieval call binding the contract method 0x3850c7bd. -// -// Solidity: function slot0() view returns(uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked) -func (_UniV3 *UniV3CallerSession) Slot0() (struct { - SqrtPriceX96 *big.Int - Tick *big.Int - ObservationIndex uint16 - ObservationCardinality uint16 - ObservationCardinalityNext uint16 - FeeProtocol uint8 - Unlocked bool -}, error) { - return _UniV3.Contract.Slot0(&_UniV3.CallOpts) -} diff --git a/internal/crypto/ethereum/identity.go b/internal/crypto/ethereum/identity.go deleted file mode 100644 index 84a9c56a..00000000 --- a/internal/crypto/ethereum/identity.go +++ /dev/null @@ -1,89 +0,0 @@ -package ethereum - -import ( - "crypto/ecdsa" - - "github.com/TimeleapLabs/unchained/internal/config" - "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" -) - -// Signer represents an Ethereum identity. -type Signer struct { - PublicKey *ecdsa.PublicKey - PrivateKey *ecdsa.PrivateKey - Address string -} - -func (s *Signer) Verify(_ []byte, _ []byte, _ []byte) (bool, error) { - // TODO implement me - panic("implement me") -} - -// WriteConfigs writes the secret key, public key and address to the global config object. -func (s *Signer) WriteConfigs() { - privateKeyBytes := crypto.FromECDSA(s.PrivateKey) - config.App.Secret.EvmPrivateKey = hexutil.Encode(privateKeyBytes)[2:] - config.App.Secret.EvmAddress = s.Address -} - -func (s *Signer) Sign(data []byte) ([]byte, error) { - signature, err := crypto.Sign(data, s.PrivateKey) - if err != nil { - return nil, err - } - - if signature[64] < 27 { - signature[64] += 27 - } - - return signature, nil -} - -// NewIdentity creates a new Ethereum identity. -func NewIdentity() *Signer { - var privateKey *ecdsa.PrivateKey - var err error - - if config.App.Secret.EvmPrivateKey == "" && !config.App.System.AllowGenerateSecrets { - panic("EVM private key is not provided and secrets generation is not allowed") - } - - if config.App.Secret.EvmPrivateKey != "" { - privateKey, err = crypto.HexToECDSA(config.App.Secret.EvmPrivateKey) - if err != nil { - utils.Logger. - With("Error", err). - Error("Can't decode EVM private key") - - panic(err) - } - } else { - privateKey, err = crypto.GenerateKey() - if err != nil { - utils.Logger. - With("Error", err). - Error("Can't generate EVM private key") - - panic(err) - } - } - - publicKeyECDSA, ok := privateKey.Public().(*ecdsa.PublicKey) - if !ok { - panic("Can't assert type: publicKey is not of type *ecdsa.PublicKey") - } - - s := &Signer{ - PublicKey: publicKeyECDSA, - PrivateKey: privateKey, - Address: crypto.PubkeyToAddress(*publicKeyECDSA).Hex(), - } - - utils.Logger. - With("Address", s.Address). - Info("EVM identity initialized") - - return s -} diff --git a/internal/crypto/ethereum/rpc.go b/internal/crypto/ethereum/rpc.go deleted file mode 100644 index a3bdf516..00000000 --- a/internal/crypto/ethereum/rpc.go +++ /dev/null @@ -1,112 +0,0 @@ -package ethereum - -import ( - "context" - "sync" - - "github.com/TimeleapLabs/unchained/internal/consts" - "github.com/TimeleapLabs/unchained/internal/utils" - - "github.com/TimeleapLabs/unchained/internal/crypto/ethereum/contracts" - - "github.com/TimeleapLabs/unchained/internal/config" - - "github.com/ethereum/go-ethereum/common" - - "github.com/ethereum/go-ethereum/ethclient" -) - -type RPC interface { - RefreshRPC(network string) - GetClient(network string) *ethclient.Client - GetNewStakingContract(network string, address string, refresh bool) (*contracts.UnchainedStaking, error) - GetNewUniV3Contract(network string, address string, refresh bool) (*contracts.UniV3, error) - GetBlockNumber(ctx context.Context, network string) (uint64, error) -} - -type repository struct { - list map[string][]string - index map[string]int - clients map[string]*ethclient.Client - mutex *sync.Mutex -} - -func (r *repository) GetClient(chain string) *ethclient.Client { - return r.clients[chain] -} - -func (r *repository) refreshRPCWithRetries(network string, retries int) bool { - if retries == 0 { - panic("Cannot connect to any of the provided RPCs") - } - - if r.index[network] == len(r.list[network])-1 { - r.index[network] = 0 - } else { - r.index[network]++ - } - - var err error - - index := r.index[network] - r.clients[network], err = ethclient.Dial(r.list[network][index]) - - if err != nil { - return r.refreshRPCWithRetries(network, retries-1) - } - - return true -} - -func (r *repository) RefreshRPC(network string) { - r.mutex.Lock() - defer r.mutex.Unlock() - - utils.Logger.With("Network", network).Info("Connecting to RPC") - r.refreshRPCWithRetries(network, len(r.list)) -} - -func (r *repository) GetNewStakingContract(network string, address string, refresh bool) (*contracts.UnchainedStaking, error) { - if refresh { - r.RefreshRPC(network) - } - - return contracts.NewUnchainedStaking(common.HexToAddress(address), r.clients[network]) -} - -func (r *repository) GetNewUniV3Contract(network string, address string, refresh bool) (*contracts.UniV3, error) { - if refresh { - r.RefreshRPC(network) - } - - return contracts.NewUniV3(common.HexToAddress(address), r.clients[network]) -} - -// GetBlockNumber returns the most recent block number. -func (r *repository) GetBlockNumber(ctx context.Context, network string) (uint64, error) { - client, ok := r.clients[network] - - if !ok { - utils.Logger.With("Network", network).Error("Client not found") - return 0, consts.ErrClientNotFound - } - - return client.BlockNumber(ctx) -} - -func New() RPC { - r := &repository{ - list: map[string][]string{}, - index: map[string]int{}, - clients: map[string]*ethclient.Client{}, - mutex: new(sync.Mutex), - } - - for _, rpc := range config.App.RPC { - r.index[rpc.Name] = 0 - r.list[rpc.Name] = append(r.list[rpc.Name], rpc.Nodes...) - r.RefreshRPC(rpc.Name) - } - - return r -} diff --git a/internal/crypto/ethereum/rpc_mock.go b/internal/crypto/ethereum/rpc_mock.go deleted file mode 100644 index 36df1b39..00000000 --- a/internal/crypto/ethereum/rpc_mock.go +++ /dev/null @@ -1,51 +0,0 @@ -package ethereum - -import ( - "context" - - "github.com/TimeleapLabs/unchained/internal/crypto/ethereum/contracts" - - "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/ethclient" -) - -type mockRPC struct { - backend *backends.SimulatedBackend -} - -func (m mockRPC) GetClient(_ string) *ethclient.Client { - // TODO implement me - panic("implement me") -} - -func (m mockRPC) RefreshRPC(_ string) {} - -func (m mockRPC) GetNewStakingContract(_ string, address string, _ bool) (*contracts.UnchainedStaking, error) { - return contracts.NewUnchainedStaking( - common.HexToAddress(address), - m.backend, - ) -} - -func (m mockRPC) GetNewUniV3Contract(_ string, address string, _ bool) (*contracts.UniV3, error) { - return contracts.NewUniV3( - common.HexToAddress(address), - m.backend, - ) -} - -func (m mockRPC) GetBlockNumber(_ context.Context, _ string) (uint64, error) { - var blockNumber uint64 = 1000 - return blockNumber, nil -} - -func NewMock() RPC { - return &mockRPC{ - backend: backends.NewSimulatedBackend( - core.DefaultGenesisBlock().Alloc, - 9000000, - ), - } -} diff --git a/internal/crypto/identity.go b/internal/crypto/identity.go deleted file mode 100644 index 971a853c..00000000 --- a/internal/crypto/identity.go +++ /dev/null @@ -1,96 +0,0 @@ -package crypto - -import ( - "encoding/hex" - - "github.com/TimeleapLabs/unchained/internal/config" - "github.com/TimeleapLabs/unchained/internal/crypto/bls" - "github.com/TimeleapLabs/unchained/internal/crypto/ethereum" - "github.com/TimeleapLabs/unchained/internal/crypto/tss" - "github.com/TimeleapLabs/unchained/internal/model" -) - -// Signer represents a Signing method. -type Signer interface { - Sign(data []byte) ([]byte, error) - Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) - WriteConfigs() -} - -// MachineIdentity holds machine identity and provide and manage keys. -type MachineIdentity struct { - Bls Signer - Eth Signer - Tss *tss.DistributedSigner -} - -// Identity is a global variable that holds machine identity. -var Identity = &MachineIdentity{} - -// Option represents a function that can add new identity to machine identity. -type Option func(identity *MachineIdentity) error - -// InitMachineIdentity loads all provided identities and save them to secret file. -func InitMachineIdentity(options ...Option) { - for _, option := range options { - err := option(Identity) - if err != nil { - panic(err) - } - } - - if config.App.System.AllowGenerateSecrets { - err := config.App.Secret.Save() - if err != nil { - panic(err) - } - } -} - -// ExportEvmSigner returns EVM signer from machine identity. -func (i *MachineIdentity) ExportEvmSigner() *model.Signer { - blsPublicKey, err := hex.DecodeString(config.App.Secret.PublicKey) - if err != nil { - panic(err) - } - - return &model.Signer{ - Name: config.App.System.Name, - EvmAddress: config.App.Secret.EvmAddress, - PublicKey: [96]byte(blsPublicKey), - ShortPublicKey: config.App.Secret.ShortPublicKey, - } -} - -// WithEvmSigner initialize and will add Evm identity to machine identity. -func WithEvmSigner() func(machineIdentity *MachineIdentity) error { - return func(machineIdentity *MachineIdentity) error { - machineIdentity.Eth = ethereum.NewIdentity() - machineIdentity.Eth.WriteConfigs() - - return nil - } -} - -// WithTssSigner initialize and will add Tss identity to machine identity. -// func WithTssSigner(signers []string, minThreshold int) func(machineIdentity *MachineIdentity) error { -// return func(machineIdentity *MachineIdentity) error { -// machineIdentity.Tss = tss.NewIdentity( -// signers, -// minThreshold, -// ) -// //machineIdentity.Tss.WriteConfigs() -// -// return nil -// } -//} - -// WithBlsIdentity initialize and will add Bls identity to machine identity. -func WithBlsIdentity() func(machineIdentity *MachineIdentity) error { - return func(machineIdentity *MachineIdentity) error { - machineIdentity.Bls = bls.NewIdentity() - machineIdentity.Bls.WriteConfigs() - - return nil - } -} diff --git a/internal/crypto/identity_test.go b/internal/crypto/identity_test.go deleted file mode 100644 index b0fa65b6..00000000 --- a/internal/crypto/identity_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package crypto - -import ( - "testing" - - "github.com/TimeleapLabs/unchained/internal/config" - "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/stretchr/testify/assert" -) - -const SamplePrivateKey = "3b885a8a8f043724abfa865eccd38f536887d9ea1c08a742720e810f38a86872" - -func TestEvmSignerWithoutGeneratePrivateKey(t *testing.T) { - utils.SetupLogger("info") - config.App.Secret.EvmPrivateKey = SamplePrivateKey - - InitMachineIdentity( - WithEvmSigner(), - ) - - assert.Equal(t, config.App.Secret.EvmPrivateKey, SamplePrivateKey) -} - -func TestEvmSignerWithGeneratePrivateKey(t *testing.T) { - utils.SetupLogger("info") - config.App.Secret.EvmPrivateKey = "" - - InitMachineIdentity( - WithEvmSigner(), - ) - assert.NotEmpty(t, config.App.Secret.EvmPrivateKey) -} diff --git a/internal/crypto/tss/identity.go b/internal/crypto/tss/identity.go deleted file mode 100644 index 3db295a0..00000000 --- a/internal/crypto/tss/identity.go +++ /dev/null @@ -1,113 +0,0 @@ -package tss - -import ( - "math/big" - - "github.com/TimeleapLabs/unchained/internal/consts" - "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/bnb-chain/tss-lib/ecdsa/keygen" - "github.com/bnb-chain/tss-lib/tss" -) - -// DistributedSigner represents a TSS identity. -type DistributedSigner struct { - ctx *tss.PeerContext - partyIDs tss.UnSortedPartyIDs - PartyID *tss.PartyID - keyParty *keygen.LocalParty - localPartySaved *keygen.LocalPartySaveData - result chan keygen.LocalPartySaveData - minThreshold int - numberOfPeers int -} - -// Verify function will check message signature to be valid. -func (s *DistributedSigner) Verify(_ []byte, _ []byte, _ []byte) (bool, error) { - // TODO implement me - panic("implement me") -} - -// WriteConfigs will write identity keys to a persistent storage. -func (s *DistributedSigner) WriteConfigs() { - // nothing to do! -} - -// Update function will update the identity key about other parties. -func (s *DistributedSigner) Update(msg tss.Message) error { - if s.keyParty.PartyID() == msg.GetFrom() { - return nil - } - - bz, _, err := msg.WireBytes() - if err != nil { - utils.Logger.Error(err.Error()) - return err - } - - pMsg, err := tss.ParseWireMessage(bz, msg.GetFrom(), msg.IsBroadcast()) - if err != nil { - utils.Logger.Error(err.Error()) - return err - } - - isOK, tssErr := s.keyParty.Update(pMsg) - if tssErr != nil { - utils.Logger.Error(tssErr.Error()) - return err - } - - if !isOK { - return consts.ErrInternalError - } - - return nil -} - -// NewIdentity creates a new BLS identity. -func NewIdentity(signerID int, signers []string, outCh chan tss.Message, done chan struct{}, minThreshold int) *DistributedSigner { - partyIDs := make(tss.UnSortedPartyIDs, len(signers)) - for i, signer := range signers { - party := tss.NewPartyID(signer, signer, big.NewInt(int64(i+1))) - partyIDs[i] = party - } - - signer := &DistributedSigner{ - minThreshold: minThreshold, - numberOfPeers: len(signers), - //rawPartyID: signers[signerID], - partyIDs: partyIDs, - PartyID: partyIDs[signerID], - result: make(chan keygen.LocalPartySaveData, len(signers)), - } - - sortedPartyIDs := tss.SortPartyIDs(partyIDs) - - signer.ctx = tss.NewPeerContext(sortedPartyIDs) - - var isOk bool - signer.keyParty, isOk = keygen.NewLocalParty( - tss.NewParameters(tss.S256(), signer.ctx, sortedPartyIDs[signerID], len(signers), minThreshold), - outCh, - signer.result, - ).(*keygen.LocalParty) - - if !isOk { - panic(consts.ErrInternalError) - } - - go func(signer *DistributedSigner) { - err := signer.keyParty.Start() - if err != nil { - panic(err) - } - utils.Logger.With("ID", signer.PartyID.Moniker).Info("New Tss party started") - - for save := range signer.result { - localPartySaved := save - signer.localPartySaved = &localPartySaved - done <- struct{}{} - } - }(signer) - - return signer -} diff --git a/internal/crypto/tss/identity_test.go b/internal/crypto/tss/identity_test.go deleted file mode 100644 index 08fda944..00000000 --- a/internal/crypto/tss/identity_test.go +++ /dev/null @@ -1,140 +0,0 @@ -package tss - -import ( - "fmt" - "testing" - - "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/bnb-chain/tss-lib/common" - "github.com/bnb-chain/tss-lib/tss" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" -) - -const ( - numOfSigners = 4 - minNumOfSigners = 2 -) - -var ( - testData = []byte("HELLO hello") - - signers = []string{} -) - -type TssIdentityTestSuite struct { - suite.Suite - parties []*DistributedSigner -} - -func (s *TssIdentityTestSuite) SetupTest() { - utils.SetupLogger("info") - - for i := 0; i < numOfSigners; i++ { - signers = append(signers, fmt.Sprintf("signer-%d", i)) - } - - outCh := make(chan tss.Message, len(signers)) - done := make(chan struct{}) - - for i := 0; i < numOfSigners; i++ { - party := NewIdentity(i, signers, outCh, done, minNumOfSigners) - s.parties = append(s.parties, party) - } - - wait := 0 -keygen: - for { - select { - case msg := <-outCh: - dest := msg.GetTo() - - if dest == nil { // broadcast! - for _, p := range s.parties { - if p.PartyID.Index == msg.GetFrom().Index { - continue - } - - go func(signer *DistributedSigner) { - err := signer.Update(msg) - if err != nil { - utils.Logger.Error(err.Error()) - } - }(p) - } - } else { // point-to-point! - if dest[0].Index == msg.GetFrom().Index { - return - } - go func() { - err := s.parties[dest[0].Index].Update(msg) - if err != nil { - utils.Logger.Error(err.Error()) - } - }() - } - - case <-done: - wait++ - if wait == numOfSigners { - break keygen - } - } - } -} - -func (s *TssIdentityTestSuite) TestSign() { - outCh := make(chan tss.Message, minNumOfSigners+1) - endCh := make(chan common.SignatureData, minNumOfSigners+1) - msgSigners := make([]*MessageSigner, 0, minNumOfSigners+1) - - for i := 0; i < minNumOfSigners+1; i++ { - signer, err := s.parties[i].NewSigning(s.parties[:minNumOfSigners+1], testData, outCh, endCh) - assert.NoError(s.T(), err) - - msgSigners = append(msgSigners, signer) - } - - wait := 0 -signing: - for { - select { - case msg := <-outCh: - dest := msg.GetTo() - if dest == nil { - for _, p := range msgSigners { - if p.party.PartyID().Index == msg.GetFrom().Index { - continue - } - - go func(signer *MessageSigner, msg tss.Message) { - err := signer.Acknowledge(msg) - if err != nil { - utils.Logger.Error(err.Error()) - } - }(p, msg) - } - } else { - if dest[0].Index == msg.GetFrom().Index { - common.Logger.Fatalf("party %d tried to send a message to itself (%d)", dest[0].Index, msg.GetFrom().Index) - } - - go func(signer *MessageSigner, msg tss.Message) { - err := signer.Acknowledge(msg) - if err != nil { - utils.Logger.Error(err.Error()) - } - }(msgSigners[dest[0].Index], msg) - } - case <-endCh: - wait++ - if wait == numOfSigners-1 { - break signing - } - } - } -} - -func TestTssIdentitySuite(t *testing.T) { - suite.Run(t, new(TssIdentityTestSuite)) -} diff --git a/internal/crypto/tss/signer.go b/internal/crypto/tss/signer.go deleted file mode 100644 index d92a66aa..00000000 --- a/internal/crypto/tss/signer.go +++ /dev/null @@ -1,81 +0,0 @@ -package tss - -import ( - "math/big" - - "github.com/TimeleapLabs/unchained/internal/consts" - "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/bnb-chain/tss-lib/common" - "github.com/bnb-chain/tss-lib/ecdsa/signing" - "github.com/bnb-chain/tss-lib/tss" -) - -// MessageSigner represents state of signing of a message. -type MessageSigner struct { - party *signing.LocalParty -} - -// NewSigning will sign a data with tss secret and return signed data. -func (s *DistributedSigner) NewSigning(signers []*DistributedSigner, data []byte, out chan tss.Message, end chan<- common.SignatureData) (*MessageSigner, error) { - if !s.localPartySaved.ValidateWithProof() { - return &MessageSigner{}, consts.ErrSignerIsNotReady - } - - dataBig := new(big.Int).SetBytes(data) - - partyIDs := make(tss.UnSortedPartyIDs, len(signers)) - for i, signer := range signers { - partyIDs[i] = signer.PartyID - } - - sortedPartyIDs := tss.SortPartyIDs(partyIDs) - - ctx := tss.NewPeerContext(sortedPartyIDs) - - params := tss.NewParameters(tss.S256(), ctx, s.PartyID, s.numberOfPeers, s.minThreshold) - signer := &MessageSigner{ - party: signing.NewLocalParty(dataBig, params, *s.localPartySaved, out, end).(*signing.LocalParty), - } - - go func(signer *signing.LocalParty) { - err := signer.Start() - if err != nil { - panic(err) - } - - utils.Logger.With("ID", signer.PartyID().Moniker).Info("New Tss signer started") - }(signer.party) - - return signer, nil -} - -// Acknowledge function will confirm an acceptance from other signers. -func (s *MessageSigner) Acknowledge(msg tss.Message) error { - if s.party.PartyID() == msg.GetFrom() { - return nil - } - - bz, _, err := msg.WireBytes() - if err != nil { - utils.Logger.Error(err.Error()) - return err - } - - pMsg, err := tss.ParseWireMessage(bz, msg.GetFrom(), msg.IsBroadcast()) - if err != nil { - utils.Logger.Error(err.Error()) - return err - } - - isOK, tssErr := s.party.Update(pMsg) - if tssErr != nil { - utils.Logger.Error(tssErr.Error()) - return err - } - - if !isOK { - return consts.ErrInternalError - } - - return nil -} From 5a61099a112d4f427efe6384302bbc9aac3aaa5f Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Sat, 18 May 2024 22:24:55 +0330 Subject: [PATCH 06/29] =?UTF-8?q?=E2=9C=A8=20feat(front):=20delete=20tss?= =?UTF-8?q?=20and=20add=20frost=20algothim=20>>>=20=E2=8F=B0=201.5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/crypto/bls/bls.go | 47 + internal/crypto/bls/identity.go | 130 + internal/crypto/bls/identity_test.go | 77 + .../ethereum/contracts/UnchainedStaking.go | 2644 +++++++++++++++++ internal/crypto/ethereum/contracts/UniV3.go | 251 ++ internal/crypto/ethereum/identity.go | 89 + internal/crypto/ethereum/rpc.go | 112 + internal/crypto/ethereum/rpc_mock.go | 51 + internal/crypto/frost/identity.go | 95 + internal/crypto/frost/identity_test.go | 83 + internal/crypto/frost/signer.go | 62 + internal/crypto/identity.go | 96 + internal/crypto/identity_test.go | 32 + 13 files changed, 3769 insertions(+) create mode 100644 internal/crypto/bls/bls.go create mode 100644 internal/crypto/bls/identity.go create mode 100644 internal/crypto/bls/identity_test.go create mode 100644 internal/crypto/ethereum/contracts/UnchainedStaking.go create mode 100644 internal/crypto/ethereum/contracts/UniV3.go create mode 100644 internal/crypto/ethereum/identity.go create mode 100644 internal/crypto/ethereum/rpc.go create mode 100644 internal/crypto/ethereum/rpc_mock.go create mode 100644 internal/crypto/frost/identity.go create mode 100644 internal/crypto/frost/identity_test.go create mode 100644 internal/crypto/frost/signer.go create mode 100644 internal/crypto/identity.go create mode 100644 internal/crypto/identity_test.go diff --git a/internal/crypto/bls/bls.go b/internal/crypto/bls/bls.go new file mode 100644 index 00000000..39ac22a0 --- /dev/null +++ b/internal/crypto/bls/bls.go @@ -0,0 +1,47 @@ +package bls + +import ( + bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" +) + +func Hash(message []byte) (bls12381.G1Affine, error) { + dst := []byte("UNCHAINED") + return bls12381.HashToG1(message, dst) +} + +func RecoverSignature(bytes [48]byte) (bls12381.G1Affine, error) { + signature := new(bls12381.G1Affine) + _, err := signature.SetBytes(bytes[:]) + return *signature, err +} + +func RecoverPublicKey(bytes [96]byte) (bls12381.G2Affine, error) { + pk := new(bls12381.G2Affine) + _, err := pk.SetBytes(bytes[:]) + return *pk, err +} + +func AggregateSignatures(signatures [][]byte) ([]byte, error) { + signaturesBls := []bls12381.G1Affine{} + + for _, signature := range signatures { + signatureBls, err := RecoverSignature([48]byte(signature)) + if err != nil { + return nil, err + } + + signaturesBls = append(signaturesBls, signatureBls) + } + + aggregated := new(bls12381.G1Jac).FromAffine(&signaturesBls[0]) + + for _, sig := range signaturesBls[1:] { + sigJac := new(bls12381.G1Jac).FromAffine(&sig) + aggregated.AddAssign(sigJac) + } + + aggregatedAffine := new(bls12381.G1Affine).FromJacobian(aggregated) + aggregatedAffineByte := aggregatedAffine.Bytes() + + return aggregatedAffineByte[:], nil +} diff --git a/internal/crypto/bls/identity.go b/internal/crypto/bls/identity.go new file mode 100644 index 00000000..74ed867f --- /dev/null +++ b/internal/crypto/bls/identity.go @@ -0,0 +1,130 @@ +package bls + +import ( + "crypto/rand" + "encoding/hex" + "math/big" + + "github.com/TimeleapLabs/unchained/internal/consts" + + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/btcsuite/btcutil/base58" + bls12381_fr "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" + + "github.com/TimeleapLabs/unchained/internal/utils/address" + + "github.com/TimeleapLabs/unchained/internal/config" + bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" +) + +// Signer represents a BLS identity. +type Signer struct { + Name string + SecretKey *big.Int + PublicKey *bls12381.G2Affine + ShortPublicKey *bls12381.G1Affine + + g2Aff bls12381.G2Affine + g1Aff bls12381.G1Affine +} + +// Sign will sign a data with bls secret and return signed data. +func (s *Signer) Sign(data []byte) ([]byte, error) { + hashedMessage, err := Hash(data) + if err != nil { + panic(err) + } + + signature := new(bls12381.G1Affine).ScalarMultiplication(&hashedMessage, s.SecretKey).Bytes() + + return signature[:], err +} + +// WriteConfigs writes the secret key, public key and address to the global config object. +func (s *Signer) WriteConfigs() { + pkBytes := s.PublicKey.Bytes() + config.App.Secret.SecretKey = hex.EncodeToString(s.SecretKey.Bytes()) + config.App.Secret.PublicKey = hex.EncodeToString(pkBytes[:]) + config.App.Secret.Address = address.Calculate(pkBytes[:]) +} + +// Verify verifies the signature of a message belongs to the public key. +func (s *Signer) Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) { + signatureBls, err := RecoverSignature([48]byte(signature)) + if err != nil { + utils.Logger.With("Err", err).Error("Can't recover bls signature") + return false, consts.ErrInternalError + } + + publicKeyBls, err := RecoverPublicKey([96]byte(publicKey)) + if err != nil { + utils.Logger.With("Err", err).Error("Can't recover pub-key") + return false, consts.ErrInternalError + } + + messageBls, err := Hash(hashedMessage) + if err != nil { + utils.Logger.With("Err", err).Error("Can't convert message to hash") + return false, consts.ErrInternalError + } + + pairingSigG2, err := bls12381.Pair( + []bls12381.G1Affine{signatureBls}, + []bls12381.G2Affine{s.g2Aff}) + if err != nil { + return false, err + } + + pairingHmPk, pairingError := bls12381.Pair( + []bls12381.G1Affine{messageBls}, + []bls12381.G2Affine{publicKeyBls}) + + ok := pairingSigG2.Equal(&pairingHmPk) + + return ok, pairingError +} + +// NewIdentity creates a new BLS identity. +func NewIdentity() *Signer { + s := &Signer{ + SecretKey: new(big.Int), + } + + if config.App.Secret.SecretKey == "" && !config.App.System.AllowGenerateSecrets { + panic("BLS secret key is not provided and secrets generation is not allowed") + } + + _, _, s.g1Aff, s.g2Aff = bls12381.Generators() + + if config.App.Secret.SecretKey != "" { + decoded, err := hex.DecodeString(config.App.Secret.SecretKey) + if err != nil { + // TODO: Backwards compatibility with base58 encoded secret keys + // Remove this after a few releases + decoded = base58.Decode(config.App.Secret.SecretKey) + } + + s.SecretKey.SetBytes(decoded) + s.PublicKey = new(bls12381.G2Affine).ScalarMultiplication(&s.g2Aff, s.SecretKey) + } else { + // generate a random point in G2 + g2Order := bls12381_fr.Modulus() + sk, err := rand.Int(rand.Reader, g2Order) + if err != nil { + panic(err) + } + + pk := new(bls12381.G2Affine).ScalarMultiplication(&s.g2Aff, sk) + + s.SecretKey = sk + s.PublicKey = pk + } + + s.ShortPublicKey = new(bls12381.G1Affine).ScalarMultiplication(&s.g1Aff, s.SecretKey) + + utils.Logger. + With("Address", s.ShortPublicKey.String()). + Info("Unchained identity initialized") + + return s +} diff --git a/internal/crypto/bls/identity_test.go b/internal/crypto/bls/identity_test.go new file mode 100644 index 00000000..0b530354 --- /dev/null +++ b/internal/crypto/bls/identity_test.go @@ -0,0 +1,77 @@ +package bls + +import ( + "crypto/rand" + "testing" + + "github.com/TimeleapLabs/unchained/internal/config" + "github.com/TimeleapLabs/unchained/internal/utils" + bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" + bls12381_fr "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" +) + +var ( + testData = []byte("HELLO hello") + secondTestData = []byte("HELLO hello 2") +) + +type BlsIdentityTestSuite struct { + suite.Suite + identity *Signer +} + +func (s *BlsIdentityTestSuite) SetupTest() { + utils.SetupLogger("info") + + config.App.System.AllowGenerateSecrets = true + s.identity = NewIdentity() +} + +func (s *BlsIdentityTestSuite) TestSign() { + signedData, err := s.identity.Sign(testData) + assert.NoError(s.T(), err) + + publicKey := s.identity.PublicKey.Bytes() + + s.Run("Should verify the message correctly", func() { + isVerified, err := s.identity.Verify(signedData, testData, publicKey[:]) + assert.NoError(s.T(), err) + assert.True(s.T(), isVerified) + }) + + s.Run("Should not verify the message because of wrong data case", func() { + isVerified, err := s.identity.Verify(signedData, secondTestData, publicKey[:]) + assert.NoError(s.T(), err) + assert.False(s.T(), isVerified) + }) + + s.Run("Should not verify the message because of wrong data case", func() { + signedSecondData, err := s.identity.Sign(secondTestData) + assert.NoError(s.T(), err) + + isVerified, err := s.identity.Verify(signedSecondData, testData, publicKey[:]) + assert.NoError(s.T(), err) + assert.False(s.T(), isVerified) + }) + + s.Run("Should not verify the message because publicKey is not belong to this message", func() { + _, _, _, g2Aff := bls12381.Generators() + g2Order := bls12381_fr.Modulus() + sk, err := rand.Int(rand.Reader, g2Order) + if err != nil { + panic(err) + } + + pk := new(bls12381.G2Affine).ScalarMultiplication(&g2Aff, sk).Bytes() + + isVerified, err := s.identity.Verify(signedData, secondTestData, pk[:]) + assert.NoError(s.T(), err) + assert.False(s.T(), isVerified) + }) +} + +func TestBlsIdentitySuite(t *testing.T) { + suite.Run(t, new(BlsIdentityTestSuite)) +} diff --git a/internal/crypto/ethereum/contracts/UnchainedStaking.go b/internal/crypto/ethereum/contracts/UnchainedStaking.go new file mode 100644 index 00000000..ed3fa3c4 --- /dev/null +++ b/internal/crypto/ethereum/contracts/UnchainedStaking.go @@ -0,0 +1,2644 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contracts + +import ( + "errors" + "math/big" + "strings" + + 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" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// UnchainedStakingEIP712SetNftPrice is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingEIP712SetNftPrice struct { + Requester common.Address + NftId *big.Int + Price *big.Int + Nonce *big.Int +} + +// UnchainedStakingEIP712SetNftPriceKey is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingEIP712SetNftPriceKey struct { + NftId *big.Int + Price *big.Int + Nonce *big.Int +} + +// UnchainedStakingEIP712SetParams is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingEIP712SetParams struct { + Requester common.Address + Token common.Address + Nft common.Address + NftTracker common.Address + Threshold *big.Int + Expiration *big.Int + Nonce *big.Int +} + +// UnchainedStakingEIP712SetParamsKey is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingEIP712SetParamsKey struct { + Token common.Address + Nft common.Address + NftTracker common.Address + Threshold *big.Int + Expiration *big.Int + Nonce *big.Int +} + +// UnchainedStakingEIP712SetSigner is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingEIP712SetSigner struct { + Staker common.Address + Signer common.Address +} + +// UnchainedStakingEIP712Transfer is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingEIP712Transfer struct { + Signer common.Address + From common.Address + To common.Address + Amount *big.Int + NftIds []*big.Int + Nonces []*big.Int +} + +// UnchainedStakingEIP712TransferKey is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingEIP712TransferKey struct { + From common.Address + To common.Address + Amount *big.Int + NftIds []*big.Int + Nonces []*big.Int +} + +// UnchainedStakingNftPriceInfo is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingNftPriceInfo struct { + NftId *big.Int + Price *big.Int + Voted *big.Int + Accepted bool +} + +// UnchainedStakingParamsInfo is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingParamsInfo struct { + Token common.Address + Nft common.Address + NftTracker common.Address + Threshold *big.Int + Expiration *big.Int + Voted *big.Int + Nonce *big.Int + Accepted bool +} + +// UnchainedStakingSignature is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingSignature struct { + V uint8 + R [32]byte + S [32]byte +} + +// UnchainedStakingStake is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingStake struct { + Amount *big.Int + Unlock *big.Int + NftIds []*big.Int +} + +// UnchainedStakingTransferInfo is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingTransferInfo struct { + From common.Address + To common.Address + Amount *big.Int + NftIds []*big.Int + Voted *big.Int + Accepted bool + Nonces []*big.Int +} + +// UnchainedStakingMetaData contains all meta data concerning the UnchainedStaking contract. +var UnchainedStakingMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTrackerAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"consensusLock\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AddressInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyStaked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AmountZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BlsNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DurationZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ECDSAInvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"ECDSAInvalidSignatureLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"ECDSAInvalidSignatureS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Forbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"NonceUsed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotUnlocked\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"StakeExpiresBeforeVote\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StakeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"TopicExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"VotingPowerZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNFT\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"from\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"to\",\"type\":\"bytes32\"}],\"name\":\"BlsAddressChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unlock\",\"type\":\"uint256\"}],\"name\":\"Extended\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"ParamsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"SignerChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"StakeIncreased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"Staked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"UnStaked\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"evm\",\"type\":\"address\"}],\"name\":\"blsAddressOf\",\"outputs\":[{\"internalType\":\"bytes20\",\"name\":\"\",\"type\":\"bytes20\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"bls\",\"type\":\"bytes20\"}],\"name\":\"evmAddressOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"}],\"name\":\"extend\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConsensusThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"}],\"name\":\"getNftPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getParams\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"accepted\",\"type\":\"bool\"}],\"internalType\":\"structUnchainedStaking.ParamsInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetNftPriceKey\",\"name\":\"key\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"getRequestedSetNftPrice\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetParamsKey\",\"name\":\"key\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"getRequestedSetParams\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.EIP712TransferKey\",\"name\":\"key\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"transferer\",\"type\":\"address\"}],\"name\":\"getRequestedTransfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetNftPriceKey\",\"name\":\"key\",\"type\":\"tuple\"}],\"name\":\"getSetNftPriceData\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"accepted\",\"type\":\"bool\"}],\"internalType\":\"structUnchainedStaking.NftPriceInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetParamsKey\",\"name\":\"key\",\"type\":\"tuple\"}],\"name\":\"getSetParamsData\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"accepted\",\"type\":\"bool\"}],\"internalType\":\"structUnchainedStaking.ParamsInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"evm\",\"type\":\"address\"}],\"name\":\"getStake\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.Stake\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"bls\",\"type\":\"bytes20\"}],\"name\":\"getStake\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.Stake\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalVotingPower\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.EIP712TransferKey\",\"name\":\"key\",\"type\":\"tuple\"}],\"name\":\"getTransferData\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"accepted\",\"type\":\"bool\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.TransferInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"bls\",\"type\":\"bytes20\"}],\"name\":\"getVotingPower\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"evm\",\"type\":\"address\"}],\"name\":\"getVotingPower\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"increaseStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"blsAddress\",\"type\":\"bytes20\"}],\"name\":\"setBlsAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetNftPrice[]\",\"name\":\"eip712SetNftPrices\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"}],\"name\":\"setNftPrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetParams[]\",\"name\":\"eip712SetParams\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"}],\"name\":\"setParams\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"internalType\":\"structUnchainedStaking.EIP712SetSigner\",\"name\":\"eip712SetSigner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"stakerSignature\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signerSignature\",\"type\":\"tuple\"}],\"name\":\"setSigner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"signerToStaker\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"stake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"}],\"name\":\"stakerToSigner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.EIP712Transfer[]\",\"name\":\"eip712Transferes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unstake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetParams\",\"name\":\"eip712SetParam\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signature\",\"type\":\"tuple\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetNftPrice\",\"name\":\"eip712SetNftPrice\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signature\",\"type\":\"tuple\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"internalType\":\"structUnchainedStaking.EIP712SetSigner\",\"name\":\"eip712SetSigner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"stakerSignature\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signerSignature\",\"type\":\"tuple\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.EIP712Transfer\",\"name\":\"eip712Transfer\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signature\",\"type\":\"tuple\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +// UnchainedStakingABI is the input ABI used to generate the binding from. +// Deprecated: Use UnchainedStakingMetaData.ABI instead. +var UnchainedStakingABI = UnchainedStakingMetaData.ABI + +// UnchainedStaking is an auto generated Go binding around an Ethereum contract. +type UnchainedStaking struct { + UnchainedStakingCaller // Read-only binding to the contract + UnchainedStakingTransactor // Write-only binding to the contract + UnchainedStakingFilterer // Log filterer for contract events +} + +// UnchainedStakingCaller is an auto generated read-only Go binding around an Ethereum contract. +type UnchainedStakingCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UnchainedStakingTransactor is an auto generated write-only Go binding around an Ethereum contract. +type UnchainedStakingTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UnchainedStakingFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type UnchainedStakingFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UnchainedStakingSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type UnchainedStakingSession struct { + Contract *UnchainedStaking // 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 +} + +// UnchainedStakingCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type UnchainedStakingCallerSession struct { + Contract *UnchainedStakingCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// UnchainedStakingTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type UnchainedStakingTransactorSession struct { + Contract *UnchainedStakingTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// UnchainedStakingRaw is an auto generated low-level Go binding around an Ethereum contract. +type UnchainedStakingRaw struct { + Contract *UnchainedStaking // Generic contract binding to access the raw methods on +} + +// UnchainedStakingCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type UnchainedStakingCallerRaw struct { + Contract *UnchainedStakingCaller // Generic read-only contract binding to access the raw methods on +} + +// UnchainedStakingTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type UnchainedStakingTransactorRaw struct { + Contract *UnchainedStakingTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewUnchainedStaking creates a new instance of UnchainedStaking, bound to a specific deployed contract. +func NewUnchainedStaking(address common.Address, backend bind.ContractBackend) (*UnchainedStaking, error) { + contract, err := bindUnchainedStaking(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &UnchainedStaking{UnchainedStakingCaller: UnchainedStakingCaller{contract: contract}, UnchainedStakingTransactor: UnchainedStakingTransactor{contract: contract}, UnchainedStakingFilterer: UnchainedStakingFilterer{contract: contract}}, nil +} + +// NewUnchainedStakingCaller creates a new read-only instance of UnchainedStaking, bound to a specific deployed contract. +func NewUnchainedStakingCaller(address common.Address, caller bind.ContractCaller) (*UnchainedStakingCaller, error) { + contract, err := bindUnchainedStaking(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &UnchainedStakingCaller{contract: contract}, nil +} + +// NewUnchainedStakingTransactor creates a new write-only instance of UnchainedStaking, bound to a specific deployed contract. +func NewUnchainedStakingTransactor(address common.Address, transactor bind.ContractTransactor) (*UnchainedStakingTransactor, error) { + contract, err := bindUnchainedStaking(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &UnchainedStakingTransactor{contract: contract}, nil +} + +// NewUnchainedStakingFilterer creates a new log filterer instance of UnchainedStaking, bound to a specific deployed contract. +func NewUnchainedStakingFilterer(address common.Address, filterer bind.ContractFilterer) (*UnchainedStakingFilterer, error) { + contract, err := bindUnchainedStaking(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &UnchainedStakingFilterer{contract: contract}, nil +} + +// bindUnchainedStaking binds a generic wrapper to an already deployed contract. +func bindUnchainedStaking(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := UnchainedStakingMetaData.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 (_UnchainedStaking *UnchainedStakingRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _UnchainedStaking.Contract.UnchainedStakingCaller.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 (_UnchainedStaking *UnchainedStakingRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _UnchainedStaking.Contract.UnchainedStakingTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_UnchainedStaking *UnchainedStakingRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _UnchainedStaking.Contract.UnchainedStakingTransactor.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 (_UnchainedStaking *UnchainedStakingCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _UnchainedStaking.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 (_UnchainedStaking *UnchainedStakingTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _UnchainedStaking.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_UnchainedStaking *UnchainedStakingTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _UnchainedStaking.Contract.contract.Transact(opts, method, params...) +} + +// BlsAddressOf is a free data retrieval call binding the contract method 0x9e95a1a5. +// +// Solidity: function blsAddressOf(address evm) view returns(bytes20) +func (_UnchainedStaking *UnchainedStakingCaller) BlsAddressOf(opts *bind.CallOpts, evm common.Address) ([20]byte, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "blsAddressOf", evm) + + if err != nil { + return *new([20]byte), err + } + + out0 := *abi.ConvertType(out[0], new([20]byte)).(*[20]byte) + + return out0, err + +} + +// BlsAddressOf is a free data retrieval call binding the contract method 0x9e95a1a5. +// +// Solidity: function blsAddressOf(address evm) view returns(bytes20) +func (_UnchainedStaking *UnchainedStakingSession) BlsAddressOf(evm common.Address) ([20]byte, error) { + return _UnchainedStaking.Contract.BlsAddressOf(&_UnchainedStaking.CallOpts, evm) +} + +// BlsAddressOf is a free data retrieval call binding the contract method 0x9e95a1a5. +// +// Solidity: function blsAddressOf(address evm) view returns(bytes20) +func (_UnchainedStaking *UnchainedStakingCallerSession) BlsAddressOf(evm common.Address) ([20]byte, error) { + return _UnchainedStaking.Contract.BlsAddressOf(&_UnchainedStaking.CallOpts, evm) +} + +// EvmAddressOf is a free data retrieval call binding the contract method 0x40043ead. +// +// Solidity: function evmAddressOf(bytes20 bls) view returns(address) +func (_UnchainedStaking *UnchainedStakingCaller) EvmAddressOf(opts *bind.CallOpts, bls [20]byte) (common.Address, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "evmAddressOf", bls) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// EvmAddressOf is a free data retrieval call binding the contract method 0x40043ead. +// +// Solidity: function evmAddressOf(bytes20 bls) view returns(address) +func (_UnchainedStaking *UnchainedStakingSession) EvmAddressOf(bls [20]byte) (common.Address, error) { + return _UnchainedStaking.Contract.EvmAddressOf(&_UnchainedStaking.CallOpts, bls) +} + +// EvmAddressOf is a free data retrieval call binding the contract method 0x40043ead. +// +// Solidity: function evmAddressOf(bytes20 bls) view returns(address) +func (_UnchainedStaking *UnchainedStakingCallerSession) EvmAddressOf(bls [20]byte) (common.Address, error) { + return _UnchainedStaking.Contract.EvmAddressOf(&_UnchainedStaking.CallOpts, bls) +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCaller) GetChainId(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getChainId") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingSession) GetChainId() (*big.Int, error) { + return _UnchainedStaking.Contract.GetChainId(&_UnchainedStaking.CallOpts) +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetChainId() (*big.Int, error) { + return _UnchainedStaking.Contract.GetChainId(&_UnchainedStaking.CallOpts) +} + +// GetConsensusThreshold is a free data retrieval call binding the contract method 0xd42791e1. +// +// Solidity: function getConsensusThreshold() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCaller) GetConsensusThreshold(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getConsensusThreshold") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetConsensusThreshold is a free data retrieval call binding the contract method 0xd42791e1. +// +// Solidity: function getConsensusThreshold() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingSession) GetConsensusThreshold() (*big.Int, error) { + return _UnchainedStaking.Contract.GetConsensusThreshold(&_UnchainedStaking.CallOpts) +} + +// GetConsensusThreshold is a free data retrieval call binding the contract method 0xd42791e1. +// +// Solidity: function getConsensusThreshold() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetConsensusThreshold() (*big.Int, error) { + return _UnchainedStaking.Contract.GetConsensusThreshold(&_UnchainedStaking.CallOpts) +} + +// GetNftPrice is a free data retrieval call binding the contract method 0x7bf0989a. +// +// Solidity: function getNftPrice(uint256 nftId) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCaller) GetNftPrice(opts *bind.CallOpts, nftId *big.Int) (*big.Int, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getNftPrice", nftId) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetNftPrice is a free data retrieval call binding the contract method 0x7bf0989a. +// +// Solidity: function getNftPrice(uint256 nftId) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingSession) GetNftPrice(nftId *big.Int) (*big.Int, error) { + return _UnchainedStaking.Contract.GetNftPrice(&_UnchainedStaking.CallOpts, nftId) +} + +// GetNftPrice is a free data retrieval call binding the contract method 0x7bf0989a. +// +// Solidity: function getNftPrice(uint256 nftId) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetNftPrice(nftId *big.Int) (*big.Int, error) { + return _UnchainedStaking.Contract.GetNftPrice(&_UnchainedStaking.CallOpts, nftId) +} + +// GetParams is a free data retrieval call binding the contract method 0x5e615a6b. +// +// Solidity: function getParams() view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingCaller) GetParams(opts *bind.CallOpts) (UnchainedStakingParamsInfo, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getParams") + + if err != nil { + return *new(UnchainedStakingParamsInfo), err + } + + out0 := *abi.ConvertType(out[0], new(UnchainedStakingParamsInfo)).(*UnchainedStakingParamsInfo) + + return out0, err + +} + +// GetParams is a free data retrieval call binding the contract method 0x5e615a6b. +// +// Solidity: function getParams() view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingSession) GetParams() (UnchainedStakingParamsInfo, error) { + return _UnchainedStaking.Contract.GetParams(&_UnchainedStaking.CallOpts) +} + +// GetParams is a free data retrieval call binding the contract method 0x5e615a6b. +// +// Solidity: function getParams() view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetParams() (UnchainedStakingParamsInfo, error) { + return _UnchainedStaking.Contract.GetParams(&_UnchainedStaking.CallOpts) +} + +// GetRequestedSetNftPrice is a free data retrieval call binding the contract method 0x45a6e62f. +// +// Solidity: function getRequestedSetNftPrice((uint256,uint256,uint256) key, address requester) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCaller) GetRequestedSetNftPrice(opts *bind.CallOpts, key UnchainedStakingEIP712SetNftPriceKey, requester common.Address) (bool, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getRequestedSetNftPrice", key, requester) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// GetRequestedSetNftPrice is a free data retrieval call binding the contract method 0x45a6e62f. +// +// Solidity: function getRequestedSetNftPrice((uint256,uint256,uint256) key, address requester) view returns(bool) +func (_UnchainedStaking *UnchainedStakingSession) GetRequestedSetNftPrice(key UnchainedStakingEIP712SetNftPriceKey, requester common.Address) (bool, error) { + return _UnchainedStaking.Contract.GetRequestedSetNftPrice(&_UnchainedStaking.CallOpts, key, requester) +} + +// GetRequestedSetNftPrice is a free data retrieval call binding the contract method 0x45a6e62f. +// +// Solidity: function getRequestedSetNftPrice((uint256,uint256,uint256) key, address requester) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetRequestedSetNftPrice(key UnchainedStakingEIP712SetNftPriceKey, requester common.Address) (bool, error) { + return _UnchainedStaking.Contract.GetRequestedSetNftPrice(&_UnchainedStaking.CallOpts, key, requester) +} + +// GetRequestedSetParams is a free data retrieval call binding the contract method 0x984d92e8. +// +// Solidity: function getRequestedSetParams((address,address,address,uint256,uint256,uint256) key, address requester) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCaller) GetRequestedSetParams(opts *bind.CallOpts, key UnchainedStakingEIP712SetParamsKey, requester common.Address) (bool, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getRequestedSetParams", key, requester) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// GetRequestedSetParams is a free data retrieval call binding the contract method 0x984d92e8. +// +// Solidity: function getRequestedSetParams((address,address,address,uint256,uint256,uint256) key, address requester) view returns(bool) +func (_UnchainedStaking *UnchainedStakingSession) GetRequestedSetParams(key UnchainedStakingEIP712SetParamsKey, requester common.Address) (bool, error) { + return _UnchainedStaking.Contract.GetRequestedSetParams(&_UnchainedStaking.CallOpts, key, requester) +} + +// GetRequestedSetParams is a free data retrieval call binding the contract method 0x984d92e8. +// +// Solidity: function getRequestedSetParams((address,address,address,uint256,uint256,uint256) key, address requester) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetRequestedSetParams(key UnchainedStakingEIP712SetParamsKey, requester common.Address) (bool, error) { + return _UnchainedStaking.Contract.GetRequestedSetParams(&_UnchainedStaking.CallOpts, key, requester) +} + +// GetRequestedTransfer is a free data retrieval call binding the contract method 0xf8560edb. +// +// Solidity: function getRequestedTransfer((address,address,uint256,uint256[],uint256[]) key, address transferer) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCaller) GetRequestedTransfer(opts *bind.CallOpts, key UnchainedStakingEIP712TransferKey, transferer common.Address) (bool, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getRequestedTransfer", key, transferer) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// GetRequestedTransfer is a free data retrieval call binding the contract method 0xf8560edb. +// +// Solidity: function getRequestedTransfer((address,address,uint256,uint256[],uint256[]) key, address transferer) view returns(bool) +func (_UnchainedStaking *UnchainedStakingSession) GetRequestedTransfer(key UnchainedStakingEIP712TransferKey, transferer common.Address) (bool, error) { + return _UnchainedStaking.Contract.GetRequestedTransfer(&_UnchainedStaking.CallOpts, key, transferer) +} + +// GetRequestedTransfer is a free data retrieval call binding the contract method 0xf8560edb. +// +// Solidity: function getRequestedTransfer((address,address,uint256,uint256[],uint256[]) key, address transferer) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetRequestedTransfer(key UnchainedStakingEIP712TransferKey, transferer common.Address) (bool, error) { + return _UnchainedStaking.Contract.GetRequestedTransfer(&_UnchainedStaking.CallOpts, key, transferer) +} + +// GetSetNftPriceData is a free data retrieval call binding the contract method 0xbbb5b849. +// +// Solidity: function getSetNftPriceData((uint256,uint256,uint256) key) view returns((uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingCaller) GetSetNftPriceData(opts *bind.CallOpts, key UnchainedStakingEIP712SetNftPriceKey) (UnchainedStakingNftPriceInfo, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getSetNftPriceData", key) + + if err != nil { + return *new(UnchainedStakingNftPriceInfo), err + } + + out0 := *abi.ConvertType(out[0], new(UnchainedStakingNftPriceInfo)).(*UnchainedStakingNftPriceInfo) + + return out0, err + +} + +// GetSetNftPriceData is a free data retrieval call binding the contract method 0xbbb5b849. +// +// Solidity: function getSetNftPriceData((uint256,uint256,uint256) key) view returns((uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingSession) GetSetNftPriceData(key UnchainedStakingEIP712SetNftPriceKey) (UnchainedStakingNftPriceInfo, error) { + return _UnchainedStaking.Contract.GetSetNftPriceData(&_UnchainedStaking.CallOpts, key) +} + +// GetSetNftPriceData is a free data retrieval call binding the contract method 0xbbb5b849. +// +// Solidity: function getSetNftPriceData((uint256,uint256,uint256) key) view returns((uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetSetNftPriceData(key UnchainedStakingEIP712SetNftPriceKey) (UnchainedStakingNftPriceInfo, error) { + return _UnchainedStaking.Contract.GetSetNftPriceData(&_UnchainedStaking.CallOpts, key) +} + +// GetSetParamsData is a free data retrieval call binding the contract method 0x300fab4f. +// +// Solidity: function getSetParamsData((address,address,address,uint256,uint256,uint256) key) view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingCaller) GetSetParamsData(opts *bind.CallOpts, key UnchainedStakingEIP712SetParamsKey) (UnchainedStakingParamsInfo, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getSetParamsData", key) + + if err != nil { + return *new(UnchainedStakingParamsInfo), err + } + + out0 := *abi.ConvertType(out[0], new(UnchainedStakingParamsInfo)).(*UnchainedStakingParamsInfo) + + return out0, err + +} + +// GetSetParamsData is a free data retrieval call binding the contract method 0x300fab4f. +// +// Solidity: function getSetParamsData((address,address,address,uint256,uint256,uint256) key) view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingSession) GetSetParamsData(key UnchainedStakingEIP712SetParamsKey) (UnchainedStakingParamsInfo, error) { + return _UnchainedStaking.Contract.GetSetParamsData(&_UnchainedStaking.CallOpts, key) +} + +// GetSetParamsData is a free data retrieval call binding the contract method 0x300fab4f. +// +// Solidity: function getSetParamsData((address,address,address,uint256,uint256,uint256) key) view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetSetParamsData(key UnchainedStakingEIP712SetParamsKey) (UnchainedStakingParamsInfo, error) { + return _UnchainedStaking.Contract.GetSetParamsData(&_UnchainedStaking.CallOpts, key) +} + +// GetStake is a free data retrieval call binding the contract method 0x7a766460. +// +// Solidity: function getStake(address evm) view returns((uint256,uint256,uint256[])) +func (_UnchainedStaking *UnchainedStakingCaller) GetStake(opts *bind.CallOpts, evm common.Address) (UnchainedStakingStake, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getStake", evm) + + if err != nil { + return *new(UnchainedStakingStake), err + } + + out0 := *abi.ConvertType(out[0], new(UnchainedStakingStake)).(*UnchainedStakingStake) + + return out0, err + +} + +// GetStake is a free data retrieval call binding the contract method 0x7a766460. +// +// Solidity: function getStake(address evm) view returns((uint256,uint256,uint256[])) +func (_UnchainedStaking *UnchainedStakingSession) GetStake(evm common.Address) (UnchainedStakingStake, error) { + return _UnchainedStaking.Contract.GetStake(&_UnchainedStaking.CallOpts, evm) +} + +// GetStake is a free data retrieval call binding the contract method 0x7a766460. +// +// Solidity: function getStake(address evm) view returns((uint256,uint256,uint256[])) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetStake(evm common.Address) (UnchainedStakingStake, error) { + return _UnchainedStaking.Contract.GetStake(&_UnchainedStaking.CallOpts, evm) +} + +// GetStake0 is a free data retrieval call binding the contract method 0xf86fec69. +// +// Solidity: function getStake(bytes20 bls) view returns((uint256,uint256,uint256[])) +func (_UnchainedStaking *UnchainedStakingCaller) GetStake0(opts *bind.CallOpts, bls [20]byte) (UnchainedStakingStake, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getStake0", bls) + + if err != nil { + return *new(UnchainedStakingStake), err + } + + out0 := *abi.ConvertType(out[0], new(UnchainedStakingStake)).(*UnchainedStakingStake) + + return out0, err + +} + +// GetStake0 is a free data retrieval call binding the contract method 0xf86fec69. +// +// Solidity: function getStake(bytes20 bls) view returns((uint256,uint256,uint256[])) +func (_UnchainedStaking *UnchainedStakingSession) GetStake0(bls [20]byte) (UnchainedStakingStake, error) { + return _UnchainedStaking.Contract.GetStake0(&_UnchainedStaking.CallOpts, bls) +} + +// GetStake0 is a free data retrieval call binding the contract method 0xf86fec69. +// +// Solidity: function getStake(bytes20 bls) view returns((uint256,uint256,uint256[])) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetStake0(bls [20]byte) (UnchainedStakingStake, error) { + return _UnchainedStaking.Contract.GetStake0(&_UnchainedStaking.CallOpts, bls) +} + +// GetTotalVotingPower is a free data retrieval call binding the contract method 0x11acc1a7. +// +// Solidity: function getTotalVotingPower() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCaller) GetTotalVotingPower(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getTotalVotingPower") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetTotalVotingPower is a free data retrieval call binding the contract method 0x11acc1a7. +// +// Solidity: function getTotalVotingPower() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingSession) GetTotalVotingPower() (*big.Int, error) { + return _UnchainedStaking.Contract.GetTotalVotingPower(&_UnchainedStaking.CallOpts) +} + +// GetTotalVotingPower is a free data retrieval call binding the contract method 0x11acc1a7. +// +// Solidity: function getTotalVotingPower() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetTotalVotingPower() (*big.Int, error) { + return _UnchainedStaking.Contract.GetTotalVotingPower(&_UnchainedStaking.CallOpts) +} + +// GetTransferData is a free data retrieval call binding the contract method 0x865e1281. +// +// Solidity: function getTransferData((address,address,uint256,uint256[],uint256[]) key) view returns((address,address,uint256,uint256[],uint256,bool,uint256[])) +func (_UnchainedStaking *UnchainedStakingCaller) GetTransferData(opts *bind.CallOpts, key UnchainedStakingEIP712TransferKey) (UnchainedStakingTransferInfo, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getTransferData", key) + + if err != nil { + return *new(UnchainedStakingTransferInfo), err + } + + out0 := *abi.ConvertType(out[0], new(UnchainedStakingTransferInfo)).(*UnchainedStakingTransferInfo) + + return out0, err + +} + +// GetTransferData is a free data retrieval call binding the contract method 0x865e1281. +// +// Solidity: function getTransferData((address,address,uint256,uint256[],uint256[]) key) view returns((address,address,uint256,uint256[],uint256,bool,uint256[])) +func (_UnchainedStaking *UnchainedStakingSession) GetTransferData(key UnchainedStakingEIP712TransferKey) (UnchainedStakingTransferInfo, error) { + return _UnchainedStaking.Contract.GetTransferData(&_UnchainedStaking.CallOpts, key) +} + +// GetTransferData is a free data retrieval call binding the contract method 0x865e1281. +// +// Solidity: function getTransferData((address,address,uint256,uint256[],uint256[]) key) view returns((address,address,uint256,uint256[],uint256,bool,uint256[])) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetTransferData(key UnchainedStakingEIP712TransferKey) (UnchainedStakingTransferInfo, error) { + return _UnchainedStaking.Contract.GetTransferData(&_UnchainedStaking.CallOpts, key) +} + +// GetVotingPower is a free data retrieval call binding the contract method 0x68eacf93. +// +// Solidity: function getVotingPower(bytes20 bls) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCaller) GetVotingPower(opts *bind.CallOpts, bls [20]byte) (*big.Int, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getVotingPower", bls) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetVotingPower is a free data retrieval call binding the contract method 0x68eacf93. +// +// Solidity: function getVotingPower(bytes20 bls) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingSession) GetVotingPower(bls [20]byte) (*big.Int, error) { + return _UnchainedStaking.Contract.GetVotingPower(&_UnchainedStaking.CallOpts, bls) +} + +// GetVotingPower is a free data retrieval call binding the contract method 0x68eacf93. +// +// Solidity: function getVotingPower(bytes20 bls) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetVotingPower(bls [20]byte) (*big.Int, error) { + return _UnchainedStaking.Contract.GetVotingPower(&_UnchainedStaking.CallOpts, bls) +} + +// GetVotingPower0 is a free data retrieval call binding the contract method 0xbb4d4436. +// +// Solidity: function getVotingPower(address evm) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCaller) GetVotingPower0(opts *bind.CallOpts, evm common.Address) (*big.Int, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getVotingPower0", evm) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetVotingPower0 is a free data retrieval call binding the contract method 0xbb4d4436. +// +// Solidity: function getVotingPower(address evm) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingSession) GetVotingPower0(evm common.Address) (*big.Int, error) { + return _UnchainedStaking.Contract.GetVotingPower0(&_UnchainedStaking.CallOpts, evm) +} + +// GetVotingPower0 is a free data retrieval call binding the contract method 0xbb4d4436. +// +// Solidity: function getVotingPower(address evm) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetVotingPower0(evm common.Address) (*big.Int, error) { + return _UnchainedStaking.Contract.GetVotingPower0(&_UnchainedStaking.CallOpts, evm) +} + +// OnERC721Received is a free data retrieval call binding the contract method 0x150b7a02. +// +// Solidity: function onERC721Received(address , address , uint256 , bytes ) view returns(bytes4) +func (_UnchainedStaking *UnchainedStakingCaller) OnERC721Received(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 []byte) ([4]byte, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "onERC721Received", arg0, arg1, arg2, arg3) + + if err != nil { + return *new([4]byte), err + } + + out0 := *abi.ConvertType(out[0], new([4]byte)).(*[4]byte) + + return out0, err + +} + +// OnERC721Received is a free data retrieval call binding the contract method 0x150b7a02. +// +// Solidity: function onERC721Received(address , address , uint256 , bytes ) view returns(bytes4) +func (_UnchainedStaking *UnchainedStakingSession) OnERC721Received(arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 []byte) ([4]byte, error) { + return _UnchainedStaking.Contract.OnERC721Received(&_UnchainedStaking.CallOpts, arg0, arg1, arg2, arg3) +} + +// OnERC721Received is a free data retrieval call binding the contract method 0x150b7a02. +// +// Solidity: function onERC721Received(address , address , uint256 , bytes ) view returns(bytes4) +func (_UnchainedStaking *UnchainedStakingCallerSession) OnERC721Received(arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 []byte) ([4]byte, error) { + return _UnchainedStaking.Contract.OnERC721Received(&_UnchainedStaking.CallOpts, arg0, arg1, arg2, arg3) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_UnchainedStaking *UnchainedStakingCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _UnchainedStaking.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 (_UnchainedStaking *UnchainedStakingSession) Owner() (common.Address, error) { + return _UnchainedStaking.Contract.Owner(&_UnchainedStaking.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_UnchainedStaking *UnchainedStakingCallerSession) Owner() (common.Address, error) { + return _UnchainedStaking.Contract.Owner(&_UnchainedStaking.CallOpts) +} + +// SignerToStaker is a free data retrieval call binding the contract method 0xad5a98c5. +// +// Solidity: function signerToStaker(address signer) view returns(address) +func (_UnchainedStaking *UnchainedStakingCaller) SignerToStaker(opts *bind.CallOpts, signer common.Address) (common.Address, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "signerToStaker", signer) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SignerToStaker is a free data retrieval call binding the contract method 0xad5a98c5. +// +// Solidity: function signerToStaker(address signer) view returns(address) +func (_UnchainedStaking *UnchainedStakingSession) SignerToStaker(signer common.Address) (common.Address, error) { + return _UnchainedStaking.Contract.SignerToStaker(&_UnchainedStaking.CallOpts, signer) +} + +// SignerToStaker is a free data retrieval call binding the contract method 0xad5a98c5. +// +// Solidity: function signerToStaker(address signer) view returns(address) +func (_UnchainedStaking *UnchainedStakingCallerSession) SignerToStaker(signer common.Address) (common.Address, error) { + return _UnchainedStaking.Contract.SignerToStaker(&_UnchainedStaking.CallOpts, signer) +} + +// StakerToSigner is a free data retrieval call binding the contract method 0xc7bcae78. +// +// Solidity: function stakerToSigner(address staker) view returns(address) +func (_UnchainedStaking *UnchainedStakingCaller) StakerToSigner(opts *bind.CallOpts, staker common.Address) (common.Address, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "stakerToSigner", staker) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// StakerToSigner is a free data retrieval call binding the contract method 0xc7bcae78. +// +// Solidity: function stakerToSigner(address staker) view returns(address) +func (_UnchainedStaking *UnchainedStakingSession) StakerToSigner(staker common.Address) (common.Address, error) { + return _UnchainedStaking.Contract.StakerToSigner(&_UnchainedStaking.CallOpts, staker) +} + +// StakerToSigner is a free data retrieval call binding the contract method 0xc7bcae78. +// +// Solidity: function stakerToSigner(address staker) view returns(address) +func (_UnchainedStaking *UnchainedStakingCallerSession) StakerToSigner(staker common.Address) (common.Address, error) { + return _UnchainedStaking.Contract.StakerToSigner(&_UnchainedStaking.CallOpts, staker) +} + +// Verify is a free data retrieval call binding the contract method 0x6e0b9e40. +// +// Solidity: function verify((address,address,address,address,uint256,uint256,uint256) eip712SetParam, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCaller) Verify(opts *bind.CallOpts, eip712SetParam UnchainedStakingEIP712SetParams, signature UnchainedStakingSignature) (bool, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "verify", eip712SetParam, signature) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Verify is a free data retrieval call binding the contract method 0x6e0b9e40. +// +// Solidity: function verify((address,address,address,address,uint256,uint256,uint256) eip712SetParam, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingSession) Verify(eip712SetParam UnchainedStakingEIP712SetParams, signature UnchainedStakingSignature) (bool, error) { + return _UnchainedStaking.Contract.Verify(&_UnchainedStaking.CallOpts, eip712SetParam, signature) +} + +// Verify is a free data retrieval call binding the contract method 0x6e0b9e40. +// +// Solidity: function verify((address,address,address,address,uint256,uint256,uint256) eip712SetParam, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCallerSession) Verify(eip712SetParam UnchainedStakingEIP712SetParams, signature UnchainedStakingSignature) (bool, error) { + return _UnchainedStaking.Contract.Verify(&_UnchainedStaking.CallOpts, eip712SetParam, signature) +} + +// Verify0 is a free data retrieval call binding the contract method 0x709eb01b. +// +// Solidity: function verify((address,uint256,uint256,uint256) eip712SetNftPrice, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCaller) Verify0(opts *bind.CallOpts, eip712SetNftPrice UnchainedStakingEIP712SetNftPrice, signature UnchainedStakingSignature) (bool, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "verify0", eip712SetNftPrice, signature) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Verify0 is a free data retrieval call binding the contract method 0x709eb01b. +// +// Solidity: function verify((address,uint256,uint256,uint256) eip712SetNftPrice, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingSession) Verify0(eip712SetNftPrice UnchainedStakingEIP712SetNftPrice, signature UnchainedStakingSignature) (bool, error) { + return _UnchainedStaking.Contract.Verify0(&_UnchainedStaking.CallOpts, eip712SetNftPrice, signature) +} + +// Verify0 is a free data retrieval call binding the contract method 0x709eb01b. +// +// Solidity: function verify((address,uint256,uint256,uint256) eip712SetNftPrice, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCallerSession) Verify0(eip712SetNftPrice UnchainedStakingEIP712SetNftPrice, signature UnchainedStakingSignature) (bool, error) { + return _UnchainedStaking.Contract.Verify0(&_UnchainedStaking.CallOpts, eip712SetNftPrice, signature) +} + +// Verify1 is a free data retrieval call binding the contract method 0x7856cc70. +// +// Solidity: function verify((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCaller) Verify1(opts *bind.CallOpts, eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (bool, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "verify1", eip712SetSigner, stakerSignature, signerSignature) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Verify1 is a free data retrieval call binding the contract method 0x7856cc70. +// +// Solidity: function verify((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingSession) Verify1(eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (bool, error) { + return _UnchainedStaking.Contract.Verify1(&_UnchainedStaking.CallOpts, eip712SetSigner, stakerSignature, signerSignature) +} + +// Verify1 is a free data retrieval call binding the contract method 0x7856cc70. +// +// Solidity: function verify((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCallerSession) Verify1(eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (bool, error) { + return _UnchainedStaking.Contract.Verify1(&_UnchainedStaking.CallOpts, eip712SetSigner, stakerSignature, signerSignature) +} + +// Verify2 is a free data retrieval call binding the contract method 0xb7543d3e. +// +// Solidity: function verify((address,address,address,uint256,uint256[],uint256[]) eip712Transfer, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCaller) Verify2(opts *bind.CallOpts, eip712Transfer UnchainedStakingEIP712Transfer, signature UnchainedStakingSignature) (bool, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "verify2", eip712Transfer, signature) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Verify2 is a free data retrieval call binding the contract method 0xb7543d3e. +// +// Solidity: function verify((address,address,address,uint256,uint256[],uint256[]) eip712Transfer, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingSession) Verify2(eip712Transfer UnchainedStakingEIP712Transfer, signature UnchainedStakingSignature) (bool, error) { + return _UnchainedStaking.Contract.Verify2(&_UnchainedStaking.CallOpts, eip712Transfer, signature) +} + +// Verify2 is a free data retrieval call binding the contract method 0xb7543d3e. +// +// Solidity: function verify((address,address,address,uint256,uint256[],uint256[]) eip712Transfer, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCallerSession) Verify2(eip712Transfer UnchainedStakingEIP712Transfer, signature UnchainedStakingSignature) (bool, error) { + return _UnchainedStaking.Contract.Verify2(&_UnchainedStaking.CallOpts, eip712Transfer, signature) +} + +// Extend is a paid mutator transaction binding the contract method 0x9714378c. +// +// Solidity: function extend(uint256 duration) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) Extend(opts *bind.TransactOpts, duration *big.Int) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "extend", duration) +} + +// Extend is a paid mutator transaction binding the contract method 0x9714378c. +// +// Solidity: function extend(uint256 duration) returns() +func (_UnchainedStaking *UnchainedStakingSession) Extend(duration *big.Int) (*types.Transaction, error) { + return _UnchainedStaking.Contract.Extend(&_UnchainedStaking.TransactOpts, duration) +} + +// Extend is a paid mutator transaction binding the contract method 0x9714378c. +// +// Solidity: function extend(uint256 duration) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) Extend(duration *big.Int) (*types.Transaction, error) { + return _UnchainedStaking.Contract.Extend(&_UnchainedStaking.TransactOpts, duration) +} + +// IncreaseStake is a paid mutator transaction binding the contract method 0x0062ad9d. +// +// Solidity: function increaseStake(uint256 amount, uint256[] nftIds) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) IncreaseStake(opts *bind.TransactOpts, amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "increaseStake", amount, nftIds) +} + +// IncreaseStake is a paid mutator transaction binding the contract method 0x0062ad9d. +// +// Solidity: function increaseStake(uint256 amount, uint256[] nftIds) returns() +func (_UnchainedStaking *UnchainedStakingSession) IncreaseStake(amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { + return _UnchainedStaking.Contract.IncreaseStake(&_UnchainedStaking.TransactOpts, amount, nftIds) +} + +// IncreaseStake is a paid mutator transaction binding the contract method 0x0062ad9d. +// +// Solidity: function increaseStake(uint256 amount, uint256[] nftIds) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) IncreaseStake(amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { + return _UnchainedStaking.Contract.IncreaseStake(&_UnchainedStaking.TransactOpts, amount, nftIds) +} + +// RecoverERC20 is a paid mutator transaction binding the contract method 0x1171bda9. +// +// Solidity: function recoverERC20(address token, address recipient, uint256 amount) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) RecoverERC20(opts *bind.TransactOpts, token common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "recoverERC20", token, recipient, amount) +} + +// RecoverERC20 is a paid mutator transaction binding the contract method 0x1171bda9. +// +// Solidity: function recoverERC20(address token, address recipient, uint256 amount) returns() +func (_UnchainedStaking *UnchainedStakingSession) RecoverERC20(token common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _UnchainedStaking.Contract.RecoverERC20(&_UnchainedStaking.TransactOpts, token, recipient, amount) +} + +// RecoverERC20 is a paid mutator transaction binding the contract method 0x1171bda9. +// +// Solidity: function recoverERC20(address token, address recipient, uint256 amount) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) RecoverERC20(token common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _UnchainedStaking.Contract.RecoverERC20(&_UnchainedStaking.TransactOpts, token, recipient, amount) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_UnchainedStaking *UnchainedStakingTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_UnchainedStaking *UnchainedStakingSession) RenounceOwnership() (*types.Transaction, error) { + return _UnchainedStaking.Contract.RenounceOwnership(&_UnchainedStaking.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _UnchainedStaking.Contract.RenounceOwnership(&_UnchainedStaking.TransactOpts) +} + +// SetBlsAddress is a paid mutator transaction binding the contract method 0x3e5d4675. +// +// Solidity: function setBlsAddress(bytes20 blsAddress) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) SetBlsAddress(opts *bind.TransactOpts, blsAddress [20]byte) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "setBlsAddress", blsAddress) +} + +// SetBlsAddress is a paid mutator transaction binding the contract method 0x3e5d4675. +// +// Solidity: function setBlsAddress(bytes20 blsAddress) returns() +func (_UnchainedStaking *UnchainedStakingSession) SetBlsAddress(blsAddress [20]byte) (*types.Transaction, error) { + return _UnchainedStaking.Contract.SetBlsAddress(&_UnchainedStaking.TransactOpts, blsAddress) +} + +// SetBlsAddress is a paid mutator transaction binding the contract method 0x3e5d4675. +// +// Solidity: function setBlsAddress(bytes20 blsAddress) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) SetBlsAddress(blsAddress [20]byte) (*types.Transaction, error) { + return _UnchainedStaking.Contract.SetBlsAddress(&_UnchainedStaking.TransactOpts, blsAddress) +} + +// SetNftPrices is a paid mutator transaction binding the contract method 0xd43d8d1e. +// +// Solidity: function setNftPrices((address,uint256,uint256,uint256)[] eip712SetNftPrices, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) SetNftPrices(opts *bind.TransactOpts, eip712SetNftPrices []UnchainedStakingEIP712SetNftPrice, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "setNftPrices", eip712SetNftPrices, signatures) +} + +// SetNftPrices is a paid mutator transaction binding the contract method 0xd43d8d1e. +// +// Solidity: function setNftPrices((address,uint256,uint256,uint256)[] eip712SetNftPrices, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingSession) SetNftPrices(eip712SetNftPrices []UnchainedStakingEIP712SetNftPrice, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.Contract.SetNftPrices(&_UnchainedStaking.TransactOpts, eip712SetNftPrices, signatures) +} + +// SetNftPrices is a paid mutator transaction binding the contract method 0xd43d8d1e. +// +// Solidity: function setNftPrices((address,uint256,uint256,uint256)[] eip712SetNftPrices, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) SetNftPrices(eip712SetNftPrices []UnchainedStakingEIP712SetNftPrice, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.Contract.SetNftPrices(&_UnchainedStaking.TransactOpts, eip712SetNftPrices, signatures) +} + +// SetParams is a paid mutator transaction binding the contract method 0x642ca50f. +// +// Solidity: function setParams((address,address,address,address,uint256,uint256,uint256)[] eip712SetParams, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) SetParams(opts *bind.TransactOpts, eip712SetParams []UnchainedStakingEIP712SetParams, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "setParams", eip712SetParams, signatures) +} + +// SetParams is a paid mutator transaction binding the contract method 0x642ca50f. +// +// Solidity: function setParams((address,address,address,address,uint256,uint256,uint256)[] eip712SetParams, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingSession) SetParams(eip712SetParams []UnchainedStakingEIP712SetParams, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.Contract.SetParams(&_UnchainedStaking.TransactOpts, eip712SetParams, signatures) +} + +// SetParams is a paid mutator transaction binding the contract method 0x642ca50f. +// +// Solidity: function setParams((address,address,address,address,uint256,uint256,uint256)[] eip712SetParams, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) SetParams(eip712SetParams []UnchainedStakingEIP712SetParams, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.Contract.SetParams(&_UnchainedStaking.TransactOpts, eip712SetParams, signatures) +} + +// SetSigner is a paid mutator transaction binding the contract method 0xd9d35a4d. +// +// Solidity: function setSigner((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) SetSigner(opts *bind.TransactOpts, eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "setSigner", eip712SetSigner, stakerSignature, signerSignature) +} + +// SetSigner is a paid mutator transaction binding the contract method 0xd9d35a4d. +// +// Solidity: function setSigner((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) returns() +func (_UnchainedStaking *UnchainedStakingSession) SetSigner(eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.Contract.SetSigner(&_UnchainedStaking.TransactOpts, eip712SetSigner, stakerSignature, signerSignature) +} + +// SetSigner is a paid mutator transaction binding the contract method 0xd9d35a4d. +// +// Solidity: function setSigner((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) SetSigner(eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.Contract.SetSigner(&_UnchainedStaking.TransactOpts, eip712SetSigner, stakerSignature, signerSignature) +} + +// Stake is a paid mutator transaction binding the contract method 0x9debdddc. +// +// Solidity: function stake(uint256 duration, uint256 amount, uint256[] nftIds) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) Stake(opts *bind.TransactOpts, duration *big.Int, amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "stake", duration, amount, nftIds) +} + +// Stake is a paid mutator transaction binding the contract method 0x9debdddc. +// +// Solidity: function stake(uint256 duration, uint256 amount, uint256[] nftIds) returns() +func (_UnchainedStaking *UnchainedStakingSession) Stake(duration *big.Int, amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { + return _UnchainedStaking.Contract.Stake(&_UnchainedStaking.TransactOpts, duration, amount, nftIds) +} + +// Stake is a paid mutator transaction binding the contract method 0x9debdddc. +// +// Solidity: function stake(uint256 duration, uint256 amount, uint256[] nftIds) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) Stake(duration *big.Int, amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { + return _UnchainedStaking.Contract.Stake(&_UnchainedStaking.TransactOpts, duration, amount, nftIds) +} + +// Transfer is a paid mutator transaction binding the contract method 0xdc668266. +// +// Solidity: function transfer((address,address,address,uint256,uint256[],uint256[])[] eip712Transferes, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) Transfer(opts *bind.TransactOpts, eip712Transferes []UnchainedStakingEIP712Transfer, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "transfer", eip712Transferes, signatures) +} + +// Transfer is a paid mutator transaction binding the contract method 0xdc668266. +// +// Solidity: function transfer((address,address,address,uint256,uint256[],uint256[])[] eip712Transferes, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingSession) Transfer(eip712Transferes []UnchainedStakingEIP712Transfer, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.Contract.Transfer(&_UnchainedStaking.TransactOpts, eip712Transferes, signatures) +} + +// Transfer is a paid mutator transaction binding the contract method 0xdc668266. +// +// Solidity: function transfer((address,address,address,uint256,uint256[],uint256[])[] eip712Transferes, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) Transfer(eip712Transferes []UnchainedStakingEIP712Transfer, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.Contract.Transfer(&_UnchainedStaking.TransactOpts, eip712Transferes, signatures) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_UnchainedStaking *UnchainedStakingSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _UnchainedStaking.Contract.TransferOwnership(&_UnchainedStaking.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _UnchainedStaking.Contract.TransferOwnership(&_UnchainedStaking.TransactOpts, newOwner) +} + +// Unstake is a paid mutator transaction binding the contract method 0x2def6620. +// +// Solidity: function unstake() returns() +func (_UnchainedStaking *UnchainedStakingTransactor) Unstake(opts *bind.TransactOpts) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "unstake") +} + +// Unstake is a paid mutator transaction binding the contract method 0x2def6620. +// +// Solidity: function unstake() returns() +func (_UnchainedStaking *UnchainedStakingSession) Unstake() (*types.Transaction, error) { + return _UnchainedStaking.Contract.Unstake(&_UnchainedStaking.TransactOpts) +} + +// Unstake is a paid mutator transaction binding the contract method 0x2def6620. +// +// Solidity: function unstake() returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) Unstake() (*types.Transaction, error) { + return _UnchainedStaking.Contract.Unstake(&_UnchainedStaking.TransactOpts) +} + +// UnchainedStakingBlsAddressChangedIterator is returned from FilterBlsAddressChanged and is used to iterate over the raw logs and unpacked data for BlsAddressChanged events raised by the UnchainedStaking contract. +type UnchainedStakingBlsAddressChangedIterator struct { + Event *UnchainedStakingBlsAddressChanged // 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 *UnchainedStakingBlsAddressChangedIterator) 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(UnchainedStakingBlsAddressChanged) + 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(UnchainedStakingBlsAddressChanged) + 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 *UnchainedStakingBlsAddressChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingBlsAddressChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingBlsAddressChanged represents a BlsAddressChanged event raised by the UnchainedStaking contract. +type UnchainedStakingBlsAddressChanged struct { + User common.Address + From [32]byte + To [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBlsAddressChanged is a free log retrieval operation binding the contract event 0xa5c20a3e40dbfce0ccdadcb27e2f561e84ddf0618a41338cc1acb1524780ff39. +// +// Solidity: event BlsAddressChanged(address indexed user, bytes32 indexed from, bytes32 indexed to) +func (_UnchainedStaking *UnchainedStakingFilterer) FilterBlsAddressChanged(opts *bind.FilterOpts, user []common.Address, from [][32]byte, to [][32]byte) (*UnchainedStakingBlsAddressChangedIterator, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "BlsAddressChanged", userRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &UnchainedStakingBlsAddressChangedIterator{contract: _UnchainedStaking.contract, event: "BlsAddressChanged", logs: logs, sub: sub}, nil +} + +// WatchBlsAddressChanged is a free log subscription operation binding the contract event 0xa5c20a3e40dbfce0ccdadcb27e2f561e84ddf0618a41338cc1acb1524780ff39. +// +// Solidity: event BlsAddressChanged(address indexed user, bytes32 indexed from, bytes32 indexed to) +func (_UnchainedStaking *UnchainedStakingFilterer) WatchBlsAddressChanged(opts *bind.WatchOpts, sink chan<- *UnchainedStakingBlsAddressChanged, user []common.Address, from [][32]byte, to [][32]byte) (event.Subscription, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "BlsAddressChanged", userRule, fromRule, toRule) + 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(UnchainedStakingBlsAddressChanged) + if err := _UnchainedStaking.contract.UnpackLog(event, "BlsAddressChanged", 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 +} + +// ParseBlsAddressChanged is a log parse operation binding the contract event 0xa5c20a3e40dbfce0ccdadcb27e2f561e84ddf0618a41338cc1acb1524780ff39. +// +// Solidity: event BlsAddressChanged(address indexed user, bytes32 indexed from, bytes32 indexed to) +func (_UnchainedStaking *UnchainedStakingFilterer) ParseBlsAddressChanged(log types.Log) (*UnchainedStakingBlsAddressChanged, error) { + event := new(UnchainedStakingBlsAddressChanged) + if err := _UnchainedStaking.contract.UnpackLog(event, "BlsAddressChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UnchainedStakingExtendedIterator is returned from FilterExtended and is used to iterate over the raw logs and unpacked data for Extended events raised by the UnchainedStaking contract. +type UnchainedStakingExtendedIterator struct { + Event *UnchainedStakingExtended // 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 *UnchainedStakingExtendedIterator) 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(UnchainedStakingExtended) + 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(UnchainedStakingExtended) + 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 *UnchainedStakingExtendedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingExtendedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingExtended represents a Extended event raised by the UnchainedStaking contract. +type UnchainedStakingExtended struct { + User common.Address + Unlock *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExtended is a free log retrieval operation binding the contract event 0xa29fc12cda82ff659de006abb10fa5ee256d922af1661e395e5f2fb6b004387e. +// +// Solidity: event Extended(address indexed user, uint256 unlock) +func (_UnchainedStaking *UnchainedStakingFilterer) FilterExtended(opts *bind.FilterOpts, user []common.Address) (*UnchainedStakingExtendedIterator, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "Extended", userRule) + if err != nil { + return nil, err + } + return &UnchainedStakingExtendedIterator{contract: _UnchainedStaking.contract, event: "Extended", logs: logs, sub: sub}, nil +} + +// WatchExtended is a free log subscription operation binding the contract event 0xa29fc12cda82ff659de006abb10fa5ee256d922af1661e395e5f2fb6b004387e. +// +// Solidity: event Extended(address indexed user, uint256 unlock) +func (_UnchainedStaking *UnchainedStakingFilterer) WatchExtended(opts *bind.WatchOpts, sink chan<- *UnchainedStakingExtended, user []common.Address) (event.Subscription, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "Extended", userRule) + 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(UnchainedStakingExtended) + if err := _UnchainedStaking.contract.UnpackLog(event, "Extended", 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 +} + +// ParseExtended is a log parse operation binding the contract event 0xa29fc12cda82ff659de006abb10fa5ee256d922af1661e395e5f2fb6b004387e. +// +// Solidity: event Extended(address indexed user, uint256 unlock) +func (_UnchainedStaking *UnchainedStakingFilterer) ParseExtended(log types.Log) (*UnchainedStakingExtended, error) { + event := new(UnchainedStakingExtended) + if err := _UnchainedStaking.contract.UnpackLog(event, "Extended", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UnchainedStakingOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the UnchainedStaking contract. +type UnchainedStakingOwnershipTransferredIterator struct { + Event *UnchainedStakingOwnershipTransferred // 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 *UnchainedStakingOwnershipTransferredIterator) 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(UnchainedStakingOwnershipTransferred) + 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(UnchainedStakingOwnershipTransferred) + 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 *UnchainedStakingOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingOwnershipTransferred represents a OwnershipTransferred event raised by the UnchainedStaking contract. +type UnchainedStakingOwnershipTransferred 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 (_UnchainedStaking *UnchainedStakingFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*UnchainedStakingOwnershipTransferredIterator, 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 := _UnchainedStaking.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &UnchainedStakingOwnershipTransferredIterator{contract: _UnchainedStaking.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 (_UnchainedStaking *UnchainedStakingFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *UnchainedStakingOwnershipTransferred, 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 := _UnchainedStaking.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(UnchainedStakingOwnershipTransferred) + if err := _UnchainedStaking.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 (_UnchainedStaking *UnchainedStakingFilterer) ParseOwnershipTransferred(log types.Log) (*UnchainedStakingOwnershipTransferred, error) { + event := new(UnchainedStakingOwnershipTransferred) + if err := _UnchainedStaking.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UnchainedStakingParamsChangedIterator is returned from FilterParamsChanged and is used to iterate over the raw logs and unpacked data for ParamsChanged events raised by the UnchainedStaking contract. +type UnchainedStakingParamsChangedIterator struct { + Event *UnchainedStakingParamsChanged // 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 *UnchainedStakingParamsChangedIterator) 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(UnchainedStakingParamsChanged) + 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(UnchainedStakingParamsChanged) + 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 *UnchainedStakingParamsChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingParamsChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingParamsChanged represents a ParamsChanged event raised by the UnchainedStaking contract. +type UnchainedStakingParamsChanged struct { + Token common.Address + Nft common.Address + NftTracker common.Address + Threshold *big.Int + Expiration *big.Int + Voted *big.Int + Nonce *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterParamsChanged is a free log retrieval operation binding the contract event 0xcccaeb9d161525e3f31950313467c2e9a945a55a1ff09658479fe753054fafe0. +// +// Solidity: event ParamsChanged(address token, address nft, address nftTracker, uint256 threshold, uint256 expiration, uint256 voted, uint256 nonce) +func (_UnchainedStaking *UnchainedStakingFilterer) FilterParamsChanged(opts *bind.FilterOpts) (*UnchainedStakingParamsChangedIterator, error) { + + logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "ParamsChanged") + if err != nil { + return nil, err + } + return &UnchainedStakingParamsChangedIterator{contract: _UnchainedStaking.contract, event: "ParamsChanged", logs: logs, sub: sub}, nil +} + +// WatchParamsChanged is a free log subscription operation binding the contract event 0xcccaeb9d161525e3f31950313467c2e9a945a55a1ff09658479fe753054fafe0. +// +// Solidity: event ParamsChanged(address token, address nft, address nftTracker, uint256 threshold, uint256 expiration, uint256 voted, uint256 nonce) +func (_UnchainedStaking *UnchainedStakingFilterer) WatchParamsChanged(opts *bind.WatchOpts, sink chan<- *UnchainedStakingParamsChanged) (event.Subscription, error) { + + logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "ParamsChanged") + 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(UnchainedStakingParamsChanged) + if err := _UnchainedStaking.contract.UnpackLog(event, "ParamsChanged", 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 +} + +// ParseParamsChanged is a log parse operation binding the contract event 0xcccaeb9d161525e3f31950313467c2e9a945a55a1ff09658479fe753054fafe0. +// +// Solidity: event ParamsChanged(address token, address nft, address nftTracker, uint256 threshold, uint256 expiration, uint256 voted, uint256 nonce) +func (_UnchainedStaking *UnchainedStakingFilterer) ParseParamsChanged(log types.Log) (*UnchainedStakingParamsChanged, error) { + event := new(UnchainedStakingParamsChanged) + if err := _UnchainedStaking.contract.UnpackLog(event, "ParamsChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UnchainedStakingSignerChangedIterator is returned from FilterSignerChanged and is used to iterate over the raw logs and unpacked data for SignerChanged events raised by the UnchainedStaking contract. +type UnchainedStakingSignerChangedIterator struct { + Event *UnchainedStakingSignerChanged // 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 *UnchainedStakingSignerChangedIterator) 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(UnchainedStakingSignerChanged) + 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(UnchainedStakingSignerChanged) + 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 *UnchainedStakingSignerChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingSignerChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingSignerChanged represents a SignerChanged event raised by the UnchainedStaking contract. +type UnchainedStakingSignerChanged struct { + Staker common.Address + Signer common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSignerChanged is a free log retrieval operation binding the contract event 0xeeb293e1f8f3a9db91ade748726387ed1352ca78f5430c5f06fe3d1e1ad50579. +// +// Solidity: event SignerChanged(address indexed staker, address indexed signer) +func (_UnchainedStaking *UnchainedStakingFilterer) FilterSignerChanged(opts *bind.FilterOpts, staker []common.Address, signer []common.Address) (*UnchainedStakingSignerChangedIterator, error) { + + var stakerRule []interface{} + for _, stakerItem := range staker { + stakerRule = append(stakerRule, stakerItem) + } + var signerRule []interface{} + for _, signerItem := range signer { + signerRule = append(signerRule, signerItem) + } + + logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "SignerChanged", stakerRule, signerRule) + if err != nil { + return nil, err + } + return &UnchainedStakingSignerChangedIterator{contract: _UnchainedStaking.contract, event: "SignerChanged", logs: logs, sub: sub}, nil +} + +// WatchSignerChanged is a free log subscription operation binding the contract event 0xeeb293e1f8f3a9db91ade748726387ed1352ca78f5430c5f06fe3d1e1ad50579. +// +// Solidity: event SignerChanged(address indexed staker, address indexed signer) +func (_UnchainedStaking *UnchainedStakingFilterer) WatchSignerChanged(opts *bind.WatchOpts, sink chan<- *UnchainedStakingSignerChanged, staker []common.Address, signer []common.Address) (event.Subscription, error) { + + var stakerRule []interface{} + for _, stakerItem := range staker { + stakerRule = append(stakerRule, stakerItem) + } + var signerRule []interface{} + for _, signerItem := range signer { + signerRule = append(signerRule, signerItem) + } + + logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "SignerChanged", stakerRule, signerRule) + 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(UnchainedStakingSignerChanged) + if err := _UnchainedStaking.contract.UnpackLog(event, "SignerChanged", 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 +} + +// ParseSignerChanged is a log parse operation binding the contract event 0xeeb293e1f8f3a9db91ade748726387ed1352ca78f5430c5f06fe3d1e1ad50579. +// +// Solidity: event SignerChanged(address indexed staker, address indexed signer) +func (_UnchainedStaking *UnchainedStakingFilterer) ParseSignerChanged(log types.Log) (*UnchainedStakingSignerChanged, error) { + event := new(UnchainedStakingSignerChanged) + if err := _UnchainedStaking.contract.UnpackLog(event, "SignerChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UnchainedStakingStakeIncreasedIterator is returned from FilterStakeIncreased and is used to iterate over the raw logs and unpacked data for StakeIncreased events raised by the UnchainedStaking contract. +type UnchainedStakingStakeIncreasedIterator struct { + Event *UnchainedStakingStakeIncreased // 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 *UnchainedStakingStakeIncreasedIterator) 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(UnchainedStakingStakeIncreased) + 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(UnchainedStakingStakeIncreased) + 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 *UnchainedStakingStakeIncreasedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingStakeIncreasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingStakeIncreased represents a StakeIncreased event raised by the UnchainedStaking contract. +type UnchainedStakingStakeIncreased struct { + User common.Address + Amount *big.Int + NftIds []*big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterStakeIncreased is a free log retrieval operation binding the contract event 0x26e4d06799c60ba22ec168ee4a9314ed451cf9c78dbf6a5f7bfeaf3c84688f58. +// +// Solidity: event StakeIncreased(address indexed user, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) FilterStakeIncreased(opts *bind.FilterOpts, user []common.Address) (*UnchainedStakingStakeIncreasedIterator, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "StakeIncreased", userRule) + if err != nil { + return nil, err + } + return &UnchainedStakingStakeIncreasedIterator{contract: _UnchainedStaking.contract, event: "StakeIncreased", logs: logs, sub: sub}, nil +} + +// WatchStakeIncreased is a free log subscription operation binding the contract event 0x26e4d06799c60ba22ec168ee4a9314ed451cf9c78dbf6a5f7bfeaf3c84688f58. +// +// Solidity: event StakeIncreased(address indexed user, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) WatchStakeIncreased(opts *bind.WatchOpts, sink chan<- *UnchainedStakingStakeIncreased, user []common.Address) (event.Subscription, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "StakeIncreased", userRule) + 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(UnchainedStakingStakeIncreased) + if err := _UnchainedStaking.contract.UnpackLog(event, "StakeIncreased", 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 +} + +// ParseStakeIncreased is a log parse operation binding the contract event 0x26e4d06799c60ba22ec168ee4a9314ed451cf9c78dbf6a5f7bfeaf3c84688f58. +// +// Solidity: event StakeIncreased(address indexed user, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) ParseStakeIncreased(log types.Log) (*UnchainedStakingStakeIncreased, error) { + event := new(UnchainedStakingStakeIncreased) + if err := _UnchainedStaking.contract.UnpackLog(event, "StakeIncreased", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UnchainedStakingStakedIterator is returned from FilterStaked and is used to iterate over the raw logs and unpacked data for Staked events raised by the UnchainedStaking contract. +type UnchainedStakingStakedIterator struct { + Event *UnchainedStakingStaked // 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 *UnchainedStakingStakedIterator) 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(UnchainedStakingStaked) + 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(UnchainedStakingStaked) + 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 *UnchainedStakingStakedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingStakedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingStaked represents a Staked event raised by the UnchainedStaking contract. +type UnchainedStakingStaked struct { + User common.Address + Unlock *big.Int + Amount *big.Int + NftIds []*big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterStaked is a free log retrieval operation binding the contract event 0x5df5de9ccb680fe3d60088f6d4c3b6d535074c704699377046c743a5b276e171. +// +// Solidity: event Staked(address indexed user, uint256 unlock, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) FilterStaked(opts *bind.FilterOpts, user []common.Address) (*UnchainedStakingStakedIterator, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "Staked", userRule) + if err != nil { + return nil, err + } + return &UnchainedStakingStakedIterator{contract: _UnchainedStaking.contract, event: "Staked", logs: logs, sub: sub}, nil +} + +// WatchStaked is a free log subscription operation binding the contract event 0x5df5de9ccb680fe3d60088f6d4c3b6d535074c704699377046c743a5b276e171. +// +// Solidity: event Staked(address indexed user, uint256 unlock, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) WatchStaked(opts *bind.WatchOpts, sink chan<- *UnchainedStakingStaked, user []common.Address) (event.Subscription, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "Staked", userRule) + 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(UnchainedStakingStaked) + if err := _UnchainedStaking.contract.UnpackLog(event, "Staked", 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 +} + +// ParseStaked is a log parse operation binding the contract event 0x5df5de9ccb680fe3d60088f6d4c3b6d535074c704699377046c743a5b276e171. +// +// Solidity: event Staked(address indexed user, uint256 unlock, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) ParseStaked(log types.Log) (*UnchainedStakingStaked, error) { + event := new(UnchainedStakingStaked) + if err := _UnchainedStaking.contract.UnpackLog(event, "Staked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UnchainedStakingTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the UnchainedStaking contract. +type UnchainedStakingTransferIterator struct { + Event *UnchainedStakingTransfer // 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 *UnchainedStakingTransferIterator) 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(UnchainedStakingTransfer) + 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(UnchainedStakingTransfer) + 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 *UnchainedStakingTransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingTransfer represents a Transfer event raised by the UnchainedStaking contract. +type UnchainedStakingTransfer struct { + From common.Address + To common.Address + Amount *big.Int + NftIds []*big.Int + Nonces []*big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0x26a79d74e745222aa0f380aabeac7f0a270b037daf3b5fb1b1b66ff7f4c3144f. +// +// Solidity: event Transfer(address from, address to, uint256 amount, uint256[] nftIds, uint256[] nonces) +func (_UnchainedStaking *UnchainedStakingFilterer) FilterTransfer(opts *bind.FilterOpts) (*UnchainedStakingTransferIterator, error) { + + logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "Transfer") + if err != nil { + return nil, err + } + return &UnchainedStakingTransferIterator{contract: _UnchainedStaking.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0x26a79d74e745222aa0f380aabeac7f0a270b037daf3b5fb1b1b66ff7f4c3144f. +// +// Solidity: event Transfer(address from, address to, uint256 amount, uint256[] nftIds, uint256[] nonces) +func (_UnchainedStaking *UnchainedStakingFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *UnchainedStakingTransfer) (event.Subscription, error) { + + logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "Transfer") + 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(UnchainedStakingTransfer) + if err := _UnchainedStaking.contract.UnpackLog(event, "Transfer", 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 +} + +// ParseTransfer is a log parse operation binding the contract event 0x26a79d74e745222aa0f380aabeac7f0a270b037daf3b5fb1b1b66ff7f4c3144f. +// +// Solidity: event Transfer(address from, address to, uint256 amount, uint256[] nftIds, uint256[] nonces) +func (_UnchainedStaking *UnchainedStakingFilterer) ParseTransfer(log types.Log) (*UnchainedStakingTransfer, error) { + event := new(UnchainedStakingTransfer) + if err := _UnchainedStaking.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UnchainedStakingUnStakedIterator is returned from FilterUnStaked and is used to iterate over the raw logs and unpacked data for UnStaked events raised by the UnchainedStaking contract. +type UnchainedStakingUnStakedIterator struct { + Event *UnchainedStakingUnStaked // 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 *UnchainedStakingUnStakedIterator) 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(UnchainedStakingUnStaked) + 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(UnchainedStakingUnStaked) + 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 *UnchainedStakingUnStakedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingUnStakedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingUnStaked represents a UnStaked event raised by the UnchainedStaking contract. +type UnchainedStakingUnStaked struct { + User common.Address + Amount *big.Int + NftIds []*big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnStaked is a free log retrieval operation binding the contract event 0xef4ce4a0205d268e0effbc76aaabb2ad2509ec58a2e9013645347d3c3cd9be42. +// +// Solidity: event UnStaked(address indexed user, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) FilterUnStaked(opts *bind.FilterOpts, user []common.Address) (*UnchainedStakingUnStakedIterator, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "UnStaked", userRule) + if err != nil { + return nil, err + } + return &UnchainedStakingUnStakedIterator{contract: _UnchainedStaking.contract, event: "UnStaked", logs: logs, sub: sub}, nil +} + +// WatchUnStaked is a free log subscription operation binding the contract event 0xef4ce4a0205d268e0effbc76aaabb2ad2509ec58a2e9013645347d3c3cd9be42. +// +// Solidity: event UnStaked(address indexed user, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) WatchUnStaked(opts *bind.WatchOpts, sink chan<- *UnchainedStakingUnStaked, user []common.Address) (event.Subscription, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "UnStaked", userRule) + 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(UnchainedStakingUnStaked) + if err := _UnchainedStaking.contract.UnpackLog(event, "UnStaked", 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 +} + +// ParseUnStaked is a log parse operation binding the contract event 0xef4ce4a0205d268e0effbc76aaabb2ad2509ec58a2e9013645347d3c3cd9be42. +// +// Solidity: event UnStaked(address indexed user, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) ParseUnStaked(log types.Log) (*UnchainedStakingUnStaked, error) { + event := new(UnchainedStakingUnStaked) + if err := _UnchainedStaking.contract.UnpackLog(event, "UnStaked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/internal/crypto/ethereum/contracts/UniV3.go b/internal/crypto/ethereum/contracts/UniV3.go new file mode 100644 index 00000000..087ab06e --- /dev/null +++ b/internal/crypto/ethereum/contracts/UniV3.go @@ -0,0 +1,251 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contracts + +import ( + "errors" + "math/big" + "strings" + + 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" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// UniV3MetaData contains all meta data concerning the UniV3 contract. +var UniV3MetaData = &bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"slot0\",\"constant\":true,\"stateMutability\":\"view\",\"payable\":false,\"inputs\":[],\"outputs\":[{\"type\":\"uint160\",\"name\":\"sqrtPriceX96\"},{\"type\":\"int24\",\"name\":\"tick\"},{\"type\":\"uint16\",\"name\":\"observationIndex\"},{\"type\":\"uint16\",\"name\":\"observationCardinality\"},{\"type\":\"uint16\",\"name\":\"observationCardinalityNext\"},{\"type\":\"uint8\",\"name\":\"feeProtocol\"},{\"type\":\"bool\",\"name\":\"unlocked\"}]}]", +} + +// UniV3ABI is the input ABI used to generate the binding from. +// Deprecated: Use UniV3MetaData.ABI instead. +var UniV3ABI = UniV3MetaData.ABI + +// UniV3 is an auto generated Go binding around an Ethereum contract. +type UniV3 struct { + UniV3Caller // Read-only binding to the contract + UniV3Transactor // Write-only binding to the contract + UniV3Filterer // Log filterer for contract events +} + +// UniV3Caller is an auto generated read-only Go binding around an Ethereum contract. +type UniV3Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UniV3Transactor is an auto generated write-only Go binding around an Ethereum contract. +type UniV3Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UniV3Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type UniV3Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UniV3Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type UniV3Session struct { + Contract *UniV3 // 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 +} + +// UniV3CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type UniV3CallerSession struct { + Contract *UniV3Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// UniV3TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type UniV3TransactorSession struct { + Contract *UniV3Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// UniV3Raw is an auto generated low-level Go binding around an Ethereum contract. +type UniV3Raw struct { + Contract *UniV3 // Generic contract binding to access the raw methods on +} + +// UniV3CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type UniV3CallerRaw struct { + Contract *UniV3Caller // Generic read-only contract binding to access the raw methods on +} + +// UniV3TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type UniV3TransactorRaw struct { + Contract *UniV3Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewUniV3 creates a new instance of UniV3, bound to a specific deployed contract. +func NewUniV3(address common.Address, backend bind.ContractBackend) (*UniV3, error) { + contract, err := bindUniV3(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &UniV3{UniV3Caller: UniV3Caller{contract: contract}, UniV3Transactor: UniV3Transactor{contract: contract}, UniV3Filterer: UniV3Filterer{contract: contract}}, nil +} + +// NewUniV3Caller creates a new read-only instance of UniV3, bound to a specific deployed contract. +func NewUniV3Caller(address common.Address, caller bind.ContractCaller) (*UniV3Caller, error) { + contract, err := bindUniV3(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &UniV3Caller{contract: contract}, nil +} + +// NewUniV3Transactor creates a new write-only instance of UniV3, bound to a specific deployed contract. +func NewUniV3Transactor(address common.Address, transactor bind.ContractTransactor) (*UniV3Transactor, error) { + contract, err := bindUniV3(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &UniV3Transactor{contract: contract}, nil +} + +// NewUniV3Filterer creates a new log filterer instance of UniV3, bound to a specific deployed contract. +func NewUniV3Filterer(address common.Address, filterer bind.ContractFilterer) (*UniV3Filterer, error) { + contract, err := bindUniV3(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &UniV3Filterer{contract: contract}, nil +} + +// bindUniV3 binds a generic wrapper to an already deployed contract. +func bindUniV3(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := UniV3MetaData.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 (_UniV3 *UniV3Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _UniV3.Contract.UniV3Caller.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 (_UniV3 *UniV3Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _UniV3.Contract.UniV3Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_UniV3 *UniV3Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _UniV3.Contract.UniV3Transactor.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 (_UniV3 *UniV3CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _UniV3.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 (_UniV3 *UniV3TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _UniV3.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_UniV3 *UniV3TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _UniV3.Contract.contract.Transact(opts, method, params...) +} + +// Slot0 is a free data retrieval call binding the contract method 0x3850c7bd. +// +// Solidity: function slot0() view returns(uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked) +func (_UniV3 *UniV3Caller) Slot0(opts *bind.CallOpts) (struct { + SqrtPriceX96 *big.Int + Tick *big.Int + ObservationIndex uint16 + ObservationCardinality uint16 + ObservationCardinalityNext uint16 + FeeProtocol uint8 + Unlocked bool +}, error) { + var out []interface{} + err := _UniV3.contract.Call(opts, &out, "slot0") + + outstruct := new(struct { + SqrtPriceX96 *big.Int + Tick *big.Int + ObservationIndex uint16 + ObservationCardinality uint16 + ObservationCardinalityNext uint16 + FeeProtocol uint8 + Unlocked bool + }) + if err != nil { + return *outstruct, err + } + + outstruct.SqrtPriceX96 = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Tick = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.ObservationIndex = *abi.ConvertType(out[2], new(uint16)).(*uint16) + outstruct.ObservationCardinality = *abi.ConvertType(out[3], new(uint16)).(*uint16) + outstruct.ObservationCardinalityNext = *abi.ConvertType(out[4], new(uint16)).(*uint16) + outstruct.FeeProtocol = *abi.ConvertType(out[5], new(uint8)).(*uint8) + outstruct.Unlocked = *abi.ConvertType(out[6], new(bool)).(*bool) + + return *outstruct, err + +} + +// Slot0 is a free data retrieval call binding the contract method 0x3850c7bd. +// +// Solidity: function slot0() view returns(uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked) +func (_UniV3 *UniV3Session) Slot0() (struct { + SqrtPriceX96 *big.Int + Tick *big.Int + ObservationIndex uint16 + ObservationCardinality uint16 + ObservationCardinalityNext uint16 + FeeProtocol uint8 + Unlocked bool +}, error) { + return _UniV3.Contract.Slot0(&_UniV3.CallOpts) +} + +// Slot0 is a free data retrieval call binding the contract method 0x3850c7bd. +// +// Solidity: function slot0() view returns(uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked) +func (_UniV3 *UniV3CallerSession) Slot0() (struct { + SqrtPriceX96 *big.Int + Tick *big.Int + ObservationIndex uint16 + ObservationCardinality uint16 + ObservationCardinalityNext uint16 + FeeProtocol uint8 + Unlocked bool +}, error) { + return _UniV3.Contract.Slot0(&_UniV3.CallOpts) +} diff --git a/internal/crypto/ethereum/identity.go b/internal/crypto/ethereum/identity.go new file mode 100644 index 00000000..84a9c56a --- /dev/null +++ b/internal/crypto/ethereum/identity.go @@ -0,0 +1,89 @@ +package ethereum + +import ( + "crypto/ecdsa" + + "github.com/TimeleapLabs/unchained/internal/config" + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" +) + +// Signer represents an Ethereum identity. +type Signer struct { + PublicKey *ecdsa.PublicKey + PrivateKey *ecdsa.PrivateKey + Address string +} + +func (s *Signer) Verify(_ []byte, _ []byte, _ []byte) (bool, error) { + // TODO implement me + panic("implement me") +} + +// WriteConfigs writes the secret key, public key and address to the global config object. +func (s *Signer) WriteConfigs() { + privateKeyBytes := crypto.FromECDSA(s.PrivateKey) + config.App.Secret.EvmPrivateKey = hexutil.Encode(privateKeyBytes)[2:] + config.App.Secret.EvmAddress = s.Address +} + +func (s *Signer) Sign(data []byte) ([]byte, error) { + signature, err := crypto.Sign(data, s.PrivateKey) + if err != nil { + return nil, err + } + + if signature[64] < 27 { + signature[64] += 27 + } + + return signature, nil +} + +// NewIdentity creates a new Ethereum identity. +func NewIdentity() *Signer { + var privateKey *ecdsa.PrivateKey + var err error + + if config.App.Secret.EvmPrivateKey == "" && !config.App.System.AllowGenerateSecrets { + panic("EVM private key is not provided and secrets generation is not allowed") + } + + if config.App.Secret.EvmPrivateKey != "" { + privateKey, err = crypto.HexToECDSA(config.App.Secret.EvmPrivateKey) + if err != nil { + utils.Logger. + With("Error", err). + Error("Can't decode EVM private key") + + panic(err) + } + } else { + privateKey, err = crypto.GenerateKey() + if err != nil { + utils.Logger. + With("Error", err). + Error("Can't generate EVM private key") + + panic(err) + } + } + + publicKeyECDSA, ok := privateKey.Public().(*ecdsa.PublicKey) + if !ok { + panic("Can't assert type: publicKey is not of type *ecdsa.PublicKey") + } + + s := &Signer{ + PublicKey: publicKeyECDSA, + PrivateKey: privateKey, + Address: crypto.PubkeyToAddress(*publicKeyECDSA).Hex(), + } + + utils.Logger. + With("Address", s.Address). + Info("EVM identity initialized") + + return s +} diff --git a/internal/crypto/ethereum/rpc.go b/internal/crypto/ethereum/rpc.go new file mode 100644 index 00000000..a3bdf516 --- /dev/null +++ b/internal/crypto/ethereum/rpc.go @@ -0,0 +1,112 @@ +package ethereum + +import ( + "context" + "sync" + + "github.com/TimeleapLabs/unchained/internal/consts" + "github.com/TimeleapLabs/unchained/internal/utils" + + "github.com/TimeleapLabs/unchained/internal/crypto/ethereum/contracts" + + "github.com/TimeleapLabs/unchained/internal/config" + + "github.com/ethereum/go-ethereum/common" + + "github.com/ethereum/go-ethereum/ethclient" +) + +type RPC interface { + RefreshRPC(network string) + GetClient(network string) *ethclient.Client + GetNewStakingContract(network string, address string, refresh bool) (*contracts.UnchainedStaking, error) + GetNewUniV3Contract(network string, address string, refresh bool) (*contracts.UniV3, error) + GetBlockNumber(ctx context.Context, network string) (uint64, error) +} + +type repository struct { + list map[string][]string + index map[string]int + clients map[string]*ethclient.Client + mutex *sync.Mutex +} + +func (r *repository) GetClient(chain string) *ethclient.Client { + return r.clients[chain] +} + +func (r *repository) refreshRPCWithRetries(network string, retries int) bool { + if retries == 0 { + panic("Cannot connect to any of the provided RPCs") + } + + if r.index[network] == len(r.list[network])-1 { + r.index[network] = 0 + } else { + r.index[network]++ + } + + var err error + + index := r.index[network] + r.clients[network], err = ethclient.Dial(r.list[network][index]) + + if err != nil { + return r.refreshRPCWithRetries(network, retries-1) + } + + return true +} + +func (r *repository) RefreshRPC(network string) { + r.mutex.Lock() + defer r.mutex.Unlock() + + utils.Logger.With("Network", network).Info("Connecting to RPC") + r.refreshRPCWithRetries(network, len(r.list)) +} + +func (r *repository) GetNewStakingContract(network string, address string, refresh bool) (*contracts.UnchainedStaking, error) { + if refresh { + r.RefreshRPC(network) + } + + return contracts.NewUnchainedStaking(common.HexToAddress(address), r.clients[network]) +} + +func (r *repository) GetNewUniV3Contract(network string, address string, refresh bool) (*contracts.UniV3, error) { + if refresh { + r.RefreshRPC(network) + } + + return contracts.NewUniV3(common.HexToAddress(address), r.clients[network]) +} + +// GetBlockNumber returns the most recent block number. +func (r *repository) GetBlockNumber(ctx context.Context, network string) (uint64, error) { + client, ok := r.clients[network] + + if !ok { + utils.Logger.With("Network", network).Error("Client not found") + return 0, consts.ErrClientNotFound + } + + return client.BlockNumber(ctx) +} + +func New() RPC { + r := &repository{ + list: map[string][]string{}, + index: map[string]int{}, + clients: map[string]*ethclient.Client{}, + mutex: new(sync.Mutex), + } + + for _, rpc := range config.App.RPC { + r.index[rpc.Name] = 0 + r.list[rpc.Name] = append(r.list[rpc.Name], rpc.Nodes...) + r.RefreshRPC(rpc.Name) + } + + return r +} diff --git a/internal/crypto/ethereum/rpc_mock.go b/internal/crypto/ethereum/rpc_mock.go new file mode 100644 index 00000000..36df1b39 --- /dev/null +++ b/internal/crypto/ethereum/rpc_mock.go @@ -0,0 +1,51 @@ +package ethereum + +import ( + "context" + + "github.com/TimeleapLabs/unchained/internal/crypto/ethereum/contracts" + + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/ethclient" +) + +type mockRPC struct { + backend *backends.SimulatedBackend +} + +func (m mockRPC) GetClient(_ string) *ethclient.Client { + // TODO implement me + panic("implement me") +} + +func (m mockRPC) RefreshRPC(_ string) {} + +func (m mockRPC) GetNewStakingContract(_ string, address string, _ bool) (*contracts.UnchainedStaking, error) { + return contracts.NewUnchainedStaking( + common.HexToAddress(address), + m.backend, + ) +} + +func (m mockRPC) GetNewUniV3Contract(_ string, address string, _ bool) (*contracts.UniV3, error) { + return contracts.NewUniV3( + common.HexToAddress(address), + m.backend, + ) +} + +func (m mockRPC) GetBlockNumber(_ context.Context, _ string) (uint64, error) { + var blockNumber uint64 = 1000 + return blockNumber, nil +} + +func NewMock() RPC { + return &mockRPC{ + backend: backends.NewSimulatedBackend( + core.DefaultGenesisBlock().Alloc, + 9000000, + ), + } +} diff --git a/internal/crypto/frost/identity.go b/internal/crypto/frost/identity.go new file mode 100644 index 00000000..df8367e4 --- /dev/null +++ b/internal/crypto/frost/identity.go @@ -0,0 +1,95 @@ +package frost + +import ( + "errors" + "github.com/bytemare/crypto" + "github.com/bytemare/frost" + "github.com/bytemare/frost/dkg" +) + +// DistributedSigner represents a Frost identity. +type DistributedSigner struct { + ID *crypto.Scalar + currentParticipant *dkg.Participant + finalParticipant *frost.Participant + accumulatedMessages []*dkg.Round1Data + ackMessages []*dkg.Round2Data + config *frost.Configuration + signerCount int + minSigningCount int +} + +// Update function will update the identity key about other parties. +func (s *DistributedSigner) Update(msg *dkg.Round1Data) ([]*dkg.Round2Data, error) { + s.accumulatedMessages = append(s.accumulatedMessages, msg) + + if len(s.accumulatedMessages) != s.signerCount { + return nil, nil + } + + round2Data, err := s.currentParticipant.Continue(s.accumulatedMessages) + if err != nil { + return nil, err + } + + if len(round2Data) != len(s.accumulatedMessages)-1 { + return nil, errors.New("number of accept messages is not correct") + } + + return round2Data, nil +} + +func (s *DistributedSigner) Finalize(msg *dkg.Round2Data) error { + if msg.ReceiverIdentifier.Equal(s.currentParticipant.Identifier) == 0 { + return nil + } + + s.ackMessages = append(s.ackMessages, msg) + + if len(s.ackMessages) < len(s.accumulatedMessages)-1 { + return nil + } + + // This will, for each participant, return their secret key (which is a share of the global secret signing key), + // the corresponding verification key, and the global public key. + participantsSecretKey, _, groupPublicKeyGeneratedInDKG, err := s.currentParticipant.Finalize( + s.accumulatedMessages, + s.ackMessages, + ) + if err != nil { + return err + } + + s.config.GroupPublicKey = groupPublicKeyGeneratedInDKG + + s.finalParticipant = s.config.Participant(s.ID, participantsSecretKey) + + return nil +} + +// NewIdentity creates a new Frost identity. +func NewIdentity(ID int, signerCount int, minSigningCount int) (*dkg.Round1Data, *DistributedSigner) { + signer := DistributedSigner{ + accumulatedMessages: make([]*dkg.Round1Data, 0, signerCount), + config: frost.Ristretto255.Configuration(), + signerCount: signerCount, + minSigningCount: minSigningCount, + } + + signer.ID = signer.config.IDFromInt(ID) + signer.currentParticipant = dkg.NewParticipant( + signer.config.Ciphersuite, + signer.ID, + signerCount, + minSigningCount, + ) + + round1Data := signer.currentParticipant.Init() + if round1Data.SenderIdentifier.Equal(signer.ID) != 1 { + panic("this is just a test, and it failed") + } + + //signer.accumulatedMessages = append(signer.accumulatedMessages, round1Data) + + return round1Data, &signer +} diff --git a/internal/crypto/frost/identity_test.go b/internal/crypto/frost/identity_test.go new file mode 100644 index 00000000..f2108938 --- /dev/null +++ b/internal/crypto/frost/identity_test.go @@ -0,0 +1,83 @@ +package frost + +import ( + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/bytemare/frost" + "github.com/bytemare/frost/dkg" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + "math/rand" + "testing" +) + +const ( + numOfSigners = 4 + minNumOfSigners = 2 +) + +var ( + testData = []byte("HELLO hello") + + signers = []int{} +) + +type FrostIdentityTestSuite struct { + suite.Suite + parties []*DistributedSigner +} + +func (s *FrostIdentityTestSuite) SetupTest() { + utils.SetupLogger("info") + + for i := 0; i < numOfSigners; i++ { + signers = append(signers, rand.Intn(9999)) + } + + r1Messages := []*dkg.Round1Data{} + for i := 0; i < numOfSigners; i++ { + r1Msg, party := NewIdentity(signers[i], numOfSigners, minNumOfSigners) + s.parties = append(s.parties, party) + r1Messages = append(r1Messages, r1Msg) + } + + r2Messages := []*dkg.Round2Data{} + for i := 0; i < numOfSigners; i++ { + for j := 0; j < numOfSigners; j++ { + r2Msgs, err := s.parties[i].Update(r1Messages[j]) + assert.NoError(s.T(), err) + + r2Messages = append(r2Messages, r2Msgs...) + } + } + + for k := 0; k < numOfSigners; k++ { + for _, msg := range r2Messages { + err := s.parties[k].Finalize(msg) + assert.NoError(s.T(), err) + } + } +} + +func (s *FrostIdentityTestSuite) TestSign() { + signers := make([]*MessageSigner, 0, minNumOfSigners) + commits := make([]*frost.Commitment, 0, minNumOfSigners) + + for i := 0; i < minNumOfSigners; i++ { + signer, msg, err := s.parties[i].NewSigner(testData) + assert.NoError(s.T(), err) + + commits = append(commits, msg) + signers = append(signers, signer) + } + + for i := 0; i < minNumOfSigners; i++ { + for j := 0; j < minNumOfSigners; j++ { + err := signers[i].Confirm(commits[j]) + assert.NoError(s.T(), err) + } + } +} + +func TestFrostIdentitySuite(t *testing.T) { + suite.Run(t, new(FrostIdentityTestSuite)) +} diff --git a/internal/crypto/frost/signer.go b/internal/crypto/frost/signer.go new file mode 100644 index 00000000..9e33b540 --- /dev/null +++ b/internal/crypto/frost/signer.go @@ -0,0 +1,62 @@ +package frost + +import ( + "errors" + "github.com/TimeleapLabs/unchained/internal/consts" + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/bytemare/frost" +) + +// MessageSigner represents state of signing of a message. +type MessageSigner struct { + partySize int + data []byte + commitments frost.CommitmentList + participant *frost.Participant +} + +func (s *MessageSigner) Confirm(commitment *frost.Commitment) error { + s.commitments = append(s.commitments, commitment) + + if len(s.commitments.Participants()) < s.partySize { + return nil + } + + signatureShare, err := s.participant.Sign(s.data, s.commitments) + if err != nil { + utils.Logger.With("err", err).Error("cant sign message") + return consts.ErrCantSign + } + + if !s.participant.VerifySignatureShare( + commitment, + s.participant.GroupPublicKey, + signatureShare.SignatureShare, + s.commitments, + s.data, + ) { + return consts.ErrCantVerify + } + + return nil +} + +func (s *DistributedSigner) NewSigner(data []byte) (*MessageSigner, *frost.Commitment, error) { + if s.finalParticipant == nil { + return nil, nil, consts.ErrSignerIsNotReady + } + + signer := &MessageSigner{ + partySize: s.signerCount, + data: data, + commitments: make(frost.CommitmentList, 0, s.signerCount), + participant: s.finalParticipant, + } + + commitment := s.finalParticipant.Commit() + if commitment.Identifier.Equal(s.finalParticipant.KeyShare.Identifier) != 1 { + return nil, nil, errors.New("identifier is not correct") + } + + return signer, commitment, nil +} diff --git a/internal/crypto/identity.go b/internal/crypto/identity.go new file mode 100644 index 00000000..971a853c --- /dev/null +++ b/internal/crypto/identity.go @@ -0,0 +1,96 @@ +package crypto + +import ( + "encoding/hex" + + "github.com/TimeleapLabs/unchained/internal/config" + "github.com/TimeleapLabs/unchained/internal/crypto/bls" + "github.com/TimeleapLabs/unchained/internal/crypto/ethereum" + "github.com/TimeleapLabs/unchained/internal/crypto/tss" + "github.com/TimeleapLabs/unchained/internal/model" +) + +// Signer represents a Signing method. +type Signer interface { + Sign(data []byte) ([]byte, error) + Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) + WriteConfigs() +} + +// MachineIdentity holds machine identity and provide and manage keys. +type MachineIdentity struct { + Bls Signer + Eth Signer + Tss *tss.DistributedSigner +} + +// Identity is a global variable that holds machine identity. +var Identity = &MachineIdentity{} + +// Option represents a function that can add new identity to machine identity. +type Option func(identity *MachineIdentity) error + +// InitMachineIdentity loads all provided identities and save them to secret file. +func InitMachineIdentity(options ...Option) { + for _, option := range options { + err := option(Identity) + if err != nil { + panic(err) + } + } + + if config.App.System.AllowGenerateSecrets { + err := config.App.Secret.Save() + if err != nil { + panic(err) + } + } +} + +// ExportEvmSigner returns EVM signer from machine identity. +func (i *MachineIdentity) ExportEvmSigner() *model.Signer { + blsPublicKey, err := hex.DecodeString(config.App.Secret.PublicKey) + if err != nil { + panic(err) + } + + return &model.Signer{ + Name: config.App.System.Name, + EvmAddress: config.App.Secret.EvmAddress, + PublicKey: [96]byte(blsPublicKey), + ShortPublicKey: config.App.Secret.ShortPublicKey, + } +} + +// WithEvmSigner initialize and will add Evm identity to machine identity. +func WithEvmSigner() func(machineIdentity *MachineIdentity) error { + return func(machineIdentity *MachineIdentity) error { + machineIdentity.Eth = ethereum.NewIdentity() + machineIdentity.Eth.WriteConfigs() + + return nil + } +} + +// WithTssSigner initialize and will add Tss identity to machine identity. +// func WithTssSigner(signers []string, minThreshold int) func(machineIdentity *MachineIdentity) error { +// return func(machineIdentity *MachineIdentity) error { +// machineIdentity.Tss = tss.NewIdentity( +// signers, +// minThreshold, +// ) +// //machineIdentity.Tss.WriteConfigs() +// +// return nil +// } +//} + +// WithBlsIdentity initialize and will add Bls identity to machine identity. +func WithBlsIdentity() func(machineIdentity *MachineIdentity) error { + return func(machineIdentity *MachineIdentity) error { + machineIdentity.Bls = bls.NewIdentity() + machineIdentity.Bls.WriteConfigs() + + return nil + } +} diff --git a/internal/crypto/identity_test.go b/internal/crypto/identity_test.go new file mode 100644 index 00000000..b0fa65b6 --- /dev/null +++ b/internal/crypto/identity_test.go @@ -0,0 +1,32 @@ +package crypto + +import ( + "testing" + + "github.com/TimeleapLabs/unchained/internal/config" + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/stretchr/testify/assert" +) + +const SamplePrivateKey = "3b885a8a8f043724abfa865eccd38f536887d9ea1c08a742720e810f38a86872" + +func TestEvmSignerWithoutGeneratePrivateKey(t *testing.T) { + utils.SetupLogger("info") + config.App.Secret.EvmPrivateKey = SamplePrivateKey + + InitMachineIdentity( + WithEvmSigner(), + ) + + assert.Equal(t, config.App.Secret.EvmPrivateKey, SamplePrivateKey) +} + +func TestEvmSignerWithGeneratePrivateKey(t *testing.T) { + utils.SetupLogger("info") + config.App.Secret.EvmPrivateKey = "" + + InitMachineIdentity( + WithEvmSigner(), + ) + assert.NotEmpty(t, config.App.Secret.EvmPrivateKey) +} From fd2aef498a734e111f481a23fe5a0962170467dc Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Sat, 18 May 2024 22:28:26 +0330 Subject: [PATCH 07/29] =?UTF-8?q?=F0=9F=90=9B=20fix(tss):=20remove=20tss?= =?UTF-8?q?=20identity=20>>>=20=E2=8F=B0=205m?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/crypto/frost/identity.go | 7 ++++--- internal/crypto/frost/identity_test.go | 5 +++-- internal/crypto/frost/signer.go | 1 + internal/crypto/identity.go | 2 -- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/internal/crypto/frost/identity.go b/internal/crypto/frost/identity.go index df8367e4..30401c30 100644 --- a/internal/crypto/frost/identity.go +++ b/internal/crypto/frost/identity.go @@ -2,6 +2,7 @@ package frost import ( "errors" + "github.com/bytemare/crypto" "github.com/bytemare/frost" "github.com/bytemare/frost/dkg" @@ -68,7 +69,7 @@ func (s *DistributedSigner) Finalize(msg *dkg.Round2Data) error { } // NewIdentity creates a new Frost identity. -func NewIdentity(ID int, signerCount int, minSigningCount int) (*dkg.Round1Data, *DistributedSigner) { +func NewIdentity(id int, signerCount int, minSigningCount int) (*dkg.Round1Data, *DistributedSigner) { signer := DistributedSigner{ accumulatedMessages: make([]*dkg.Round1Data, 0, signerCount), config: frost.Ristretto255.Configuration(), @@ -76,7 +77,7 @@ func NewIdentity(ID int, signerCount int, minSigningCount int) (*dkg.Round1Data, minSigningCount: minSigningCount, } - signer.ID = signer.config.IDFromInt(ID) + signer.ID = signer.config.IDFromInt(id) signer.currentParticipant = dkg.NewParticipant( signer.config.Ciphersuite, signer.ID, @@ -89,7 +90,7 @@ func NewIdentity(ID int, signerCount int, minSigningCount int) (*dkg.Round1Data, panic("this is just a test, and it failed") } - //signer.accumulatedMessages = append(signer.accumulatedMessages, round1Data) + // signer.accumulatedMessages = append(signer.accumulatedMessages, round1Data) return round1Data, &signer } diff --git a/internal/crypto/frost/identity_test.go b/internal/crypto/frost/identity_test.go index f2108938..8996f95f 100644 --- a/internal/crypto/frost/identity_test.go +++ b/internal/crypto/frost/identity_test.go @@ -1,13 +1,14 @@ package frost import ( + "math/rand" + "testing" + "github.com/TimeleapLabs/unchained/internal/utils" "github.com/bytemare/frost" "github.com/bytemare/frost/dkg" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" - "math/rand" - "testing" ) const ( diff --git a/internal/crypto/frost/signer.go b/internal/crypto/frost/signer.go index 9e33b540..56361213 100644 --- a/internal/crypto/frost/signer.go +++ b/internal/crypto/frost/signer.go @@ -2,6 +2,7 @@ package frost import ( "errors" + "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/utils" "github.com/bytemare/frost" diff --git a/internal/crypto/identity.go b/internal/crypto/identity.go index 971a853c..53674c43 100644 --- a/internal/crypto/identity.go +++ b/internal/crypto/identity.go @@ -6,7 +6,6 @@ import ( "github.com/TimeleapLabs/unchained/internal/config" "github.com/TimeleapLabs/unchained/internal/crypto/bls" "github.com/TimeleapLabs/unchained/internal/crypto/ethereum" - "github.com/TimeleapLabs/unchained/internal/crypto/tss" "github.com/TimeleapLabs/unchained/internal/model" ) @@ -21,7 +20,6 @@ type Signer interface { type MachineIdentity struct { Bls Signer Eth Signer - Tss *tss.DistributedSigner } // Identity is a global variable that holds machine identity. From c5395d23fef745331d8341eeb8e547905149ca1c Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Tue, 21 May 2024 15:14:27 +0330 Subject: [PATCH 08/29] fix: expose key share in frost --- internal/app/broker.go | 8 ++++ internal/config/model.go | 6 +++ internal/consts/channels.go | 1 + internal/consts/opcodes.go | 2 + internal/crypto/frost/identity.go | 5 +-- internal/crypto/frost/signer.go | 19 +++++++--- internal/model/bls.go | 21 ++++++++++ internal/scheduler/frost.go | 27 +++++++++++++ internal/scheduler/scheduler.go | 12 ++++++ internal/service/frost/frost.go | 14 +++++++ internal/service/frost/sync.go | 40 ++++++++++++++++++++ internal/transport/client/client.go | 2 + internal/transport/client/handler/frost.go | 16 ++++++++ internal/transport/client/handler/handler.go | 2 + 14 files changed, 165 insertions(+), 10 deletions(-) create mode 100644 internal/scheduler/frost.go create mode 100644 internal/service/frost/frost.go create mode 100644 internal/service/frost/sync.go create mode 100644 internal/transport/client/handler/frost.go diff --git a/internal/app/broker.go b/internal/app/broker.go index cff0fa36..42875f3f 100644 --- a/internal/app/broker.go +++ b/internal/app/broker.go @@ -26,7 +26,15 @@ func Broker() { ethRPC := ethereum.New() pos.New(ethRPC) + //frostService := frost.New() + + //scheduler := scheduler.New( + // scheduler.WithFrostEvents(frostService), + //) + server.New( websocket.WithWebsocket(), ) + + //scheduler.Start() } diff --git a/internal/config/model.go b/internal/config/model.go index 7d312387..2a840806 100644 --- a/internal/config/model.go +++ b/internal/config/model.go @@ -34,10 +34,16 @@ type EthLog struct { Events []Event `yaml:"events"` } +// Frost struct represent all task detail of its plugin. +type Frost struct { + Schedule time.Duration `yaml:"schedule"` +} + // Plugins struct holds all applications plugin configs. type Plugins struct { EthLog *EthLog `yaml:"logs"` Uniswap *Uniswap `yaml:"uniswap"` + Frost *Frost `yaml:"frost"` Correctness []string `yaml:"correctness"` } diff --git a/internal/consts/channels.go b/internal/consts/channels.go index d3ff0484..616a8650 100644 --- a/internal/consts/channels.go +++ b/internal/consts/channels.go @@ -7,4 +7,5 @@ const ( ChannelPriceReport Channels = "unchained:price_report" ChannelEventLog Channels = "unchained:event_log" ChannelCorrectnessReport Channels = "unchained:correctness_report" + ChannelFrostSignerList Channels = "unchained:frost_signer_list" ) diff --git a/internal/consts/opcodes.go b/internal/consts/opcodes.go index 448fe703..31b60db5 100644 --- a/internal/consts/opcodes.go +++ b/internal/consts/opcodes.go @@ -23,4 +23,6 @@ const ( OpCodeCorrectnessReport OpCode = 10 OpCodeCorrectnessReportBroadcast OpCode = 11 + + OpCodeSendSignerList OpCode = 12 ) diff --git a/internal/crypto/frost/identity.go b/internal/crypto/frost/identity.go index 30401c30..63ef8394 100644 --- a/internal/crypto/frost/identity.go +++ b/internal/crypto/frost/identity.go @@ -40,6 +40,7 @@ func (s *DistributedSigner) Update(msg *dkg.Round1Data) ([]*dkg.Round2Data, erro return round2Data, nil } +// Finalize function will confirm the identity key about other parties updates. func (s *DistributedSigner) Finalize(msg *dkg.Round2Data) error { if msg.ReceiverIdentifier.Equal(s.currentParticipant.Identifier) == 0 { return nil @@ -51,8 +52,6 @@ func (s *DistributedSigner) Finalize(msg *dkg.Round2Data) error { return nil } - // This will, for each participant, return their secret key (which is a share of the global secret signing key), - // the corresponding verification key, and the global public key. participantsSecretKey, _, groupPublicKeyGeneratedInDKG, err := s.currentParticipant.Finalize( s.accumulatedMessages, s.ackMessages, @@ -90,7 +89,5 @@ func NewIdentity(id int, signerCount int, minSigningCount int) (*dkg.Round1Data, panic("this is just a test, and it failed") } - // signer.accumulatedMessages = append(signer.accumulatedMessages, round1Data) - return round1Data, &signer } diff --git a/internal/crypto/frost/signer.go b/internal/crypto/frost/signer.go index 56361213..b5aea5b3 100644 --- a/internal/crypto/frost/signer.go +++ b/internal/crypto/frost/signer.go @@ -2,7 +2,6 @@ package frost import ( "errors" - "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/utils" "github.com/bytemare/frost" @@ -16,17 +15,18 @@ type MessageSigner struct { participant *frost.Participant } -func (s *MessageSigner) Confirm(commitment *frost.Commitment) error { +// Confirm function will set other parties confirms. +func (s *MessageSigner) Confirm(commitment *frost.Commitment) (*frost.SignatureShare, error) { s.commitments = append(s.commitments, commitment) if len(s.commitments.Participants()) < s.partySize { - return nil + return nil, nil } signatureShare, err := s.participant.Sign(s.data, s.commitments) if err != nil { utils.Logger.With("err", err).Error("cant sign message") - return consts.ErrCantSign + return nil, consts.ErrCantSign } if !s.participant.VerifySignatureShare( @@ -36,12 +36,19 @@ func (s *MessageSigner) Confirm(commitment *frost.Commitment) error { s.commitments, s.data, ) { - return consts.ErrCantVerify + return nil, consts.ErrCantVerify } - return nil + return signatureShare, nil +} + +func (s *MessageSigner) AggregateSignatures(signatureShares []*frost.SignatureShare) ([]byte, error) { + signature := s.participant.Aggregate(s.commitments, s.data, signatureShares) + + return signature.Encode(), nil } +// NewSigner create a new signing state for a message. func (s *DistributedSigner) NewSigner(data []byte) (*MessageSigner, *frost.Commitment, error) { if s.finalParticipant == nil { return nil, nil, consts.ErrSignerIsNotReady diff --git a/internal/model/bls.go b/internal/model/bls.go index 4449e623..d0ce1671 100644 --- a/internal/model/bls.go +++ b/internal/model/bls.go @@ -4,6 +4,8 @@ import ( sia "github.com/pouya-eghbali/go-sia/v2/pkg" ) +type Signers []Signer + type Signer struct { Name string EvmAddress string @@ -34,6 +36,25 @@ func (s *Signature) FromSia(sia sia.Sia) *Signature { return s } +func (s Signers) Sia() sia.Sia { + return new(sia.ArraySia[Signer]). + AddArray8(s, func(s *sia.ArraySia[Signer], item Signer) { + s.EmbedBytes(item.Sia().Bytes()) + }) +} + +//func (s Signers) FromBytes(payload []byte) Signers { +// signers := Signers{} +// +// siaArray := sia.ArraySia[Signer]{ +// sia.NewFromBytes(payload), +// } +// +// ReadArray8(func(s *sia.ArraySia[Signer]) Signer { +// signers = append(signers, Signer) +// }) +//} + func (s *Signer) Sia() sia.Sia { return sia.New(). AddString8(s.Name). diff --git a/internal/scheduler/frost.go b/internal/scheduler/frost.go new file mode 100644 index 00000000..2b41774f --- /dev/null +++ b/internal/scheduler/frost.go @@ -0,0 +1,27 @@ +package scheduler + +import ( + "github.com/TimeleapLabs/unchained/internal/service/frost" +) + +// FrostSync is a scheduler for syncing signer of Frost and keep task's dependencies. +type FrostSync struct { + frostService frost.Service +} + +// Run will trigger by the scheduler and process the Frost sync. +func (e *FrostSync) Run() { + err := e.frostService.PushSigners() + if err != nil { + panic(err) + } +} + +// NewFrostSync will create a new FrostSync task. +func NewFrostSync(frostService frost.Service) *FrostSync { + e := FrostSync{ + frostService: frostService, + } + + return &e +} diff --git a/internal/scheduler/scheduler.go b/internal/scheduler/scheduler.go index f76a464f..d4f771a9 100644 --- a/internal/scheduler/scheduler.go +++ b/internal/scheduler/scheduler.go @@ -4,6 +4,8 @@ import ( "os" "time" + "github.com/TimeleapLabs/unchained/internal/service/frost" + "github.com/TimeleapLabs/unchained/internal/utils" "github.com/TimeleapLabs/unchained/internal/config" @@ -66,6 +68,16 @@ func WithUniswapEvents(uniswapService uniswapService.Service) func(s *Scheduler) } } +// WithFrostEvents adds frost sync event task to the scheduler. +func WithFrostEvents(frostService frost.Service) func(s *Scheduler) { + return func(s *Scheduler) { + if config.App.Plugins.Frost == nil { + return + } + s.AddTask(config.App.Plugins.Frost.Schedule, NewFrostSync(frostService)) + } +} + // AddTask adds a new task to the scheduler. func (s *Scheduler) AddTask(duration time.Duration, task Task) { utils.Logger. diff --git a/internal/service/frost/frost.go b/internal/service/frost/frost.go new file mode 100644 index 00000000..560d43eb --- /dev/null +++ b/internal/service/frost/frost.go @@ -0,0 +1,14 @@ +package frost + +type Service interface { + PushSigners() error +} + +type service struct { + reserveSigners []bool + currentSigners []bool +} + +func New() Service { + return &service{} +} diff --git a/internal/service/frost/sync.go b/internal/service/frost/sync.go new file mode 100644 index 00000000..ded26950 --- /dev/null +++ b/internal/service/frost/sync.go @@ -0,0 +1,40 @@ +package frost + +import ( + "encoding/json" + "github.com/TimeleapLabs/unchained/internal/transport/server/pubsub" + + "github.com/TimeleapLabs/unchained/internal/consts" + "github.com/TimeleapLabs/unchained/internal/model" + "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/store" + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/gorilla/websocket" +) + +// PushSigners starts calculating of Frost signers by sending signers list to the Broker. +func (s *service) PushSigners() error { + signers := []model.Signer{} + store.Signers.Range(func(_ *websocket.Conn, value model.Signer) bool { + signers = append(signers, value) + return true + }) + + signersBytes, err := json.Marshal(signers) + if err != nil { + utils.Logger.With("Error", err).Error("Cant marshal signers list") + return consts.ErrInternalError + } + + pubsub.Publish(consts.ChannelFrostSignerList, consts.OpCodeSendSignerList, signersBytes) + + return nil +} + +// SyncSigners Get list of signers and check power of voting them and generate a new list (if there is difference) of signers which have power. +func (s *service) SyncSigners(signers []model.Signer) error { + // TODO: get power of list items and delete no power ones. + + // TODO: check the final list with previous one, and replace it if it have difference + + return nil +} diff --git a/internal/transport/client/client.go b/internal/transport/client/client.go index 5470b5fe..1c0a4b2c 100644 --- a/internal/transport/client/client.go +++ b/internal/transport/client/client.go @@ -44,6 +44,8 @@ func NewRPC(handler handler.Handler) { case consts.OpCodeCorrectnessReportBroadcast: handler.CorrectnessReport(ctx, payload[1:]) + case consts.OpCodeSendSignerList: + handler.InitFrostSigner(ctx, payload[1:]) default: utils.Logger. With("Code", payload[0]). diff --git a/internal/transport/client/handler/frost.go b/internal/transport/client/handler/frost.go new file mode 100644 index 00000000..6729c763 --- /dev/null +++ b/internal/transport/client/handler/frost.go @@ -0,0 +1,16 @@ +package handler + +import ( + "context" +) + +func (h *consumer) InitFrostSigner(ctx context.Context, message []byte) { + // packet := new([]model.Signer).FromBytes(message) + +} + +func (w worker) InitFrostSigner(ctx context.Context, message []byte) { + //packet := new(model.Signers).FromBytes(message) + //TODO implement me + panic("implement me") +} diff --git a/internal/transport/client/handler/handler.go b/internal/transport/client/handler/handler.go index 71fad11e..cd515593 100644 --- a/internal/transport/client/handler/handler.go +++ b/internal/transport/client/handler/handler.go @@ -9,4 +9,6 @@ type Handler interface { CorrectnessReport(ctx context.Context, message []byte) EventLog(ctx context.Context, message []byte) PriceReport(ctx context.Context, message []byte) + + InitFrostSigner(ctx context.Context, message []byte) } From fa736d7b789baa84b6db437c606da990151d0290 Mon Sep 17 00:00:00 2001 From: Pouya Date: Wed, 22 May 2024 20:53:38 +0200 Subject: [PATCH 09/29] =?UTF-8?q?=F0=9F=90=9B=20fix:=20fix=20the=20Confirm?= =?UTF-8?q?=20function=20and=20add=20aggregate=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/crypto/frost/identity_test.go | 29 +++++++++++++++++++++----- internal/crypto/frost/signer.go | 19 ++++++++++------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/internal/crypto/frost/identity_test.go b/internal/crypto/frost/identity_test.go index 8996f95f..7e1bc9fe 100644 --- a/internal/crypto/frost/identity_test.go +++ b/internal/crypto/frost/identity_test.go @@ -1,7 +1,6 @@ package frost import ( - "math/rand" "testing" "github.com/TimeleapLabs/unchained/internal/utils" @@ -12,8 +11,8 @@ import ( ) const ( - numOfSigners = 4 - minNumOfSigners = 2 + numOfSigners = 100 + minNumOfSigners = 51 ) var ( @@ -31,7 +30,7 @@ func (s *FrostIdentityTestSuite) SetupTest() { utils.SetupLogger("info") for i := 0; i < numOfSigners; i++ { - signers = append(signers, rand.Intn(9999)) + signers = append(signers, i+1) } r1Messages := []*dkg.Round1Data{} @@ -71,12 +70,32 @@ func (s *FrostIdentityTestSuite) TestSign() { signers = append(signers, signer) } + signatureShares := make([]*frost.SignatureShare, 0, minNumOfSigners) + for i := 0; i < minNumOfSigners; i++ { for j := 0; j < minNumOfSigners; j++ { - err := signers[i].Confirm(commits[j]) + signature, err := signers[i].Confirm(commits[j]) assert.NoError(s.T(), err) + if signature != nil { + signatureShares = append(signatureShares, signature) + } } } + + signature := signers[0].participant.Aggregate( + signers[0].commitments, + testData, + signatureShares, + ) + + ok := frost.Verify( + frost.Ristretto255.Configuration().Ciphersuite, + testData, + signature, + signers[0].participant.GroupPublicKey, + ) + + assert.True(s.T(), ok) } func TestFrostIdentitySuite(t *testing.T) { diff --git a/internal/crypto/frost/signer.go b/internal/crypto/frost/signer.go index b5aea5b3..b6d8a1a7 100644 --- a/internal/crypto/frost/signer.go +++ b/internal/crypto/frost/signer.go @@ -2,6 +2,7 @@ package frost import ( "errors" + "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/utils" "github.com/bytemare/frost" @@ -13,6 +14,7 @@ type MessageSigner struct { data []byte commitments frost.CommitmentList participant *frost.Participant + commitment *frost.Commitment } // Confirm function will set other parties confirms. @@ -30,8 +32,8 @@ func (s *MessageSigner) Confirm(commitment *frost.Commitment) (*frost.SignatureS } if !s.participant.VerifySignatureShare( - commitment, - s.participant.GroupPublicKey, + s.commitment, + s.participant.PublicKey, signatureShare.SignatureShare, s.commitments, s.data, @@ -54,16 +56,17 @@ func (s *DistributedSigner) NewSigner(data []byte) (*MessageSigner, *frost.Commi return nil, nil, consts.ErrSignerIsNotReady } + commitment := s.finalParticipant.Commit() + if commitment.Identifier.Equal(s.finalParticipant.KeyShare.Identifier) != 1 { + return nil, nil, errors.New("identifier is not correct") + } + signer := &MessageSigner{ - partySize: s.signerCount, + partySize: s.minSigningCount, data: data, commitments: make(frost.CommitmentList, 0, s.signerCount), participant: s.finalParticipant, - } - - commitment := s.finalParticipant.Commit() - if commitment.Identifier.Equal(s.finalParticipant.KeyShare.Identifier) != 1 { - return nil, nil, errors.New("identifier is not correct") + commitment: commitment, } return signer, commitment, nil From e3811cacf27fb8621dc8eff646244de4155e08e0 Mon Sep 17 00:00:00 2001 From: Pouya Date: Wed, 22 May 2024 20:55:27 +0200 Subject: [PATCH 10/29] =?UTF-8?q?=F0=9F=91=B7=20build:=20run=20go=20mod=20?= =?UTF-8?q?tidy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 9 +-------- go.sum | 30 ------------------------------ 2 files changed, 1 insertion(+), 38 deletions(-) diff --git a/go.mod b/go.mod index 885bfa8e..8ceadd97 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,8 @@ require ( entgo.io/contrib v0.4.6-0.20240215171353-eff33e4dca0b entgo.io/ent v0.13.1 github.com/99designs/gqlgen v0.17.45 - github.com/bnb-chain/tss-lib v1.3.5 github.com/btcsuite/btcutil v1.0.2 + github.com/bytemare/crypto v0.5.2 github.com/bytemare/frost v0.0.0-20231127024126-bc6f7874b253 github.com/consensys/gnark-crypto v0.12.1 github.com/dgraph-io/badger/v4 v4.2.0 @@ -42,14 +42,12 @@ require ( github.com/Microsoft/go-winio v0.6.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect github.com/agext/levenshtein v1.2.3 // indirect - github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/btcsuite/btcd v0.20.1-beta // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect - github.com/bytemare/crypto v0.5.2 // indirect github.com/bytemare/hash v0.1.5 // indirect github.com/bytemare/hash2curve v0.2.2 // indirect github.com/bytemare/secp256k1 v0.1.0 // indirect @@ -67,7 +65,6 @@ require ( github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect - github.com/decred/dcrd/dcrec/edwards/v2 v2.0.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect @@ -97,7 +94,6 @@ require ( github.com/holiman/uint256 v1.2.4 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/ipfs/go-log v0.0.1 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect @@ -115,8 +111,6 @@ require ( github.com/mitchellh/pointerstructure v1.2.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/opentracing/opentracing-go v1.1.0 // indirect - github.com/otiai10/primes v0.0.0-20180210170552-f6d2a1ba97c4 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.12.0 // indirect @@ -141,7 +135,6 @@ require ( github.com/urfave/cli/v2 v2.27.1 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zclconf/go-cty v1.14.4 // indirect diff --git a/go.sum b/go.sum index b67ecc45..e9e02dd2 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ ariga.io/atlas v0.20.0 h1:b2dL/OIubrCDKDUUXtudS+lJjoTzzKsTamfEg0VkcPI= ariga.io/atlas v0.20.0/go.mod h1:VPlcXdd4w2KqKnH54yEZcry79UAhpaWaxEsmn5JRNoE= -bou.ke/monkey v1.0.1 h1:zEMLInw9xvNakzUUPjfS4Ds6jYPqCFx3m7bRmG5NH2U= -bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -69,8 +67,6 @@ github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWk github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= -github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI= -github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= @@ -97,9 +93,6 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/bnb-chain/tss-lib v1.3.5 h1:HqhrsiZfR+YPTOuedi65JnwE1HxsHAxKdoy7I2QQAPs= -github.com/bnb-chain/tss-lib v1.3.5/go.mod h1:o3zAAo7A88ZJnCE1qpjy1hTqPn+GPQlxRsj8soz14UU= -github.com/btcsuite/btcd v0.0.0-20190629003639-c26ffa870fd8/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= @@ -178,8 +171,6 @@ github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80N github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= -github.com/decred/dcrd/dcrec/edwards/v2 v2.0.0 h1:E5KszxGgpjpmW8vN811G6rBAZg0/S/DftdGqN4FW5x4= -github.com/decred/dcrd/dcrec/edwards/v2 v2.0.0/go.mod h1:d0H8xGMWbiIQP7gN3v2rByWUcuZPm9YsgmnfoxgbINc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= @@ -252,7 +243,6 @@ github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -343,7 +333,6 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= @@ -371,8 +360,6 @@ github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/C github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= -github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= @@ -411,7 +398,6 @@ github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4 github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -442,11 +428,9 @@ github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc= github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= @@ -502,14 +486,6 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/mint v1.2.4 h1:DxYL0itZyPaR5Z9HILdxSoHx+gNs6Yx+neOGS3IVUk0= -github.com/otiai10/mint v1.2.4/go.mod h1:d+b7n/0R3tdyUYYylALXpWQ/kTN+QobSq/4SRGBkR3M= -github.com/otiai10/primes v0.0.0-20180210170552-f6d2a1ba97c4 h1:blMAhTXF6uL1+e3eVSajjLT43Cc0U8mU1gcigbbolJM= -github.com/otiai10/primes v0.0.0-20180210170552-f6d2a1ba97c4/go.mod h1:UmSP7QeU3XmAdGu5+dnrTJqjBc+IscpVZkQzk473cjM= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterldowns/pgtestdb v0.0.14 h1:myVNL8ethaPZG7CQIjZxZCXwOG428THYRbSm0mIelpU= github.com/peterldowns/pgtestdb v0.0.14/go.mod h1:aG99+zgvWKOdGH+vtEFTDNVmaPOJD8ldIleuwJOgacA= @@ -631,8 +607,6 @@ github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IU github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= -github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= @@ -713,7 +687,6 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -780,7 +753,6 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -835,7 +807,6 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -967,7 +938,6 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= From 7d877e1780d4c8bd67fb715d954768404a97f8ef Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Fri, 24 May 2024 02:47:16 +0330 Subject: [PATCH 11/29] =?UTF-8?q?=E2=9C=A8=20feat(frost):=20add=20encode/d?= =?UTF-8?q?ecode=20functions=20and=20fix=20some=20issues=20>>>=20=E2=8F=B0?= =?UTF-8?q?=204h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/app/broker.go | 6 +- internal/consts/errors.go | 1 + internal/crypto/frost/convert.go | 158 +++++++++++++++++++++ internal/crypto/frost/identity.go | 22 ++- internal/crypto/frost/identity_test.go | 37 ++--- internal/crypto/frost/signer.go | 44 +++++- internal/model/bls.go | 2 +- internal/service/frost/sync.go | 1 + internal/transport/client/handler/frost.go | 4 +- 9 files changed, 235 insertions(+), 40 deletions(-) create mode 100644 internal/crypto/frost/convert.go diff --git a/internal/app/broker.go b/internal/app/broker.go index 42875f3f..214bccae 100644 --- a/internal/app/broker.go +++ b/internal/app/broker.go @@ -26,9 +26,9 @@ func Broker() { ethRPC := ethereum.New() pos.New(ethRPC) - //frostService := frost.New() + // frostService := frost.New() - //scheduler := scheduler.New( + // scheduler := scheduler.New( // scheduler.WithFrostEvents(frostService), //) @@ -36,5 +36,5 @@ func Broker() { websocket.WithWebsocket(), ) - //scheduler.Start() + // scheduler.Start() } diff --git a/internal/consts/errors.go b/internal/consts/errors.go index 4f7775d6..50c9e8c4 100644 --- a/internal/consts/errors.go +++ b/internal/consts/errors.go @@ -30,5 +30,6 @@ var ( ErrAlreadySynced = errors.New("already synced") ErrSignerIsNotReady = errors.New("signer is not ready yet") ErrCantSign = errors.New("cant sign message") + ErrCantDecode = errors.New("cant decode message") ErrCantVerify = errors.New("cant verify message") ) diff --git a/internal/crypto/frost/convert.go b/internal/crypto/frost/convert.go new file mode 100644 index 00000000..6b6aee8c --- /dev/null +++ b/internal/crypto/frost/convert.go @@ -0,0 +1,158 @@ +package frost + +import ( + "encoding/hex" + + "github.com/TimeleapLabs/unchained/internal/consts" + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/bytemare/crypto" + "github.com/bytemare/frost" + "github.com/bytemare/frost/dkg" +) + +// DecodeCommitment will decode commitment from bytes. +func (s *MessageSigner) DecodeCommitment(data []byte) (*frost.Commitment, error) { + scalarLen := s.participant.Ciphersuite.Group.ScalarLength() + commitment := &frost.Commitment{ + Identifier: s.participant.Ciphersuite.Group.NewScalar(), + HidingNonce: s.participant.Ciphersuite.Group.NewElement(), + BindingNonce: s.participant.Ciphersuite.Group.NewElement(), + } + + err := commitment.Identifier.Decode(data[:scalarLen]) + if err != nil { + utils.Logger.With("err", err, "value", hex.EncodeToString(data[:scalarLen])).Error("cant decode commitment identifier") + return nil, err + } + + err = commitment.HidingNonce.Decode(data[scalarLen : scalarLen*2]) + if err != nil { + utils.Logger.With("err", err, "value", hex.EncodeToString(data[:scalarLen])).Error("cant decode commitment hiding_nonce") + // return nil, err + } + + err = commitment.BindingNonce.Decode(data[scalarLen*2 : scalarLen*3]) + if err != nil { + utils.Logger.With("err", err, "value", hex.EncodeToString(data[:scalarLen])).Error("cant decode commitment binding_nonce") + return nil, err + } + + return commitment, nil +} + +// DecodeSignature will decode signature from bytes. +func (s *MessageSigner) DecodeSignature(data []byte) (*frost.Signature, error) { + signature := frost.Signature{ + R: s.participant.Ciphersuite.Group.NewElement(), + Z: s.participant.Ciphersuite.Group.NewScalar(), + } + err := signature.Decode(s.participant.Ciphersuite.Group, data) + if err != nil { + utils.Logger.With("err", err).Error("cant decode signature") + return &signature, consts.ErrCantDecode + } + + return &signature, nil +} + +func EncodeRoundOneMessage(message *dkg.Round1Data) []byte { + commitment := []byte{} + for _, commit := range message.Commitment { + commitment = append(commitment, commit.Encode()...) + } + + out := []byte{} + out = append(out, message.SenderIdentifier.Encode()...) + out = append(out, message.ProofOfKnowledge.Encode()...) + out = append(out, commitment...) + + return out +} + +func EncodeRoundTwoMessages(message []*dkg.Round2Data) [][]byte { + out := [][]byte{} + + for _, msg := range message { + out = append(out, EncodeRoundTwoMessage(msg)) + } + + return out +} + +func EncodeRoundTwoMessage(message *dkg.Round2Data) []byte { + out := []byte{} + + out = append(out, message.SenderIdentifier.Encode()...) + out = append(out, message.ReceiverIdentifier.Encode()...) + out = append(out, message.SecretShare.Encode()...) + + return out +} + +func (s *DistributedSigner) DecodeRoundTwoMessage(message []byte) (*dkg.Round2Data, error) { + r2Data := &dkg.Round2Data{ + SenderIdentifier: s.config.Ciphersuite.Group.NewScalar(), + ReceiverIdentifier: s.config.Ciphersuite.Group.NewScalar(), + SecretShare: s.config.Ciphersuite.Group.NewScalar(), + } + + err := r2Data.SenderIdentifier.Decode(message[:s.config.Ciphersuite.Group.ScalarLength()]) + if err != nil { + utils.Logger.With("err", err).Error("cant decode sender_identifier") + return nil, err + } + + err = r2Data.ReceiverIdentifier.Decode(message[s.config.Ciphersuite.Group.ScalarLength() : s.config.Ciphersuite.Group.ScalarLength()*2]) + if err != nil { + utils.Logger.With("err", err).Error("cant decode receiver_identifier") + return nil, err + } + + err = r2Data.SecretShare.Decode(message[s.config.Ciphersuite.Group.ScalarLength()*2:]) + if err != nil { + utils.Logger.With("err", err).Error("cant decode secret_share") + return nil, err + } + + return r2Data, nil +} + +func (s *DistributedSigner) DecodeRoundOneMessage(message []byte) (*dkg.Round1Data, error) { + senderBytes := message[:s.config.Ciphersuite.Group.ScalarLength()] + proofBytes := message[s.config.Ciphersuite.Group.ScalarLength() : s.config.Ciphersuite.Group.ScalarLength()+64] + commitmentsBytes := message[s.config.Ciphersuite.Group.ScalarLength()+64:] + + r1Data := &dkg.Round1Data{ + ProofOfKnowledge: frost.Signature{ + R: s.config.Ciphersuite.Group.NewElement(), + Z: s.config.Ciphersuite.Group.NewScalar(), + }, + SenderIdentifier: s.config.Ciphersuite.Group.NewScalar(), + Commitment: []*crypto.Element{}, + } + + for i := 0; i < len(commitmentsBytes); i += s.config.Ciphersuite.Group.ElementLength() { + commitment := s.config.Ciphersuite.Group.NewElement() + err := commitment.Decode(commitmentsBytes[i : i+s.config.Ciphersuite.Group.ElementLength()]) + if err != nil { + utils.Logger.With("err", err).Error("cant decode commitment") + return nil, err + } + + r1Data.Commitment = append(r1Data.Commitment, commitment) + } + + err := r1Data.ProofOfKnowledge.Decode(s.config.Ciphersuite.Group, proofBytes) + if err != nil { + utils.Logger.With("err", err).Error("cant decode proof_of_knowledge") + return nil, err + } + + err = r1Data.SenderIdentifier.Decode(senderBytes) + if err != nil { + utils.Logger.With("err", err).Error("cant decode identifier") + return nil, err + } + + return r1Data, nil +} diff --git a/internal/crypto/frost/identity.go b/internal/crypto/frost/identity.go index 63ef8394..831a92a8 100644 --- a/internal/crypto/frost/identity.go +++ b/internal/crypto/frost/identity.go @@ -21,8 +21,13 @@ type DistributedSigner struct { } // Update function will update the identity key about other parties. -func (s *DistributedSigner) Update(msg *dkg.Round1Data) ([]*dkg.Round2Data, error) { - s.accumulatedMessages = append(s.accumulatedMessages, msg) +func (s *DistributedSigner) Update(msg []byte) ([][]byte, error) { + round1Data, err := s.DecodeRoundOneMessage(msg) + if err != nil { + return nil, err + } + + s.accumulatedMessages = append(s.accumulatedMessages, round1Data) if len(s.accumulatedMessages) != s.signerCount { return nil, nil @@ -37,11 +42,16 @@ func (s *DistributedSigner) Update(msg *dkg.Round1Data) ([]*dkg.Round2Data, erro return nil, errors.New("number of accept messages is not correct") } - return round2Data, nil + return EncodeRoundTwoMessages(round2Data), nil } // Finalize function will confirm the identity key about other parties updates. -func (s *DistributedSigner) Finalize(msg *dkg.Round2Data) error { +func (s *DistributedSigner) Finalize(msgByte []byte) error { + msg, err := s.DecodeRoundTwoMessage(msgByte) + if err != nil { + return err + } + if msg.ReceiverIdentifier.Equal(s.currentParticipant.Identifier) == 0 { return nil } @@ -68,7 +78,7 @@ func (s *DistributedSigner) Finalize(msg *dkg.Round2Data) error { } // NewIdentity creates a new Frost identity. -func NewIdentity(id int, signerCount int, minSigningCount int) (*dkg.Round1Data, *DistributedSigner) { +func NewIdentity(id int, signerCount int, minSigningCount int) ([]byte, *DistributedSigner) { signer := DistributedSigner{ accumulatedMessages: make([]*dkg.Round1Data, 0, signerCount), config: frost.Ristretto255.Configuration(), @@ -89,5 +99,5 @@ func NewIdentity(id int, signerCount int, minSigningCount int) (*dkg.Round1Data, panic("this is just a test, and it failed") } - return round1Data, &signer + return EncodeRoundOneMessage(round1Data), &signer } diff --git a/internal/crypto/frost/identity_test.go b/internal/crypto/frost/identity_test.go index 7e1bc9fe..515a1629 100644 --- a/internal/crypto/frost/identity_test.go +++ b/internal/crypto/frost/identity_test.go @@ -4,15 +4,13 @@ import ( "testing" "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/bytemare/frost" - "github.com/bytemare/frost/dkg" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" ) const ( - numOfSigners = 100 - minNumOfSigners = 51 + numOfSigners = 10 + minNumOfSigners = 6 ) var ( @@ -33,14 +31,14 @@ func (s *FrostIdentityTestSuite) SetupTest() { signers = append(signers, i+1) } - r1Messages := []*dkg.Round1Data{} + r1Messages := [][]byte{} for i := 0; i < numOfSigners; i++ { r1Msg, party := NewIdentity(signers[i], numOfSigners, minNumOfSigners) s.parties = append(s.parties, party) r1Messages = append(r1Messages, r1Msg) } - r2Messages := []*dkg.Round2Data{} + r2Messages := [][]byte{} for i := 0; i < numOfSigners; i++ { for j := 0; j < numOfSigners; j++ { r2Msgs, err := s.parties[i].Update(r1Messages[j]) @@ -60,7 +58,7 @@ func (s *FrostIdentityTestSuite) SetupTest() { func (s *FrostIdentityTestSuite) TestSign() { signers := make([]*MessageSigner, 0, minNumOfSigners) - commits := make([]*frost.Commitment, 0, minNumOfSigners) + commits := [][]byte{} for i := 0; i < minNumOfSigners; i++ { signer, msg, err := s.parties[i].NewSigner(testData) @@ -70,31 +68,24 @@ func (s *FrostIdentityTestSuite) TestSign() { signers = append(signers, signer) } - signatureShares := make([]*frost.SignatureShare, 0, minNumOfSigners) + signatureShares := make([][]byte, 0, minNumOfSigners) - for i := 0; i < minNumOfSigners; i++ { - for j := 0; j < minNumOfSigners; j++ { - signature, err := signers[i].Confirm(commits[j]) + for _, signer := range signers { + for _, commit := range commits { + signature, err := signer.Confirm(commit) assert.NoError(s.T(), err) + if signature != nil { signatureShares = append(signatureShares, signature) } } } - signature := signers[0].participant.Aggregate( - signers[0].commitments, - testData, - signatureShares, - ) - - ok := frost.Verify( - frost.Ristretto255.Configuration().Ciphersuite, - testData, - signature, - signers[0].participant.GroupPublicKey, - ) + signature, err := signers[0].Aggregate(signatureShares) + assert.NoError(s.T(), err) + ok, err := signers[0].Verify(signature) + assert.NoError(s.T(), err) assert.True(s.T(), ok) } diff --git a/internal/crypto/frost/signer.go b/internal/crypto/frost/signer.go index b6d8a1a7..7548b3f5 100644 --- a/internal/crypto/frost/signer.go +++ b/internal/crypto/frost/signer.go @@ -18,7 +18,13 @@ type MessageSigner struct { } // Confirm function will set other parties confirms. -func (s *MessageSigner) Confirm(commitment *frost.Commitment) (*frost.SignatureShare, error) { +func (s *MessageSigner) Confirm(commitmentBytes []byte) ([]byte, error) { + commitment, err := s.DecodeCommitment(commitmentBytes) + if err != nil { + utils.Logger.With("err", err).Error("cant decode commitment") + return nil, consts.ErrCantDecode + } + s.commitments = append(s.commitments, commitment) if len(s.commitments.Participants()) < s.partySize { @@ -41,17 +47,45 @@ func (s *MessageSigner) Confirm(commitment *frost.Commitment) (*frost.SignatureS return nil, consts.ErrCantVerify } - return signatureShare, nil + return signatureShare.Encode(), nil } -func (s *MessageSigner) AggregateSignatures(signatureShares []*frost.SignatureShare) ([]byte, error) { +// Aggregate function will generate final signature by combining parties signature shares. +func (s *MessageSigner) Aggregate(signatureSharesBytes [][]byte) ([]byte, error) { + signatureShares := []*frost.SignatureShare{} + + for _, signatureShareBytes := range signatureSharesBytes { + signatureShare, err := frost.Ristretto255.Configuration().DecodeSignatureShare(signatureShareBytes) + if err != nil { + utils.Logger.With("err", err).Error("cant decode signature share") + return nil, consts.ErrCantDecode + } + + signatureShares = append(signatureShares, signatureShare) + } + signature := s.participant.Aggregate(s.commitments, s.data, signatureShares) return signature.Encode(), nil } +// Verify function will verify the signature. +func (s *MessageSigner) Verify(signatureBytes []byte) (bool, error) { + signature, err := s.DecodeSignature(signatureBytes) + if err != nil { + return false, err + } + + return frost.Verify( + frost.Ristretto255.Configuration().Ciphersuite, + s.data, + signature, + s.participant.GroupPublicKey, + ), nil +} + // NewSigner create a new signing state for a message. -func (s *DistributedSigner) NewSigner(data []byte) (*MessageSigner, *frost.Commitment, error) { +func (s *DistributedSigner) NewSigner(data []byte) (*MessageSigner, []byte, error) { if s.finalParticipant == nil { return nil, nil, consts.ErrSignerIsNotReady } @@ -69,5 +103,5 @@ func (s *DistributedSigner) NewSigner(data []byte) (*MessageSigner, *frost.Commi commitment: commitment, } - return signer, commitment, nil + return signer, commitment.Encode(), nil } diff --git a/internal/model/bls.go b/internal/model/bls.go index d0ce1671..54882dd6 100644 --- a/internal/model/bls.go +++ b/internal/model/bls.go @@ -43,7 +43,7 @@ func (s Signers) Sia() sia.Sia { }) } -//func (s Signers) FromBytes(payload []byte) Signers { +// func (s Signers) FromBytes(payload []byte) Signers { // signers := Signers{} // // siaArray := sia.ArraySia[Signer]{ diff --git a/internal/service/frost/sync.go b/internal/service/frost/sync.go index ded26950..6248b88b 100644 --- a/internal/service/frost/sync.go +++ b/internal/service/frost/sync.go @@ -2,6 +2,7 @@ package frost import ( "encoding/json" + "github.com/TimeleapLabs/unchained/internal/transport/server/pubsub" "github.com/TimeleapLabs/unchained/internal/consts" diff --git a/internal/transport/client/handler/frost.go b/internal/transport/client/handler/frost.go index 6729c763..36bf09cc 100644 --- a/internal/transport/client/handler/frost.go +++ b/internal/transport/client/handler/frost.go @@ -10,7 +10,7 @@ func (h *consumer) InitFrostSigner(ctx context.Context, message []byte) { } func (w worker) InitFrostSigner(ctx context.Context, message []byte) { - //packet := new(model.Signers).FromBytes(message) - //TODO implement me + // packet := new(model.Signers).FromBytes(message) + // TODO implement me panic("implement me") } From c562944f30ed1f2ae7b319520ffd75f38567e819 Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Wed, 15 May 2024 12:24:07 +0330 Subject: [PATCH 12/29] =?UTF-8?q?=F0=9F=90=9B=20fix(eth-rpc):=20fix=20prob?= =?UTF-8?q?lem=20of=20race=20condition=20for=20client=20list=20>>>=20?= =?UTF-8?q?=E2=8F=B0=201h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/main.go | 2 +- internal/crypto/ethereum/rpc.go | 30 ++++++++++++++++++++++-------- quickstart.md | 2 +- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 0096e570..139957b8 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -41,6 +41,6 @@ func init() { root.Flags().BoolVarP(&config.App.System.PrintVersion, "version", "v", false, "Print the Unchained version number and die") root.PersistentFlags().StringVarP(&config.App.System.ConfigPath, "config", "c", "./conf.yaml", "Config file") root.PersistentFlags().StringVarP(&config.App.System.SecretsPath, "secrets", "s", "./secrets.yaml", "Secrets file") - root.PersistentFlags().BoolVarP(&config.App.System.AllowGenerateSecrets, "allow-generate-secrets", "g", false, "Allow to generate secrets file if not exists") + root.PersistentFlags().BoolVarP(&config.App.System.AllowGenerateSecrets, "allow-generate-secrets", "a", false, "Allow to generate secrets file if not exists") root.PersistentFlags().StringVarP(&config.App.System.ContextPath, "context", "x", "./context", "Context DB") } diff --git a/internal/crypto/ethereum/rpc.go b/internal/crypto/ethereum/rpc.go index a3bdf516..8b740f9d 100644 --- a/internal/crypto/ethereum/rpc.go +++ b/internal/crypto/ethereum/rpc.go @@ -32,7 +32,13 @@ type repository struct { } func (r *repository) GetClient(chain string) *ethclient.Client { - return r.clients[chain] + client, isExist := r.clients[chain] + if !isExist { + utils.Logger.With("Network", chain).Error("Client not found") + return nil + } + + return client } func (r *repository) refreshRPCWithRetries(network string, retries int) bool { @@ -71,7 +77,12 @@ func (r *repository) GetNewStakingContract(network string, address string, refre r.RefreshRPC(network) } - return contracts.NewUnchainedStaking(common.HexToAddress(address), r.clients[network]) + client := r.GetClient(network) + if client == nil { + return nil, consts.ErrClientNotFound + } + + return contracts.NewUnchainedStaking(common.HexToAddress(address), client) } func (r *repository) GetNewUniV3Contract(network string, address string, refresh bool) (*contracts.UniV3, error) { @@ -79,15 +90,18 @@ func (r *repository) GetNewUniV3Contract(network string, address string, refresh r.RefreshRPC(network) } - return contracts.NewUniV3(common.HexToAddress(address), r.clients[network]) + client := r.GetClient(network) + if client == nil { + return nil, consts.ErrClientNotFound + } + + return contracts.NewUniV3(common.HexToAddress(address), client) } // GetBlockNumber returns the most recent block number. func (r *repository) GetBlockNumber(ctx context.Context, network string) (uint64, error) { - client, ok := r.clients[network] - - if !ok { - utils.Logger.With("Network", network).Error("Client not found") + client := r.GetClient(network) + if client == nil { return 0, consts.ErrClientNotFound } @@ -98,7 +112,7 @@ func New() RPC { r := &repository{ list: map[string][]string{}, index: map[string]int{}, - clients: map[string]*ethclient.Client{}, + clients: make(map[string]*ethclient.Client), mutex: new(sync.Mutex), } diff --git a/quickstart.md b/quickstart.md index 046bd8f0..48f40bb8 100644 --- a/quickstart.md +++ b/quickstart.md @@ -267,7 +267,7 @@ where you saved the above configuration file: unchained.OS.ARCH worker ``` -**Note: If you are running the node for the first time, Unchained needs to have permission to generating a random secret key (You can pass this permission with -g flag) . This key will be saved to the `secrets.yaml` file and it is your responsibility to keep this file safe. If the app can't find the secret file location and doesn't have permission to generate it, it leads to panic and exits the app with an error ** +**Note: If you are running the node for the first time, Unchained needs to have permission to generating a random secret key (You can pass this permission with -a flag) . This key will be saved to the `secrets.yaml` file and it is your responsibility to keep this file safe. If the app can't find the secret file location and doesn't have permission to generate it, it leads to panic and exits the app with an error ** ## Help From 55ded35bff60d748dc427e0caede2a955117ebe2 Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Wed, 15 May 2024 14:34:23 +0330 Subject: [PATCH 13/29] =?UTF-8?q?=F0=9F=90=9B=20fix(eth-rpc):=20rename=20i?= =?UTF-8?q?sExist=20to=20isFound=20>>>=20=E2=8F=B0=202m?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/crypto/ethereum/rpc.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/crypto/ethereum/rpc.go b/internal/crypto/ethereum/rpc.go index 8b740f9d..f374a14b 100644 --- a/internal/crypto/ethereum/rpc.go +++ b/internal/crypto/ethereum/rpc.go @@ -32,8 +32,8 @@ type repository struct { } func (r *repository) GetClient(chain string) *ethclient.Client { - client, isExist := r.clients[chain] - if !isExist { + client, isFound := r.clients[chain] + if !isFound { utils.Logger.With("Network", chain).Error("Client not found") return nil } From e69fbb9b5f97dacf5117aaa5170abae28f84c43b Mon Sep 17 00:00:00 2001 From: Pouya Date: Mon, 3 Jun 2024 13:40:36 +0200 Subject: [PATCH 14/29] =?UTF-8?q?=E2=9C=A8=20feat:=20add=20the=20new=20sch?= =?UTF-8?q?norr=20based=20pos=20contract?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../crypto/ethereum/contracts/ProofOfStake.go | 1476 +++++++++ .../ethereum/contracts/UnchainedStaking.go | 2644 ----------------- internal/crypto/ethereum/rpc.go | 6 +- internal/crypto/ethereum/rpc_mock.go | 4 +- internal/service/correctness/correctness.go | 2 +- internal/service/evmlog/record.go | 2 +- internal/service/pos/eip712.go | 72 - internal/service/pos/eip712/sign.go | 84 +- internal/service/pos/pos.go | 46 +- internal/service/uniswap/record.go | 2 +- 10 files changed, 1531 insertions(+), 2807 deletions(-) create mode 100644 internal/crypto/ethereum/contracts/ProofOfStake.go delete mode 100644 internal/crypto/ethereum/contracts/UnchainedStaking.go diff --git a/internal/crypto/ethereum/contracts/ProofOfStake.go b/internal/crypto/ethereum/contracts/ProofOfStake.go new file mode 100644 index 00000000..5e622c3d --- /dev/null +++ b/internal/crypto/ethereum/contracts/ProofOfStake.go @@ -0,0 +1,1476 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contracts + +import ( + "errors" + "math/big" + "strings" + + 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" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ProofOfStakeStake is an auto generated low-level Go binding around an user-defined struct. +type ProofOfStakeStake struct { + Amount *big.Int + End *big.Int + Nfts []*big.Int + NftSum *big.Int +} + +// SchnorrNftTransferTransfer is an auto generated low-level Go binding around an user-defined struct. +type SchnorrNftTransferTransfer struct { + From common.Address + To common.Address + Id *big.Int + Nonce *big.Int +} + +// SchnorrSignatureSignature is an auto generated low-level Go binding around an user-defined struct. +type SchnorrSignatureSignature struct { + Rx *big.Int + S *big.Int +} + +// SchnorrTransferOwnershipTransferOwnership is an auto generated low-level Go binding around an user-defined struct. +type SchnorrTransferOwnershipTransferOwnership struct { + To *big.Int + Nonce *big.Int +} + +// SchnorrTransferTransfer is an auto generated low-level Go binding around an user-defined struct. +type SchnorrTransferTransfer struct { + From common.Address + To common.Address + Amount *big.Int + Nonce *big.Int +} + +// SetNftPricesNftPrices is an auto generated low-level Go binding around an user-defined struct. +type SetNftPricesNftPrices struct { + Nfts []*big.Int + Prices []*big.Int + Nonce *big.Int +} + +// SetSchnorrThresholdSchnorrThreshold is an auto generated low-level Go binding around an user-defined struct. +type SetSchnorrThresholdSchnorrThreshold struct { + Threshold *big.Int + Nonce *big.Int +} + +// ProofOfStakeMetaData contains all meta data concerning the ProofOfStake contract. +var ProofOfStakeMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"shcnorrOwner\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"stakingTokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyProcessed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyStaked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AmountZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DurationZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ElementAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ElementDoesNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"IndexOutOfBounds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSchorrSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"start\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"end\",\"type\":\"uint256\"}],\"name\":\"InvalidSlice\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NftNotInStake\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoStakeToExtend\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"end\",\"type\":\"uint256\"}],\"name\":\"Extended\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nfts\",\"type\":\"uint256[]\"}],\"name\":\"Increased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"end\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nfts\",\"type\":\"uint256[]\"}],\"name\":\"Staked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nfts\",\"type\":\"uint256[]\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"eip712DomainHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"}],\"name\":\"extendStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"getStake\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"end\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nfts\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"nftSum\",\"type\":\"uint256\"}],\"internalType\":\"structProofOfStake.Stake\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getValidators\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"start\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"end\",\"type\":\"uint256\"}],\"name\":\"getValidators\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nfts\",\"type\":\"uint256[]\"}],\"name\":\"increaseStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"nftPrices\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nftToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"processed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"eip712Hash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"rx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"}],\"internalType\":\"structSchnorrSignature.Signature\",\"name\":\"schnorrSignature\",\"type\":\"tuple\"}],\"name\":\"safeVerify\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"schnorrParticipationThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256[]\",\"name\":\"nfts\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"prices\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structSetNftPrices.NftPrices\",\"name\":\"prices\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"rx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"}],\"internalType\":\"structSchnorrSignature.Signature\",\"name\":\"schnorrSignature\",\"type\":\"tuple\"}],\"name\":\"setNftPrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structSetSchnorrThreshold.SchnorrThreshold\",\"name\":\"threshold\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"rx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"}],\"internalType\":\"structSchnorrSignature.Signature\",\"name\":\"schnorrSignature\",\"type\":\"tuple\"}],\"name\":\"setSchNorrParticipationThreshold\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nfts\",\"type\":\"uint256[]\"}],\"name\":\"stake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"stakes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"end\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftSum\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakingToken\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structSchnorrTransfer.Transfer\",\"name\":\"txn\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"rx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"}],\"internalType\":\"structSchnorrSignature.Signature\",\"name\":\"schnorrSignature\",\"type\":\"tuple\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structSchnorrNftTransfer.Transfer\",\"name\":\"txn\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"rx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"}],\"internalType\":\"structSchnorrSignature.Signature\",\"name\":\"schnorrSignature\",\"type\":\"tuple\"}],\"name\":\"transferNft\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"to\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structSchnorrTransferOwnership.TransferOwnership\",\"name\":\"txn\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"rx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"}],\"internalType\":\"structSchnorrSignature.Signature\",\"name\":\"schnorrSignature\",\"type\":\"tuple\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256[]\",\"name\":\"nfts\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"prices\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structSetNftPrices.NftPrices\",\"name\":\"prices\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"rx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"}],\"internalType\":\"structSchnorrSignature.Signature\",\"name\":\"schnorrSignature\",\"type\":\"tuple\"}],\"name\":\"verifySetNftPrice\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structSetSchnorrThreshold.SchnorrThreshold\",\"name\":\"threshold\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"rx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"}],\"internalType\":\"structSchnorrSignature.Signature\",\"name\":\"schnorrSignature\",\"type\":\"tuple\"}],\"name\":\"verifySetSchnorrThreshold\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structSchnorrTransfer.Transfer\",\"name\":\"txn\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"rx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"}],\"internalType\":\"structSchnorrSignature.Signature\",\"name\":\"schnorrSignature\",\"type\":\"tuple\"}],\"name\":\"verifyTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structSchnorrNftTransfer.Transfer\",\"name\":\"txn\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"rx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"}],\"internalType\":\"structSchnorrSignature.Signature\",\"name\":\"schnorrSignature\",\"type\":\"tuple\"}],\"name\":\"verifyTransferNft\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + +// ProofOfStakeABI is the input ABI used to generate the binding from. +// Deprecated: Use ProofOfStakeMetaData.ABI instead. +var ProofOfStakeABI = ProofOfStakeMetaData.ABI + +// ProofOfStake is an auto generated Go binding around an Ethereum contract. +type ProofOfStake struct { + ProofOfStakeCaller // Read-only binding to the contract + ProofOfStakeTransactor // Write-only binding to the contract + ProofOfStakeFilterer // Log filterer for contract events +} + +// ProofOfStakeCaller is an auto generated read-only Go binding around an Ethereum contract. +type ProofOfStakeCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ProofOfStakeTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ProofOfStakeTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ProofOfStakeFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ProofOfStakeFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ProofOfStakeSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ProofOfStakeSession struct { + Contract *ProofOfStake // 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 +} + +// ProofOfStakeCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ProofOfStakeCallerSession struct { + Contract *ProofOfStakeCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ProofOfStakeTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ProofOfStakeTransactorSession struct { + Contract *ProofOfStakeTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ProofOfStakeRaw is an auto generated low-level Go binding around an Ethereum contract. +type ProofOfStakeRaw struct { + Contract *ProofOfStake // Generic contract binding to access the raw methods on +} + +// ProofOfStakeCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ProofOfStakeCallerRaw struct { + Contract *ProofOfStakeCaller // Generic read-only contract binding to access the raw methods on +} + +// ProofOfStakeTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ProofOfStakeTransactorRaw struct { + Contract *ProofOfStakeTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewProofOfStake creates a new instance of ProofOfStake, bound to a specific deployed contract. +func NewProofOfStake(address common.Address, backend bind.ContractBackend) (*ProofOfStake, error) { + contract, err := bindProofOfStake(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ProofOfStake{ProofOfStakeCaller: ProofOfStakeCaller{contract: contract}, ProofOfStakeTransactor: ProofOfStakeTransactor{contract: contract}, ProofOfStakeFilterer: ProofOfStakeFilterer{contract: contract}}, nil +} + +// NewProofOfStakeCaller creates a new read-only instance of ProofOfStake, bound to a specific deployed contract. +func NewProofOfStakeCaller(address common.Address, caller bind.ContractCaller) (*ProofOfStakeCaller, error) { + contract, err := bindProofOfStake(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ProofOfStakeCaller{contract: contract}, nil +} + +// NewProofOfStakeTransactor creates a new write-only instance of ProofOfStake, bound to a specific deployed contract. +func NewProofOfStakeTransactor(address common.Address, transactor bind.ContractTransactor) (*ProofOfStakeTransactor, error) { + contract, err := bindProofOfStake(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ProofOfStakeTransactor{contract: contract}, nil +} + +// NewProofOfStakeFilterer creates a new log filterer instance of ProofOfStake, bound to a specific deployed contract. +func NewProofOfStakeFilterer(address common.Address, filterer bind.ContractFilterer) (*ProofOfStakeFilterer, error) { + contract, err := bindProofOfStake(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ProofOfStakeFilterer{contract: contract}, nil +} + +// bindProofOfStake binds a generic wrapper to an already deployed contract. +func bindProofOfStake(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ProofOfStakeMetaData.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 (_ProofOfStake *ProofOfStakeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ProofOfStake.Contract.ProofOfStakeCaller.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 (_ProofOfStake *ProofOfStakeRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ProofOfStake.Contract.ProofOfStakeTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ProofOfStake *ProofOfStakeRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ProofOfStake.Contract.ProofOfStakeTransactor.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 (_ProofOfStake *ProofOfStakeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ProofOfStake.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 (_ProofOfStake *ProofOfStakeTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ProofOfStake.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ProofOfStake *ProofOfStakeTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ProofOfStake.Contract.contract.Transact(opts, method, params...) +} + +// Eip712DomainHash is a free data retrieval call binding the contract method 0xf94dc4bc. +// +// Solidity: function eip712DomainHash() view returns(bytes32) +func (_ProofOfStake *ProofOfStakeCaller) Eip712DomainHash(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ProofOfStake.contract.Call(opts, &out, "eip712DomainHash") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// Eip712DomainHash is a free data retrieval call binding the contract method 0xf94dc4bc. +// +// Solidity: function eip712DomainHash() view returns(bytes32) +func (_ProofOfStake *ProofOfStakeSession) Eip712DomainHash() ([32]byte, error) { + return _ProofOfStake.Contract.Eip712DomainHash(&_ProofOfStake.CallOpts) +} + +// Eip712DomainHash is a free data retrieval call binding the contract method 0xf94dc4bc. +// +// Solidity: function eip712DomainHash() view returns(bytes32) +func (_ProofOfStake *ProofOfStakeCallerSession) Eip712DomainHash() ([32]byte, error) { + return _ProofOfStake.Contract.Eip712DomainHash(&_ProofOfStake.CallOpts) +} + +// GetStake is a free data retrieval call binding the contract method 0x7a766460. +// +// Solidity: function getStake(address user) view returns((uint256,uint256,uint256[],uint256)) +func (_ProofOfStake *ProofOfStakeCaller) GetStake(opts *bind.CallOpts, user common.Address) (ProofOfStakeStake, error) { + var out []interface{} + err := _ProofOfStake.contract.Call(opts, &out, "getStake", user) + + if err != nil { + return *new(ProofOfStakeStake), err + } + + out0 := *abi.ConvertType(out[0], new(ProofOfStakeStake)).(*ProofOfStakeStake) + + return out0, err + +} + +// GetStake is a free data retrieval call binding the contract method 0x7a766460. +// +// Solidity: function getStake(address user) view returns((uint256,uint256,uint256[],uint256)) +func (_ProofOfStake *ProofOfStakeSession) GetStake(user common.Address) (ProofOfStakeStake, error) { + return _ProofOfStake.Contract.GetStake(&_ProofOfStake.CallOpts, user) +} + +// GetStake is a free data retrieval call binding the contract method 0x7a766460. +// +// Solidity: function getStake(address user) view returns((uint256,uint256,uint256[],uint256)) +func (_ProofOfStake *ProofOfStakeCallerSession) GetStake(user common.Address) (ProofOfStakeStake, error) { + return _ProofOfStake.Contract.GetStake(&_ProofOfStake.CallOpts, user) +} + +// GetValidators is a free data retrieval call binding the contract method 0xb7ab4db5. +// +// Solidity: function getValidators() view returns(address[]) +func (_ProofOfStake *ProofOfStakeCaller) GetValidators(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _ProofOfStake.contract.Call(opts, &out, "getValidators") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// GetValidators is a free data retrieval call binding the contract method 0xb7ab4db5. +// +// Solidity: function getValidators() view returns(address[]) +func (_ProofOfStake *ProofOfStakeSession) GetValidators() ([]common.Address, error) { + return _ProofOfStake.Contract.GetValidators(&_ProofOfStake.CallOpts) +} + +// GetValidators is a free data retrieval call binding the contract method 0xb7ab4db5. +// +// Solidity: function getValidators() view returns(address[]) +func (_ProofOfStake *ProofOfStakeCallerSession) GetValidators() ([]common.Address, error) { + return _ProofOfStake.Contract.GetValidators(&_ProofOfStake.CallOpts) +} + +// GetValidators0 is a free data retrieval call binding the contract method 0xbff02e20. +// +// Solidity: function getValidators(uint256 start, uint256 end) view returns(address[]) +func (_ProofOfStake *ProofOfStakeCaller) GetValidators0(opts *bind.CallOpts, start *big.Int, end *big.Int) ([]common.Address, error) { + var out []interface{} + err := _ProofOfStake.contract.Call(opts, &out, "getValidators0", start, end) + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// GetValidators0 is a free data retrieval call binding the contract method 0xbff02e20. +// +// Solidity: function getValidators(uint256 start, uint256 end) view returns(address[]) +func (_ProofOfStake *ProofOfStakeSession) GetValidators0(start *big.Int, end *big.Int) ([]common.Address, error) { + return _ProofOfStake.Contract.GetValidators0(&_ProofOfStake.CallOpts, start, end) +} + +// GetValidators0 is a free data retrieval call binding the contract method 0xbff02e20. +// +// Solidity: function getValidators(uint256 start, uint256 end) view returns(address[]) +func (_ProofOfStake *ProofOfStakeCallerSession) GetValidators0(start *big.Int, end *big.Int) ([]common.Address, error) { + return _ProofOfStake.Contract.GetValidators0(&_ProofOfStake.CallOpts, start, end) +} + +// NftPrices is a free data retrieval call binding the contract method 0xd9f10a2b. +// +// Solidity: function nftPrices(uint256 ) view returns(uint256) +func (_ProofOfStake *ProofOfStakeCaller) NftPrices(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _ProofOfStake.contract.Call(opts, &out, "nftPrices", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// NftPrices is a free data retrieval call binding the contract method 0xd9f10a2b. +// +// Solidity: function nftPrices(uint256 ) view returns(uint256) +func (_ProofOfStake *ProofOfStakeSession) NftPrices(arg0 *big.Int) (*big.Int, error) { + return _ProofOfStake.Contract.NftPrices(&_ProofOfStake.CallOpts, arg0) +} + +// NftPrices is a free data retrieval call binding the contract method 0xd9f10a2b. +// +// Solidity: function nftPrices(uint256 ) view returns(uint256) +func (_ProofOfStake *ProofOfStakeCallerSession) NftPrices(arg0 *big.Int) (*big.Int, error) { + return _ProofOfStake.Contract.NftPrices(&_ProofOfStake.CallOpts, arg0) +} + +// NftToken is a free data retrieval call binding the contract method 0xd06fcba8. +// +// Solidity: function nftToken() view returns(address) +func (_ProofOfStake *ProofOfStakeCaller) NftToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ProofOfStake.contract.Call(opts, &out, "nftToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// NftToken is a free data retrieval call binding the contract method 0xd06fcba8. +// +// Solidity: function nftToken() view returns(address) +func (_ProofOfStake *ProofOfStakeSession) NftToken() (common.Address, error) { + return _ProofOfStake.Contract.NftToken(&_ProofOfStake.CallOpts) +} + +// NftToken is a free data retrieval call binding the contract method 0xd06fcba8. +// +// Solidity: function nftToken() view returns(address) +func (_ProofOfStake *ProofOfStakeCallerSession) NftToken() (common.Address, error) { + return _ProofOfStake.Contract.NftToken(&_ProofOfStake.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(uint256) +func (_ProofOfStake *ProofOfStakeCaller) Owner(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ProofOfStake.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(uint256) +func (_ProofOfStake *ProofOfStakeSession) Owner() (*big.Int, error) { + return _ProofOfStake.Contract.Owner(&_ProofOfStake.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(uint256) +func (_ProofOfStake *ProofOfStakeCallerSession) Owner() (*big.Int, error) { + return _ProofOfStake.Contract.Owner(&_ProofOfStake.CallOpts) +} + +// Processed is a free data retrieval call binding the contract method 0xc1f0808a. +// +// Solidity: function processed(bytes32 ) view returns(bool) +func (_ProofOfStake *ProofOfStakeCaller) Processed(opts *bind.CallOpts, arg0 [32]byte) (bool, error) { + var out []interface{} + err := _ProofOfStake.contract.Call(opts, &out, "processed", arg0) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Processed is a free data retrieval call binding the contract method 0xc1f0808a. +// +// Solidity: function processed(bytes32 ) view returns(bool) +func (_ProofOfStake *ProofOfStakeSession) Processed(arg0 [32]byte) (bool, error) { + return _ProofOfStake.Contract.Processed(&_ProofOfStake.CallOpts, arg0) +} + +// Processed is a free data retrieval call binding the contract method 0xc1f0808a. +// +// Solidity: function processed(bytes32 ) view returns(bool) +func (_ProofOfStake *ProofOfStakeCallerSession) Processed(arg0 [32]byte) (bool, error) { + return _ProofOfStake.Contract.Processed(&_ProofOfStake.CallOpts, arg0) +} + +// SafeVerify is a free data retrieval call binding the contract method 0xac4185e8. +// +// Solidity: function safeVerify(bytes32 eip712Hash, (uint256,uint256) schnorrSignature) view returns() +func (_ProofOfStake *ProofOfStakeCaller) SafeVerify(opts *bind.CallOpts, eip712Hash [32]byte, schnorrSignature SchnorrSignatureSignature) error { + var out []interface{} + err := _ProofOfStake.contract.Call(opts, &out, "safeVerify", eip712Hash, schnorrSignature) + + if err != nil { + return err + } + + return err + +} + +// SafeVerify is a free data retrieval call binding the contract method 0xac4185e8. +// +// Solidity: function safeVerify(bytes32 eip712Hash, (uint256,uint256) schnorrSignature) view returns() +func (_ProofOfStake *ProofOfStakeSession) SafeVerify(eip712Hash [32]byte, schnorrSignature SchnorrSignatureSignature) error { + return _ProofOfStake.Contract.SafeVerify(&_ProofOfStake.CallOpts, eip712Hash, schnorrSignature) +} + +// SafeVerify is a free data retrieval call binding the contract method 0xac4185e8. +// +// Solidity: function safeVerify(bytes32 eip712Hash, (uint256,uint256) schnorrSignature) view returns() +func (_ProofOfStake *ProofOfStakeCallerSession) SafeVerify(eip712Hash [32]byte, schnorrSignature SchnorrSignatureSignature) error { + return _ProofOfStake.Contract.SafeVerify(&_ProofOfStake.CallOpts, eip712Hash, schnorrSignature) +} + +// SchnorrParticipationThreshold is a free data retrieval call binding the contract method 0x82e51aca. +// +// Solidity: function schnorrParticipationThreshold() view returns(uint256) +func (_ProofOfStake *ProofOfStakeCaller) SchnorrParticipationThreshold(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ProofOfStake.contract.Call(opts, &out, "schnorrParticipationThreshold") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// SchnorrParticipationThreshold is a free data retrieval call binding the contract method 0x82e51aca. +// +// Solidity: function schnorrParticipationThreshold() view returns(uint256) +func (_ProofOfStake *ProofOfStakeSession) SchnorrParticipationThreshold() (*big.Int, error) { + return _ProofOfStake.Contract.SchnorrParticipationThreshold(&_ProofOfStake.CallOpts) +} + +// SchnorrParticipationThreshold is a free data retrieval call binding the contract method 0x82e51aca. +// +// Solidity: function schnorrParticipationThreshold() view returns(uint256) +func (_ProofOfStake *ProofOfStakeCallerSession) SchnorrParticipationThreshold() (*big.Int, error) { + return _ProofOfStake.Contract.SchnorrParticipationThreshold(&_ProofOfStake.CallOpts) +} + +// Stakes is a free data retrieval call binding the contract method 0x16934fc4. +// +// Solidity: function stakes(address ) view returns(uint256 amount, uint256 end, uint256 nftSum) +func (_ProofOfStake *ProofOfStakeCaller) Stakes(opts *bind.CallOpts, arg0 common.Address) (struct { + Amount *big.Int + End *big.Int + NftSum *big.Int +}, error) { + var out []interface{} + err := _ProofOfStake.contract.Call(opts, &out, "stakes", arg0) + + outstruct := new(struct { + Amount *big.Int + End *big.Int + NftSum *big.Int + }) + if err != nil { + return *outstruct, err + } + + outstruct.Amount = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.End = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.NftSum = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +// Stakes is a free data retrieval call binding the contract method 0x16934fc4. +// +// Solidity: function stakes(address ) view returns(uint256 amount, uint256 end, uint256 nftSum) +func (_ProofOfStake *ProofOfStakeSession) Stakes(arg0 common.Address) (struct { + Amount *big.Int + End *big.Int + NftSum *big.Int +}, error) { + return _ProofOfStake.Contract.Stakes(&_ProofOfStake.CallOpts, arg0) +} + +// Stakes is a free data retrieval call binding the contract method 0x16934fc4. +// +// Solidity: function stakes(address ) view returns(uint256 amount, uint256 end, uint256 nftSum) +func (_ProofOfStake *ProofOfStakeCallerSession) Stakes(arg0 common.Address) (struct { + Amount *big.Int + End *big.Int + NftSum *big.Int +}, error) { + return _ProofOfStake.Contract.Stakes(&_ProofOfStake.CallOpts, arg0) +} + +// StakingToken is a free data retrieval call binding the contract method 0x72f702f3. +// +// Solidity: function stakingToken() view returns(address) +func (_ProofOfStake *ProofOfStakeCaller) StakingToken(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ProofOfStake.contract.Call(opts, &out, "stakingToken") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// StakingToken is a free data retrieval call binding the contract method 0x72f702f3. +// +// Solidity: function stakingToken() view returns(address) +func (_ProofOfStake *ProofOfStakeSession) StakingToken() (common.Address, error) { + return _ProofOfStake.Contract.StakingToken(&_ProofOfStake.CallOpts) +} + +// StakingToken is a free data retrieval call binding the contract method 0x72f702f3. +// +// Solidity: function stakingToken() view returns(address) +func (_ProofOfStake *ProofOfStakeCallerSession) StakingToken() (common.Address, error) { + return _ProofOfStake.Contract.StakingToken(&_ProofOfStake.CallOpts) +} + +// ExtendStake is a paid mutator transaction binding the contract method 0x7e49627d. +// +// Solidity: function extendStake(uint256 duration) returns() +func (_ProofOfStake *ProofOfStakeTransactor) ExtendStake(opts *bind.TransactOpts, duration *big.Int) (*types.Transaction, error) { + return _ProofOfStake.contract.Transact(opts, "extendStake", duration) +} + +// ExtendStake is a paid mutator transaction binding the contract method 0x7e49627d. +// +// Solidity: function extendStake(uint256 duration) returns() +func (_ProofOfStake *ProofOfStakeSession) ExtendStake(duration *big.Int) (*types.Transaction, error) { + return _ProofOfStake.Contract.ExtendStake(&_ProofOfStake.TransactOpts, duration) +} + +// ExtendStake is a paid mutator transaction binding the contract method 0x7e49627d. +// +// Solidity: function extendStake(uint256 duration) returns() +func (_ProofOfStake *ProofOfStakeTransactorSession) ExtendStake(duration *big.Int) (*types.Transaction, error) { + return _ProofOfStake.Contract.ExtendStake(&_ProofOfStake.TransactOpts, duration) +} + +// IncreaseStake is a paid mutator transaction binding the contract method 0x0062ad9d. +// +// Solidity: function increaseStake(uint256 amount, uint256[] nfts) returns() +func (_ProofOfStake *ProofOfStakeTransactor) IncreaseStake(opts *bind.TransactOpts, amount *big.Int, nfts []*big.Int) (*types.Transaction, error) { + return _ProofOfStake.contract.Transact(opts, "increaseStake", amount, nfts) +} + +// IncreaseStake is a paid mutator transaction binding the contract method 0x0062ad9d. +// +// Solidity: function increaseStake(uint256 amount, uint256[] nfts) returns() +func (_ProofOfStake *ProofOfStakeSession) IncreaseStake(amount *big.Int, nfts []*big.Int) (*types.Transaction, error) { + return _ProofOfStake.Contract.IncreaseStake(&_ProofOfStake.TransactOpts, amount, nfts) +} + +// IncreaseStake is a paid mutator transaction binding the contract method 0x0062ad9d. +// +// Solidity: function increaseStake(uint256 amount, uint256[] nfts) returns() +func (_ProofOfStake *ProofOfStakeTransactorSession) IncreaseStake(amount *big.Int, nfts []*big.Int) (*types.Transaction, error) { + return _ProofOfStake.Contract.IncreaseStake(&_ProofOfStake.TransactOpts, amount, nfts) +} + +// SetNftPrices is a paid mutator transaction binding the contract method 0x556935eb. +// +// Solidity: function setNftPrices((uint256[],uint256[],uint256) prices, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactor) SetNftPrices(opts *bind.TransactOpts, prices SetNftPricesNftPrices, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.contract.Transact(opts, "setNftPrices", prices, schnorrSignature) +} + +// SetNftPrices is a paid mutator transaction binding the contract method 0x556935eb. +// +// Solidity: function setNftPrices((uint256[],uint256[],uint256) prices, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeSession) SetNftPrices(prices SetNftPricesNftPrices, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.SetNftPrices(&_ProofOfStake.TransactOpts, prices, schnorrSignature) +} + +// SetNftPrices is a paid mutator transaction binding the contract method 0x556935eb. +// +// Solidity: function setNftPrices((uint256[],uint256[],uint256) prices, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactorSession) SetNftPrices(prices SetNftPricesNftPrices, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.SetNftPrices(&_ProofOfStake.TransactOpts, prices, schnorrSignature) +} + +// SetSchNorrParticipationThreshold is a paid mutator transaction binding the contract method 0x41bd25f5. +// +// Solidity: function setSchNorrParticipationThreshold((uint256,uint256) threshold, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactor) SetSchNorrParticipationThreshold(opts *bind.TransactOpts, threshold SetSchnorrThresholdSchnorrThreshold, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.contract.Transact(opts, "setSchNorrParticipationThreshold", threshold, schnorrSignature) +} + +// SetSchNorrParticipationThreshold is a paid mutator transaction binding the contract method 0x41bd25f5. +// +// Solidity: function setSchNorrParticipationThreshold((uint256,uint256) threshold, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeSession) SetSchNorrParticipationThreshold(threshold SetSchnorrThresholdSchnorrThreshold, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.SetSchNorrParticipationThreshold(&_ProofOfStake.TransactOpts, threshold, schnorrSignature) +} + +// SetSchNorrParticipationThreshold is a paid mutator transaction binding the contract method 0x41bd25f5. +// +// Solidity: function setSchNorrParticipationThreshold((uint256,uint256) threshold, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactorSession) SetSchNorrParticipationThreshold(threshold SetSchnorrThresholdSchnorrThreshold, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.SetSchNorrParticipationThreshold(&_ProofOfStake.TransactOpts, threshold, schnorrSignature) +} + +// Stake is a paid mutator transaction binding the contract method 0x9debdddc. +// +// Solidity: function stake(uint256 amount, uint256 duration, uint256[] nfts) returns() +func (_ProofOfStake *ProofOfStakeTransactor) Stake(opts *bind.TransactOpts, amount *big.Int, duration *big.Int, nfts []*big.Int) (*types.Transaction, error) { + return _ProofOfStake.contract.Transact(opts, "stake", amount, duration, nfts) +} + +// Stake is a paid mutator transaction binding the contract method 0x9debdddc. +// +// Solidity: function stake(uint256 amount, uint256 duration, uint256[] nfts) returns() +func (_ProofOfStake *ProofOfStakeSession) Stake(amount *big.Int, duration *big.Int, nfts []*big.Int) (*types.Transaction, error) { + return _ProofOfStake.Contract.Stake(&_ProofOfStake.TransactOpts, amount, duration, nfts) +} + +// Stake is a paid mutator transaction binding the contract method 0x9debdddc. +// +// Solidity: function stake(uint256 amount, uint256 duration, uint256[] nfts) returns() +func (_ProofOfStake *ProofOfStakeTransactorSession) Stake(amount *big.Int, duration *big.Int, nfts []*big.Int) (*types.Transaction, error) { + return _ProofOfStake.Contract.Stake(&_ProofOfStake.TransactOpts, amount, duration, nfts) +} + +// Transfer is a paid mutator transaction binding the contract method 0x423ae347. +// +// Solidity: function transfer((address,address,uint256,uint256) txn, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactor) Transfer(opts *bind.TransactOpts, txn SchnorrTransferTransfer, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.contract.Transact(opts, "transfer", txn, schnorrSignature) +} + +// Transfer is a paid mutator transaction binding the contract method 0x423ae347. +// +// Solidity: function transfer((address,address,uint256,uint256) txn, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeSession) Transfer(txn SchnorrTransferTransfer, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.Transfer(&_ProofOfStake.TransactOpts, txn, schnorrSignature) +} + +// Transfer is a paid mutator transaction binding the contract method 0x423ae347. +// +// Solidity: function transfer((address,address,uint256,uint256) txn, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactorSession) Transfer(txn SchnorrTransferTransfer, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.Transfer(&_ProofOfStake.TransactOpts, txn, schnorrSignature) +} + +// TransferNft is a paid mutator transaction binding the contract method 0x9571efb9. +// +// Solidity: function transferNft((address,address,uint256,uint256) txn, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactor) TransferNft(opts *bind.TransactOpts, txn SchnorrNftTransferTransfer, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.contract.Transact(opts, "transferNft", txn, schnorrSignature) +} + +// TransferNft is a paid mutator transaction binding the contract method 0x9571efb9. +// +// Solidity: function transferNft((address,address,uint256,uint256) txn, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeSession) TransferNft(txn SchnorrNftTransferTransfer, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.TransferNft(&_ProofOfStake.TransactOpts, txn, schnorrSignature) +} + +// TransferNft is a paid mutator transaction binding the contract method 0x9571efb9. +// +// Solidity: function transferNft((address,address,uint256,uint256) txn, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactorSession) TransferNft(txn SchnorrNftTransferTransfer, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.TransferNft(&_ProofOfStake.TransactOpts, txn, schnorrSignature) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0x7b8d534c. +// +// Solidity: function transferOwnership((uint256,uint256) txn, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactor) TransferOwnership(opts *bind.TransactOpts, txn SchnorrTransferOwnershipTransferOwnership, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.contract.Transact(opts, "transferOwnership", txn, schnorrSignature) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0x7b8d534c. +// +// Solidity: function transferOwnership((uint256,uint256) txn, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeSession) TransferOwnership(txn SchnorrTransferOwnershipTransferOwnership, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.TransferOwnership(&_ProofOfStake.TransactOpts, txn, schnorrSignature) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0x7b8d534c. +// +// Solidity: function transferOwnership((uint256,uint256) txn, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactorSession) TransferOwnership(txn SchnorrTransferOwnershipTransferOwnership, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.TransferOwnership(&_ProofOfStake.TransactOpts, txn, schnorrSignature) +} + +// VerifySetNftPrice is a paid mutator transaction binding the contract method 0xecefbdbe. +// +// Solidity: function verifySetNftPrice((uint256[],uint256[],uint256) prices, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactor) VerifySetNftPrice(opts *bind.TransactOpts, prices SetNftPricesNftPrices, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.contract.Transact(opts, "verifySetNftPrice", prices, schnorrSignature) +} + +// VerifySetNftPrice is a paid mutator transaction binding the contract method 0xecefbdbe. +// +// Solidity: function verifySetNftPrice((uint256[],uint256[],uint256) prices, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeSession) VerifySetNftPrice(prices SetNftPricesNftPrices, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.VerifySetNftPrice(&_ProofOfStake.TransactOpts, prices, schnorrSignature) +} + +// VerifySetNftPrice is a paid mutator transaction binding the contract method 0xecefbdbe. +// +// Solidity: function verifySetNftPrice((uint256[],uint256[],uint256) prices, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactorSession) VerifySetNftPrice(prices SetNftPricesNftPrices, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.VerifySetNftPrice(&_ProofOfStake.TransactOpts, prices, schnorrSignature) +} + +// VerifySetSchnorrThreshold is a paid mutator transaction binding the contract method 0x9a1bc8b8. +// +// Solidity: function verifySetSchnorrThreshold((uint256,uint256) threshold, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactor) VerifySetSchnorrThreshold(opts *bind.TransactOpts, threshold SetSchnorrThresholdSchnorrThreshold, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.contract.Transact(opts, "verifySetSchnorrThreshold", threshold, schnorrSignature) +} + +// VerifySetSchnorrThreshold is a paid mutator transaction binding the contract method 0x9a1bc8b8. +// +// Solidity: function verifySetSchnorrThreshold((uint256,uint256) threshold, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeSession) VerifySetSchnorrThreshold(threshold SetSchnorrThresholdSchnorrThreshold, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.VerifySetSchnorrThreshold(&_ProofOfStake.TransactOpts, threshold, schnorrSignature) +} + +// VerifySetSchnorrThreshold is a paid mutator transaction binding the contract method 0x9a1bc8b8. +// +// Solidity: function verifySetSchnorrThreshold((uint256,uint256) threshold, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactorSession) VerifySetSchnorrThreshold(threshold SetSchnorrThresholdSchnorrThreshold, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.VerifySetSchnorrThreshold(&_ProofOfStake.TransactOpts, threshold, schnorrSignature) +} + +// VerifyTransfer is a paid mutator transaction binding the contract method 0x69e1f231. +// +// Solidity: function verifyTransfer((address,address,uint256,uint256) txn, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactor) VerifyTransfer(opts *bind.TransactOpts, txn SchnorrTransferTransfer, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.contract.Transact(opts, "verifyTransfer", txn, schnorrSignature) +} + +// VerifyTransfer is a paid mutator transaction binding the contract method 0x69e1f231. +// +// Solidity: function verifyTransfer((address,address,uint256,uint256) txn, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeSession) VerifyTransfer(txn SchnorrTransferTransfer, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.VerifyTransfer(&_ProofOfStake.TransactOpts, txn, schnorrSignature) +} + +// VerifyTransfer is a paid mutator transaction binding the contract method 0x69e1f231. +// +// Solidity: function verifyTransfer((address,address,uint256,uint256) txn, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactorSession) VerifyTransfer(txn SchnorrTransferTransfer, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.VerifyTransfer(&_ProofOfStake.TransactOpts, txn, schnorrSignature) +} + +// VerifyTransferNft is a paid mutator transaction binding the contract method 0x65951984. +// +// Solidity: function verifyTransferNft((address,address,uint256,uint256) txn, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactor) VerifyTransferNft(opts *bind.TransactOpts, txn SchnorrNftTransferTransfer, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.contract.Transact(opts, "verifyTransferNft", txn, schnorrSignature) +} + +// VerifyTransferNft is a paid mutator transaction binding the contract method 0x65951984. +// +// Solidity: function verifyTransferNft((address,address,uint256,uint256) txn, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeSession) VerifyTransferNft(txn SchnorrNftTransferTransfer, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.VerifyTransferNft(&_ProofOfStake.TransactOpts, txn, schnorrSignature) +} + +// VerifyTransferNft is a paid mutator transaction binding the contract method 0x65951984. +// +// Solidity: function verifyTransferNft((address,address,uint256,uint256) txn, (uint256,uint256) schnorrSignature) returns() +func (_ProofOfStake *ProofOfStakeTransactorSession) VerifyTransferNft(txn SchnorrNftTransferTransfer, schnorrSignature SchnorrSignatureSignature) (*types.Transaction, error) { + return _ProofOfStake.Contract.VerifyTransferNft(&_ProofOfStake.TransactOpts, txn, schnorrSignature) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x3ccfd60b. +// +// Solidity: function withdraw() returns() +func (_ProofOfStake *ProofOfStakeTransactor) Withdraw(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ProofOfStake.contract.Transact(opts, "withdraw") +} + +// Withdraw is a paid mutator transaction binding the contract method 0x3ccfd60b. +// +// Solidity: function withdraw() returns() +func (_ProofOfStake *ProofOfStakeSession) Withdraw() (*types.Transaction, error) { + return _ProofOfStake.Contract.Withdraw(&_ProofOfStake.TransactOpts) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x3ccfd60b. +// +// Solidity: function withdraw() returns() +func (_ProofOfStake *ProofOfStakeTransactorSession) Withdraw() (*types.Transaction, error) { + return _ProofOfStake.Contract.Withdraw(&_ProofOfStake.TransactOpts) +} + +// ProofOfStakeExtendedIterator is returned from FilterExtended and is used to iterate over the raw logs and unpacked data for Extended events raised by the ProofOfStake contract. +type ProofOfStakeExtendedIterator struct { + Event *ProofOfStakeExtended // 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 *ProofOfStakeExtendedIterator) 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(ProofOfStakeExtended) + 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(ProofOfStakeExtended) + 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 *ProofOfStakeExtendedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ProofOfStakeExtendedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ProofOfStakeExtended represents a Extended event raised by the ProofOfStake contract. +type ProofOfStakeExtended struct { + User common.Address + End *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExtended is a free log retrieval operation binding the contract event 0xa29fc12cda82ff659de006abb10fa5ee256d922af1661e395e5f2fb6b004387e. +// +// Solidity: event Extended(address indexed user, uint256 end) +func (_ProofOfStake *ProofOfStakeFilterer) FilterExtended(opts *bind.FilterOpts, user []common.Address) (*ProofOfStakeExtendedIterator, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _ProofOfStake.contract.FilterLogs(opts, "Extended", userRule) + if err != nil { + return nil, err + } + return &ProofOfStakeExtendedIterator{contract: _ProofOfStake.contract, event: "Extended", logs: logs, sub: sub}, nil +} + +// WatchExtended is a free log subscription operation binding the contract event 0xa29fc12cda82ff659de006abb10fa5ee256d922af1661e395e5f2fb6b004387e. +// +// Solidity: event Extended(address indexed user, uint256 end) +func (_ProofOfStake *ProofOfStakeFilterer) WatchExtended(opts *bind.WatchOpts, sink chan<- *ProofOfStakeExtended, user []common.Address) (event.Subscription, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _ProofOfStake.contract.WatchLogs(opts, "Extended", userRule) + 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(ProofOfStakeExtended) + if err := _ProofOfStake.contract.UnpackLog(event, "Extended", 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 +} + +// ParseExtended is a log parse operation binding the contract event 0xa29fc12cda82ff659de006abb10fa5ee256d922af1661e395e5f2fb6b004387e. +// +// Solidity: event Extended(address indexed user, uint256 end) +func (_ProofOfStake *ProofOfStakeFilterer) ParseExtended(log types.Log) (*ProofOfStakeExtended, error) { + event := new(ProofOfStakeExtended) + if err := _ProofOfStake.contract.UnpackLog(event, "Extended", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ProofOfStakeIncreasedIterator is returned from FilterIncreased and is used to iterate over the raw logs and unpacked data for Increased events raised by the ProofOfStake contract. +type ProofOfStakeIncreasedIterator struct { + Event *ProofOfStakeIncreased // 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 *ProofOfStakeIncreasedIterator) 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(ProofOfStakeIncreased) + 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(ProofOfStakeIncreased) + 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 *ProofOfStakeIncreasedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ProofOfStakeIncreasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ProofOfStakeIncreased represents a Increased event raised by the ProofOfStake contract. +type ProofOfStakeIncreased struct { + User common.Address + Amount *big.Int + Nfts []*big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterIncreased is a free log retrieval operation binding the contract event 0x2db19fadbf40ed77512048f708e78f52f7727cc5af099c414320de1c2137aa88. +// +// Solidity: event Increased(address indexed user, uint256 amount, uint256[] nfts) +func (_ProofOfStake *ProofOfStakeFilterer) FilterIncreased(opts *bind.FilterOpts, user []common.Address) (*ProofOfStakeIncreasedIterator, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _ProofOfStake.contract.FilterLogs(opts, "Increased", userRule) + if err != nil { + return nil, err + } + return &ProofOfStakeIncreasedIterator{contract: _ProofOfStake.contract, event: "Increased", logs: logs, sub: sub}, nil +} + +// WatchIncreased is a free log subscription operation binding the contract event 0x2db19fadbf40ed77512048f708e78f52f7727cc5af099c414320de1c2137aa88. +// +// Solidity: event Increased(address indexed user, uint256 amount, uint256[] nfts) +func (_ProofOfStake *ProofOfStakeFilterer) WatchIncreased(opts *bind.WatchOpts, sink chan<- *ProofOfStakeIncreased, user []common.Address) (event.Subscription, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _ProofOfStake.contract.WatchLogs(opts, "Increased", userRule) + 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(ProofOfStakeIncreased) + if err := _ProofOfStake.contract.UnpackLog(event, "Increased", 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 +} + +// ParseIncreased is a log parse operation binding the contract event 0x2db19fadbf40ed77512048f708e78f52f7727cc5af099c414320de1c2137aa88. +// +// Solidity: event Increased(address indexed user, uint256 amount, uint256[] nfts) +func (_ProofOfStake *ProofOfStakeFilterer) ParseIncreased(log types.Log) (*ProofOfStakeIncreased, error) { + event := new(ProofOfStakeIncreased) + if err := _ProofOfStake.contract.UnpackLog(event, "Increased", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ProofOfStakeStakedIterator is returned from FilterStaked and is used to iterate over the raw logs and unpacked data for Staked events raised by the ProofOfStake contract. +type ProofOfStakeStakedIterator struct { + Event *ProofOfStakeStaked // 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 *ProofOfStakeStakedIterator) 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(ProofOfStakeStaked) + 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(ProofOfStakeStaked) + 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 *ProofOfStakeStakedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ProofOfStakeStakedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ProofOfStakeStaked represents a Staked event raised by the ProofOfStake contract. +type ProofOfStakeStaked struct { + User common.Address + Amount *big.Int + End *big.Int + Nfts []*big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterStaked is a free log retrieval operation binding the contract event 0x5df5de9ccb680fe3d60088f6d4c3b6d535074c704699377046c743a5b276e171. +// +// Solidity: event Staked(address indexed user, uint256 amount, uint256 end, uint256[] nfts) +func (_ProofOfStake *ProofOfStakeFilterer) FilterStaked(opts *bind.FilterOpts, user []common.Address) (*ProofOfStakeStakedIterator, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _ProofOfStake.contract.FilterLogs(opts, "Staked", userRule) + if err != nil { + return nil, err + } + return &ProofOfStakeStakedIterator{contract: _ProofOfStake.contract, event: "Staked", logs: logs, sub: sub}, nil +} + +// WatchStaked is a free log subscription operation binding the contract event 0x5df5de9ccb680fe3d60088f6d4c3b6d535074c704699377046c743a5b276e171. +// +// Solidity: event Staked(address indexed user, uint256 amount, uint256 end, uint256[] nfts) +func (_ProofOfStake *ProofOfStakeFilterer) WatchStaked(opts *bind.WatchOpts, sink chan<- *ProofOfStakeStaked, user []common.Address) (event.Subscription, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _ProofOfStake.contract.WatchLogs(opts, "Staked", userRule) + 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(ProofOfStakeStaked) + if err := _ProofOfStake.contract.UnpackLog(event, "Staked", 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 +} + +// ParseStaked is a log parse operation binding the contract event 0x5df5de9ccb680fe3d60088f6d4c3b6d535074c704699377046c743a5b276e171. +// +// Solidity: event Staked(address indexed user, uint256 amount, uint256 end, uint256[] nfts) +func (_ProofOfStake *ProofOfStakeFilterer) ParseStaked(log types.Log) (*ProofOfStakeStaked, error) { + event := new(ProofOfStakeStaked) + if err := _ProofOfStake.contract.UnpackLog(event, "Staked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ProofOfStakeWithdrawnIterator is returned from FilterWithdrawn and is used to iterate over the raw logs and unpacked data for Withdrawn events raised by the ProofOfStake contract. +type ProofOfStakeWithdrawnIterator struct { + Event *ProofOfStakeWithdrawn // 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 *ProofOfStakeWithdrawnIterator) 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(ProofOfStakeWithdrawn) + 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(ProofOfStakeWithdrawn) + 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 *ProofOfStakeWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ProofOfStakeWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ProofOfStakeWithdrawn represents a Withdrawn event raised by the ProofOfStake contract. +type ProofOfStakeWithdrawn struct { + User common.Address + Amount *big.Int + Nfts []*big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterWithdrawn is a free log retrieval operation binding the contract event 0xd40a9786b597b88b3426158112e3930e09cb031c138a150e367cfe17ff20e302. +// +// Solidity: event Withdrawn(address indexed user, uint256 amount, uint256[] nfts) +func (_ProofOfStake *ProofOfStakeFilterer) FilterWithdrawn(opts *bind.FilterOpts, user []common.Address) (*ProofOfStakeWithdrawnIterator, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _ProofOfStake.contract.FilterLogs(opts, "Withdrawn", userRule) + if err != nil { + return nil, err + } + return &ProofOfStakeWithdrawnIterator{contract: _ProofOfStake.contract, event: "Withdrawn", logs: logs, sub: sub}, nil +} + +// WatchWithdrawn is a free log subscription operation binding the contract event 0xd40a9786b597b88b3426158112e3930e09cb031c138a150e367cfe17ff20e302. +// +// Solidity: event Withdrawn(address indexed user, uint256 amount, uint256[] nfts) +func (_ProofOfStake *ProofOfStakeFilterer) WatchWithdrawn(opts *bind.WatchOpts, sink chan<- *ProofOfStakeWithdrawn, user []common.Address) (event.Subscription, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _ProofOfStake.contract.WatchLogs(opts, "Withdrawn", userRule) + 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(ProofOfStakeWithdrawn) + if err := _ProofOfStake.contract.UnpackLog(event, "Withdrawn", 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 +} + +// ParseWithdrawn is a log parse operation binding the contract event 0xd40a9786b597b88b3426158112e3930e09cb031c138a150e367cfe17ff20e302. +// +// Solidity: event Withdrawn(address indexed user, uint256 amount, uint256[] nfts) +func (_ProofOfStake *ProofOfStakeFilterer) ParseWithdrawn(log types.Log) (*ProofOfStakeWithdrawn, error) { + event := new(ProofOfStakeWithdrawn) + if err := _ProofOfStake.contract.UnpackLog(event, "Withdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/internal/crypto/ethereum/contracts/UnchainedStaking.go b/internal/crypto/ethereum/contracts/UnchainedStaking.go deleted file mode 100644 index ed3fa3c4..00000000 --- a/internal/crypto/ethereum/contracts/UnchainedStaking.go +++ /dev/null @@ -1,2644 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package contracts - -import ( - "errors" - "math/big" - "strings" - - 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" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -// UnchainedStakingEIP712SetNftPrice is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingEIP712SetNftPrice struct { - Requester common.Address - NftId *big.Int - Price *big.Int - Nonce *big.Int -} - -// UnchainedStakingEIP712SetNftPriceKey is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingEIP712SetNftPriceKey struct { - NftId *big.Int - Price *big.Int - Nonce *big.Int -} - -// UnchainedStakingEIP712SetParams is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingEIP712SetParams struct { - Requester common.Address - Token common.Address - Nft common.Address - NftTracker common.Address - Threshold *big.Int - Expiration *big.Int - Nonce *big.Int -} - -// UnchainedStakingEIP712SetParamsKey is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingEIP712SetParamsKey struct { - Token common.Address - Nft common.Address - NftTracker common.Address - Threshold *big.Int - Expiration *big.Int - Nonce *big.Int -} - -// UnchainedStakingEIP712SetSigner is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingEIP712SetSigner struct { - Staker common.Address - Signer common.Address -} - -// UnchainedStakingEIP712Transfer is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingEIP712Transfer struct { - Signer common.Address - From common.Address - To common.Address - Amount *big.Int - NftIds []*big.Int - Nonces []*big.Int -} - -// UnchainedStakingEIP712TransferKey is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingEIP712TransferKey struct { - From common.Address - To common.Address - Amount *big.Int - NftIds []*big.Int - Nonces []*big.Int -} - -// UnchainedStakingNftPriceInfo is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingNftPriceInfo struct { - NftId *big.Int - Price *big.Int - Voted *big.Int - Accepted bool -} - -// UnchainedStakingParamsInfo is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingParamsInfo struct { - Token common.Address - Nft common.Address - NftTracker common.Address - Threshold *big.Int - Expiration *big.Int - Voted *big.Int - Nonce *big.Int - Accepted bool -} - -// UnchainedStakingSignature is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingSignature struct { - V uint8 - R [32]byte - S [32]byte -} - -// UnchainedStakingStake is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingStake struct { - Amount *big.Int - Unlock *big.Int - NftIds []*big.Int -} - -// UnchainedStakingTransferInfo is an auto generated low-level Go binding around an user-defined struct. -type UnchainedStakingTransferInfo struct { - From common.Address - To common.Address - Amount *big.Int - NftIds []*big.Int - Voted *big.Int - Accepted bool - Nonces []*big.Int -} - -// UnchainedStakingMetaData contains all meta data concerning the UnchainedStaking contract. -var UnchainedStakingMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTrackerAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"consensusLock\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AddressInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyStaked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AmountZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BlsNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DurationZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ECDSAInvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"ECDSAInvalidSignatureLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"ECDSAInvalidSignatureS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Forbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"NonceUsed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotUnlocked\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"StakeExpiresBeforeVote\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StakeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"TopicExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"VotingPowerZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNFT\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"from\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"to\",\"type\":\"bytes32\"}],\"name\":\"BlsAddressChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unlock\",\"type\":\"uint256\"}],\"name\":\"Extended\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"ParamsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"SignerChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"StakeIncreased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"Staked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"UnStaked\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"evm\",\"type\":\"address\"}],\"name\":\"blsAddressOf\",\"outputs\":[{\"internalType\":\"bytes20\",\"name\":\"\",\"type\":\"bytes20\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"bls\",\"type\":\"bytes20\"}],\"name\":\"evmAddressOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"}],\"name\":\"extend\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConsensusThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"}],\"name\":\"getNftPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getParams\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"accepted\",\"type\":\"bool\"}],\"internalType\":\"structUnchainedStaking.ParamsInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetNftPriceKey\",\"name\":\"key\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"getRequestedSetNftPrice\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetParamsKey\",\"name\":\"key\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"getRequestedSetParams\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.EIP712TransferKey\",\"name\":\"key\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"transferer\",\"type\":\"address\"}],\"name\":\"getRequestedTransfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetNftPriceKey\",\"name\":\"key\",\"type\":\"tuple\"}],\"name\":\"getSetNftPriceData\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"accepted\",\"type\":\"bool\"}],\"internalType\":\"structUnchainedStaking.NftPriceInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetParamsKey\",\"name\":\"key\",\"type\":\"tuple\"}],\"name\":\"getSetParamsData\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"accepted\",\"type\":\"bool\"}],\"internalType\":\"structUnchainedStaking.ParamsInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"evm\",\"type\":\"address\"}],\"name\":\"getStake\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.Stake\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"bls\",\"type\":\"bytes20\"}],\"name\":\"getStake\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.Stake\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalVotingPower\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.EIP712TransferKey\",\"name\":\"key\",\"type\":\"tuple\"}],\"name\":\"getTransferData\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"accepted\",\"type\":\"bool\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.TransferInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"bls\",\"type\":\"bytes20\"}],\"name\":\"getVotingPower\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"evm\",\"type\":\"address\"}],\"name\":\"getVotingPower\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"increaseStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"blsAddress\",\"type\":\"bytes20\"}],\"name\":\"setBlsAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetNftPrice[]\",\"name\":\"eip712SetNftPrices\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"}],\"name\":\"setNftPrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetParams[]\",\"name\":\"eip712SetParams\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"}],\"name\":\"setParams\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"internalType\":\"structUnchainedStaking.EIP712SetSigner\",\"name\":\"eip712SetSigner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"stakerSignature\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signerSignature\",\"type\":\"tuple\"}],\"name\":\"setSigner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"signerToStaker\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"stake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"}],\"name\":\"stakerToSigner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.EIP712Transfer[]\",\"name\":\"eip712Transferes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unstake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetParams\",\"name\":\"eip712SetParam\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signature\",\"type\":\"tuple\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetNftPrice\",\"name\":\"eip712SetNftPrice\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signature\",\"type\":\"tuple\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"internalType\":\"structUnchainedStaking.EIP712SetSigner\",\"name\":\"eip712SetSigner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"stakerSignature\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signerSignature\",\"type\":\"tuple\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.EIP712Transfer\",\"name\":\"eip712Transfer\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signature\",\"type\":\"tuple\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", -} - -// UnchainedStakingABI is the input ABI used to generate the binding from. -// Deprecated: Use UnchainedStakingMetaData.ABI instead. -var UnchainedStakingABI = UnchainedStakingMetaData.ABI - -// UnchainedStaking is an auto generated Go binding around an Ethereum contract. -type UnchainedStaking struct { - UnchainedStakingCaller // Read-only binding to the contract - UnchainedStakingTransactor // Write-only binding to the contract - UnchainedStakingFilterer // Log filterer for contract events -} - -// UnchainedStakingCaller is an auto generated read-only Go binding around an Ethereum contract. -type UnchainedStakingCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// UnchainedStakingTransactor is an auto generated write-only Go binding around an Ethereum contract. -type UnchainedStakingTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// UnchainedStakingFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type UnchainedStakingFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// UnchainedStakingSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type UnchainedStakingSession struct { - Contract *UnchainedStaking // 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 -} - -// UnchainedStakingCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type UnchainedStakingCallerSession struct { - Contract *UnchainedStakingCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// UnchainedStakingTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type UnchainedStakingTransactorSession struct { - Contract *UnchainedStakingTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// UnchainedStakingRaw is an auto generated low-level Go binding around an Ethereum contract. -type UnchainedStakingRaw struct { - Contract *UnchainedStaking // Generic contract binding to access the raw methods on -} - -// UnchainedStakingCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type UnchainedStakingCallerRaw struct { - Contract *UnchainedStakingCaller // Generic read-only contract binding to access the raw methods on -} - -// UnchainedStakingTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type UnchainedStakingTransactorRaw struct { - Contract *UnchainedStakingTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewUnchainedStaking creates a new instance of UnchainedStaking, bound to a specific deployed contract. -func NewUnchainedStaking(address common.Address, backend bind.ContractBackend) (*UnchainedStaking, error) { - contract, err := bindUnchainedStaking(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &UnchainedStaking{UnchainedStakingCaller: UnchainedStakingCaller{contract: contract}, UnchainedStakingTransactor: UnchainedStakingTransactor{contract: contract}, UnchainedStakingFilterer: UnchainedStakingFilterer{contract: contract}}, nil -} - -// NewUnchainedStakingCaller creates a new read-only instance of UnchainedStaking, bound to a specific deployed contract. -func NewUnchainedStakingCaller(address common.Address, caller bind.ContractCaller) (*UnchainedStakingCaller, error) { - contract, err := bindUnchainedStaking(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &UnchainedStakingCaller{contract: contract}, nil -} - -// NewUnchainedStakingTransactor creates a new write-only instance of UnchainedStaking, bound to a specific deployed contract. -func NewUnchainedStakingTransactor(address common.Address, transactor bind.ContractTransactor) (*UnchainedStakingTransactor, error) { - contract, err := bindUnchainedStaking(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &UnchainedStakingTransactor{contract: contract}, nil -} - -// NewUnchainedStakingFilterer creates a new log filterer instance of UnchainedStaking, bound to a specific deployed contract. -func NewUnchainedStakingFilterer(address common.Address, filterer bind.ContractFilterer) (*UnchainedStakingFilterer, error) { - contract, err := bindUnchainedStaking(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &UnchainedStakingFilterer{contract: contract}, nil -} - -// bindUnchainedStaking binds a generic wrapper to an already deployed contract. -func bindUnchainedStaking(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := UnchainedStakingMetaData.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 (_UnchainedStaking *UnchainedStakingRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UnchainedStaking.Contract.UnchainedStakingCaller.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 (_UnchainedStaking *UnchainedStakingRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UnchainedStaking.Contract.UnchainedStakingTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_UnchainedStaking *UnchainedStakingRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UnchainedStaking.Contract.UnchainedStakingTransactor.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 (_UnchainedStaking *UnchainedStakingCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UnchainedStaking.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 (_UnchainedStaking *UnchainedStakingTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UnchainedStaking.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_UnchainedStaking *UnchainedStakingTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UnchainedStaking.Contract.contract.Transact(opts, method, params...) -} - -// BlsAddressOf is a free data retrieval call binding the contract method 0x9e95a1a5. -// -// Solidity: function blsAddressOf(address evm) view returns(bytes20) -func (_UnchainedStaking *UnchainedStakingCaller) BlsAddressOf(opts *bind.CallOpts, evm common.Address) ([20]byte, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "blsAddressOf", evm) - - if err != nil { - return *new([20]byte), err - } - - out0 := *abi.ConvertType(out[0], new([20]byte)).(*[20]byte) - - return out0, err - -} - -// BlsAddressOf is a free data retrieval call binding the contract method 0x9e95a1a5. -// -// Solidity: function blsAddressOf(address evm) view returns(bytes20) -func (_UnchainedStaking *UnchainedStakingSession) BlsAddressOf(evm common.Address) ([20]byte, error) { - return _UnchainedStaking.Contract.BlsAddressOf(&_UnchainedStaking.CallOpts, evm) -} - -// BlsAddressOf is a free data retrieval call binding the contract method 0x9e95a1a5. -// -// Solidity: function blsAddressOf(address evm) view returns(bytes20) -func (_UnchainedStaking *UnchainedStakingCallerSession) BlsAddressOf(evm common.Address) ([20]byte, error) { - return _UnchainedStaking.Contract.BlsAddressOf(&_UnchainedStaking.CallOpts, evm) -} - -// EvmAddressOf is a free data retrieval call binding the contract method 0x40043ead. -// -// Solidity: function evmAddressOf(bytes20 bls) view returns(address) -func (_UnchainedStaking *UnchainedStakingCaller) EvmAddressOf(opts *bind.CallOpts, bls [20]byte) (common.Address, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "evmAddressOf", bls) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// EvmAddressOf is a free data retrieval call binding the contract method 0x40043ead. -// -// Solidity: function evmAddressOf(bytes20 bls) view returns(address) -func (_UnchainedStaking *UnchainedStakingSession) EvmAddressOf(bls [20]byte) (common.Address, error) { - return _UnchainedStaking.Contract.EvmAddressOf(&_UnchainedStaking.CallOpts, bls) -} - -// EvmAddressOf is a free data retrieval call binding the contract method 0x40043ead. -// -// Solidity: function evmAddressOf(bytes20 bls) view returns(address) -func (_UnchainedStaking *UnchainedStakingCallerSession) EvmAddressOf(bls [20]byte) (common.Address, error) { - return _UnchainedStaking.Contract.EvmAddressOf(&_UnchainedStaking.CallOpts, bls) -} - -// GetChainId is a free data retrieval call binding the contract method 0x3408e470. -// -// Solidity: function getChainId() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCaller) GetChainId(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getChainId") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetChainId is a free data retrieval call binding the contract method 0x3408e470. -// -// Solidity: function getChainId() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingSession) GetChainId() (*big.Int, error) { - return _UnchainedStaking.Contract.GetChainId(&_UnchainedStaking.CallOpts) -} - -// GetChainId is a free data retrieval call binding the contract method 0x3408e470. -// -// Solidity: function getChainId() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetChainId() (*big.Int, error) { - return _UnchainedStaking.Contract.GetChainId(&_UnchainedStaking.CallOpts) -} - -// GetConsensusThreshold is a free data retrieval call binding the contract method 0xd42791e1. -// -// Solidity: function getConsensusThreshold() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCaller) GetConsensusThreshold(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getConsensusThreshold") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetConsensusThreshold is a free data retrieval call binding the contract method 0xd42791e1. -// -// Solidity: function getConsensusThreshold() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingSession) GetConsensusThreshold() (*big.Int, error) { - return _UnchainedStaking.Contract.GetConsensusThreshold(&_UnchainedStaking.CallOpts) -} - -// GetConsensusThreshold is a free data retrieval call binding the contract method 0xd42791e1. -// -// Solidity: function getConsensusThreshold() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetConsensusThreshold() (*big.Int, error) { - return _UnchainedStaking.Contract.GetConsensusThreshold(&_UnchainedStaking.CallOpts) -} - -// GetNftPrice is a free data retrieval call binding the contract method 0x7bf0989a. -// -// Solidity: function getNftPrice(uint256 nftId) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCaller) GetNftPrice(opts *bind.CallOpts, nftId *big.Int) (*big.Int, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getNftPrice", nftId) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetNftPrice is a free data retrieval call binding the contract method 0x7bf0989a. -// -// Solidity: function getNftPrice(uint256 nftId) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingSession) GetNftPrice(nftId *big.Int) (*big.Int, error) { - return _UnchainedStaking.Contract.GetNftPrice(&_UnchainedStaking.CallOpts, nftId) -} - -// GetNftPrice is a free data retrieval call binding the contract method 0x7bf0989a. -// -// Solidity: function getNftPrice(uint256 nftId) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetNftPrice(nftId *big.Int) (*big.Int, error) { - return _UnchainedStaking.Contract.GetNftPrice(&_UnchainedStaking.CallOpts, nftId) -} - -// GetParams is a free data retrieval call binding the contract method 0x5e615a6b. -// -// Solidity: function getParams() view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingCaller) GetParams(opts *bind.CallOpts) (UnchainedStakingParamsInfo, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getParams") - - if err != nil { - return *new(UnchainedStakingParamsInfo), err - } - - out0 := *abi.ConvertType(out[0], new(UnchainedStakingParamsInfo)).(*UnchainedStakingParamsInfo) - - return out0, err - -} - -// GetParams is a free data retrieval call binding the contract method 0x5e615a6b. -// -// Solidity: function getParams() view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingSession) GetParams() (UnchainedStakingParamsInfo, error) { - return _UnchainedStaking.Contract.GetParams(&_UnchainedStaking.CallOpts) -} - -// GetParams is a free data retrieval call binding the contract method 0x5e615a6b. -// -// Solidity: function getParams() view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetParams() (UnchainedStakingParamsInfo, error) { - return _UnchainedStaking.Contract.GetParams(&_UnchainedStaking.CallOpts) -} - -// GetRequestedSetNftPrice is a free data retrieval call binding the contract method 0x45a6e62f. -// -// Solidity: function getRequestedSetNftPrice((uint256,uint256,uint256) key, address requester) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCaller) GetRequestedSetNftPrice(opts *bind.CallOpts, key UnchainedStakingEIP712SetNftPriceKey, requester common.Address) (bool, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getRequestedSetNftPrice", key, requester) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// GetRequestedSetNftPrice is a free data retrieval call binding the contract method 0x45a6e62f. -// -// Solidity: function getRequestedSetNftPrice((uint256,uint256,uint256) key, address requester) view returns(bool) -func (_UnchainedStaking *UnchainedStakingSession) GetRequestedSetNftPrice(key UnchainedStakingEIP712SetNftPriceKey, requester common.Address) (bool, error) { - return _UnchainedStaking.Contract.GetRequestedSetNftPrice(&_UnchainedStaking.CallOpts, key, requester) -} - -// GetRequestedSetNftPrice is a free data retrieval call binding the contract method 0x45a6e62f. -// -// Solidity: function getRequestedSetNftPrice((uint256,uint256,uint256) key, address requester) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetRequestedSetNftPrice(key UnchainedStakingEIP712SetNftPriceKey, requester common.Address) (bool, error) { - return _UnchainedStaking.Contract.GetRequestedSetNftPrice(&_UnchainedStaking.CallOpts, key, requester) -} - -// GetRequestedSetParams is a free data retrieval call binding the contract method 0x984d92e8. -// -// Solidity: function getRequestedSetParams((address,address,address,uint256,uint256,uint256) key, address requester) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCaller) GetRequestedSetParams(opts *bind.CallOpts, key UnchainedStakingEIP712SetParamsKey, requester common.Address) (bool, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getRequestedSetParams", key, requester) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// GetRequestedSetParams is a free data retrieval call binding the contract method 0x984d92e8. -// -// Solidity: function getRequestedSetParams((address,address,address,uint256,uint256,uint256) key, address requester) view returns(bool) -func (_UnchainedStaking *UnchainedStakingSession) GetRequestedSetParams(key UnchainedStakingEIP712SetParamsKey, requester common.Address) (bool, error) { - return _UnchainedStaking.Contract.GetRequestedSetParams(&_UnchainedStaking.CallOpts, key, requester) -} - -// GetRequestedSetParams is a free data retrieval call binding the contract method 0x984d92e8. -// -// Solidity: function getRequestedSetParams((address,address,address,uint256,uint256,uint256) key, address requester) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetRequestedSetParams(key UnchainedStakingEIP712SetParamsKey, requester common.Address) (bool, error) { - return _UnchainedStaking.Contract.GetRequestedSetParams(&_UnchainedStaking.CallOpts, key, requester) -} - -// GetRequestedTransfer is a free data retrieval call binding the contract method 0xf8560edb. -// -// Solidity: function getRequestedTransfer((address,address,uint256,uint256[],uint256[]) key, address transferer) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCaller) GetRequestedTransfer(opts *bind.CallOpts, key UnchainedStakingEIP712TransferKey, transferer common.Address) (bool, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getRequestedTransfer", key, transferer) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// GetRequestedTransfer is a free data retrieval call binding the contract method 0xf8560edb. -// -// Solidity: function getRequestedTransfer((address,address,uint256,uint256[],uint256[]) key, address transferer) view returns(bool) -func (_UnchainedStaking *UnchainedStakingSession) GetRequestedTransfer(key UnchainedStakingEIP712TransferKey, transferer common.Address) (bool, error) { - return _UnchainedStaking.Contract.GetRequestedTransfer(&_UnchainedStaking.CallOpts, key, transferer) -} - -// GetRequestedTransfer is a free data retrieval call binding the contract method 0xf8560edb. -// -// Solidity: function getRequestedTransfer((address,address,uint256,uint256[],uint256[]) key, address transferer) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetRequestedTransfer(key UnchainedStakingEIP712TransferKey, transferer common.Address) (bool, error) { - return _UnchainedStaking.Contract.GetRequestedTransfer(&_UnchainedStaking.CallOpts, key, transferer) -} - -// GetSetNftPriceData is a free data retrieval call binding the contract method 0xbbb5b849. -// -// Solidity: function getSetNftPriceData((uint256,uint256,uint256) key) view returns((uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingCaller) GetSetNftPriceData(opts *bind.CallOpts, key UnchainedStakingEIP712SetNftPriceKey) (UnchainedStakingNftPriceInfo, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getSetNftPriceData", key) - - if err != nil { - return *new(UnchainedStakingNftPriceInfo), err - } - - out0 := *abi.ConvertType(out[0], new(UnchainedStakingNftPriceInfo)).(*UnchainedStakingNftPriceInfo) - - return out0, err - -} - -// GetSetNftPriceData is a free data retrieval call binding the contract method 0xbbb5b849. -// -// Solidity: function getSetNftPriceData((uint256,uint256,uint256) key) view returns((uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingSession) GetSetNftPriceData(key UnchainedStakingEIP712SetNftPriceKey) (UnchainedStakingNftPriceInfo, error) { - return _UnchainedStaking.Contract.GetSetNftPriceData(&_UnchainedStaking.CallOpts, key) -} - -// GetSetNftPriceData is a free data retrieval call binding the contract method 0xbbb5b849. -// -// Solidity: function getSetNftPriceData((uint256,uint256,uint256) key) view returns((uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetSetNftPriceData(key UnchainedStakingEIP712SetNftPriceKey) (UnchainedStakingNftPriceInfo, error) { - return _UnchainedStaking.Contract.GetSetNftPriceData(&_UnchainedStaking.CallOpts, key) -} - -// GetSetParamsData is a free data retrieval call binding the contract method 0x300fab4f. -// -// Solidity: function getSetParamsData((address,address,address,uint256,uint256,uint256) key) view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingCaller) GetSetParamsData(opts *bind.CallOpts, key UnchainedStakingEIP712SetParamsKey) (UnchainedStakingParamsInfo, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getSetParamsData", key) - - if err != nil { - return *new(UnchainedStakingParamsInfo), err - } - - out0 := *abi.ConvertType(out[0], new(UnchainedStakingParamsInfo)).(*UnchainedStakingParamsInfo) - - return out0, err - -} - -// GetSetParamsData is a free data retrieval call binding the contract method 0x300fab4f. -// -// Solidity: function getSetParamsData((address,address,address,uint256,uint256,uint256) key) view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingSession) GetSetParamsData(key UnchainedStakingEIP712SetParamsKey) (UnchainedStakingParamsInfo, error) { - return _UnchainedStaking.Contract.GetSetParamsData(&_UnchainedStaking.CallOpts, key) -} - -// GetSetParamsData is a free data retrieval call binding the contract method 0x300fab4f. -// -// Solidity: function getSetParamsData((address,address,address,uint256,uint256,uint256) key) view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetSetParamsData(key UnchainedStakingEIP712SetParamsKey) (UnchainedStakingParamsInfo, error) { - return _UnchainedStaking.Contract.GetSetParamsData(&_UnchainedStaking.CallOpts, key) -} - -// GetStake is a free data retrieval call binding the contract method 0x7a766460. -// -// Solidity: function getStake(address evm) view returns((uint256,uint256,uint256[])) -func (_UnchainedStaking *UnchainedStakingCaller) GetStake(opts *bind.CallOpts, evm common.Address) (UnchainedStakingStake, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getStake", evm) - - if err != nil { - return *new(UnchainedStakingStake), err - } - - out0 := *abi.ConvertType(out[0], new(UnchainedStakingStake)).(*UnchainedStakingStake) - - return out0, err - -} - -// GetStake is a free data retrieval call binding the contract method 0x7a766460. -// -// Solidity: function getStake(address evm) view returns((uint256,uint256,uint256[])) -func (_UnchainedStaking *UnchainedStakingSession) GetStake(evm common.Address) (UnchainedStakingStake, error) { - return _UnchainedStaking.Contract.GetStake(&_UnchainedStaking.CallOpts, evm) -} - -// GetStake is a free data retrieval call binding the contract method 0x7a766460. -// -// Solidity: function getStake(address evm) view returns((uint256,uint256,uint256[])) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetStake(evm common.Address) (UnchainedStakingStake, error) { - return _UnchainedStaking.Contract.GetStake(&_UnchainedStaking.CallOpts, evm) -} - -// GetStake0 is a free data retrieval call binding the contract method 0xf86fec69. -// -// Solidity: function getStake(bytes20 bls) view returns((uint256,uint256,uint256[])) -func (_UnchainedStaking *UnchainedStakingCaller) GetStake0(opts *bind.CallOpts, bls [20]byte) (UnchainedStakingStake, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getStake0", bls) - - if err != nil { - return *new(UnchainedStakingStake), err - } - - out0 := *abi.ConvertType(out[0], new(UnchainedStakingStake)).(*UnchainedStakingStake) - - return out0, err - -} - -// GetStake0 is a free data retrieval call binding the contract method 0xf86fec69. -// -// Solidity: function getStake(bytes20 bls) view returns((uint256,uint256,uint256[])) -func (_UnchainedStaking *UnchainedStakingSession) GetStake0(bls [20]byte) (UnchainedStakingStake, error) { - return _UnchainedStaking.Contract.GetStake0(&_UnchainedStaking.CallOpts, bls) -} - -// GetStake0 is a free data retrieval call binding the contract method 0xf86fec69. -// -// Solidity: function getStake(bytes20 bls) view returns((uint256,uint256,uint256[])) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetStake0(bls [20]byte) (UnchainedStakingStake, error) { - return _UnchainedStaking.Contract.GetStake0(&_UnchainedStaking.CallOpts, bls) -} - -// GetTotalVotingPower is a free data retrieval call binding the contract method 0x11acc1a7. -// -// Solidity: function getTotalVotingPower() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCaller) GetTotalVotingPower(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getTotalVotingPower") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetTotalVotingPower is a free data retrieval call binding the contract method 0x11acc1a7. -// -// Solidity: function getTotalVotingPower() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingSession) GetTotalVotingPower() (*big.Int, error) { - return _UnchainedStaking.Contract.GetTotalVotingPower(&_UnchainedStaking.CallOpts) -} - -// GetTotalVotingPower is a free data retrieval call binding the contract method 0x11acc1a7. -// -// Solidity: function getTotalVotingPower() view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetTotalVotingPower() (*big.Int, error) { - return _UnchainedStaking.Contract.GetTotalVotingPower(&_UnchainedStaking.CallOpts) -} - -// GetTransferData is a free data retrieval call binding the contract method 0x865e1281. -// -// Solidity: function getTransferData((address,address,uint256,uint256[],uint256[]) key) view returns((address,address,uint256,uint256[],uint256,bool,uint256[])) -func (_UnchainedStaking *UnchainedStakingCaller) GetTransferData(opts *bind.CallOpts, key UnchainedStakingEIP712TransferKey) (UnchainedStakingTransferInfo, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getTransferData", key) - - if err != nil { - return *new(UnchainedStakingTransferInfo), err - } - - out0 := *abi.ConvertType(out[0], new(UnchainedStakingTransferInfo)).(*UnchainedStakingTransferInfo) - - return out0, err - -} - -// GetTransferData is a free data retrieval call binding the contract method 0x865e1281. -// -// Solidity: function getTransferData((address,address,uint256,uint256[],uint256[]) key) view returns((address,address,uint256,uint256[],uint256,bool,uint256[])) -func (_UnchainedStaking *UnchainedStakingSession) GetTransferData(key UnchainedStakingEIP712TransferKey) (UnchainedStakingTransferInfo, error) { - return _UnchainedStaking.Contract.GetTransferData(&_UnchainedStaking.CallOpts, key) -} - -// GetTransferData is a free data retrieval call binding the contract method 0x865e1281. -// -// Solidity: function getTransferData((address,address,uint256,uint256[],uint256[]) key) view returns((address,address,uint256,uint256[],uint256,bool,uint256[])) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetTransferData(key UnchainedStakingEIP712TransferKey) (UnchainedStakingTransferInfo, error) { - return _UnchainedStaking.Contract.GetTransferData(&_UnchainedStaking.CallOpts, key) -} - -// GetVotingPower is a free data retrieval call binding the contract method 0x68eacf93. -// -// Solidity: function getVotingPower(bytes20 bls) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCaller) GetVotingPower(opts *bind.CallOpts, bls [20]byte) (*big.Int, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getVotingPower", bls) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetVotingPower is a free data retrieval call binding the contract method 0x68eacf93. -// -// Solidity: function getVotingPower(bytes20 bls) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingSession) GetVotingPower(bls [20]byte) (*big.Int, error) { - return _UnchainedStaking.Contract.GetVotingPower(&_UnchainedStaking.CallOpts, bls) -} - -// GetVotingPower is a free data retrieval call binding the contract method 0x68eacf93. -// -// Solidity: function getVotingPower(bytes20 bls) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetVotingPower(bls [20]byte) (*big.Int, error) { - return _UnchainedStaking.Contract.GetVotingPower(&_UnchainedStaking.CallOpts, bls) -} - -// GetVotingPower0 is a free data retrieval call binding the contract method 0xbb4d4436. -// -// Solidity: function getVotingPower(address evm) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCaller) GetVotingPower0(opts *bind.CallOpts, evm common.Address) (*big.Int, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "getVotingPower0", evm) - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// GetVotingPower0 is a free data retrieval call binding the contract method 0xbb4d4436. -// -// Solidity: function getVotingPower(address evm) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingSession) GetVotingPower0(evm common.Address) (*big.Int, error) { - return _UnchainedStaking.Contract.GetVotingPower0(&_UnchainedStaking.CallOpts, evm) -} - -// GetVotingPower0 is a free data retrieval call binding the contract method 0xbb4d4436. -// -// Solidity: function getVotingPower(address evm) view returns(uint256) -func (_UnchainedStaking *UnchainedStakingCallerSession) GetVotingPower0(evm common.Address) (*big.Int, error) { - return _UnchainedStaking.Contract.GetVotingPower0(&_UnchainedStaking.CallOpts, evm) -} - -// OnERC721Received is a free data retrieval call binding the contract method 0x150b7a02. -// -// Solidity: function onERC721Received(address , address , uint256 , bytes ) view returns(bytes4) -func (_UnchainedStaking *UnchainedStakingCaller) OnERC721Received(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 []byte) ([4]byte, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "onERC721Received", arg0, arg1, arg2, arg3) - - if err != nil { - return *new([4]byte), err - } - - out0 := *abi.ConvertType(out[0], new([4]byte)).(*[4]byte) - - return out0, err - -} - -// OnERC721Received is a free data retrieval call binding the contract method 0x150b7a02. -// -// Solidity: function onERC721Received(address , address , uint256 , bytes ) view returns(bytes4) -func (_UnchainedStaking *UnchainedStakingSession) OnERC721Received(arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 []byte) ([4]byte, error) { - return _UnchainedStaking.Contract.OnERC721Received(&_UnchainedStaking.CallOpts, arg0, arg1, arg2, arg3) -} - -// OnERC721Received is a free data retrieval call binding the contract method 0x150b7a02. -// -// Solidity: function onERC721Received(address , address , uint256 , bytes ) view returns(bytes4) -func (_UnchainedStaking *UnchainedStakingCallerSession) OnERC721Received(arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 []byte) ([4]byte, error) { - return _UnchainedStaking.Contract.OnERC721Received(&_UnchainedStaking.CallOpts, arg0, arg1, arg2, arg3) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UnchainedStaking *UnchainedStakingCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _UnchainedStaking.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 (_UnchainedStaking *UnchainedStakingSession) Owner() (common.Address, error) { - return _UnchainedStaking.Contract.Owner(&_UnchainedStaking.CallOpts) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UnchainedStaking *UnchainedStakingCallerSession) Owner() (common.Address, error) { - return _UnchainedStaking.Contract.Owner(&_UnchainedStaking.CallOpts) -} - -// SignerToStaker is a free data retrieval call binding the contract method 0xad5a98c5. -// -// Solidity: function signerToStaker(address signer) view returns(address) -func (_UnchainedStaking *UnchainedStakingCaller) SignerToStaker(opts *bind.CallOpts, signer common.Address) (common.Address, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "signerToStaker", signer) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// SignerToStaker is a free data retrieval call binding the contract method 0xad5a98c5. -// -// Solidity: function signerToStaker(address signer) view returns(address) -func (_UnchainedStaking *UnchainedStakingSession) SignerToStaker(signer common.Address) (common.Address, error) { - return _UnchainedStaking.Contract.SignerToStaker(&_UnchainedStaking.CallOpts, signer) -} - -// SignerToStaker is a free data retrieval call binding the contract method 0xad5a98c5. -// -// Solidity: function signerToStaker(address signer) view returns(address) -func (_UnchainedStaking *UnchainedStakingCallerSession) SignerToStaker(signer common.Address) (common.Address, error) { - return _UnchainedStaking.Contract.SignerToStaker(&_UnchainedStaking.CallOpts, signer) -} - -// StakerToSigner is a free data retrieval call binding the contract method 0xc7bcae78. -// -// Solidity: function stakerToSigner(address staker) view returns(address) -func (_UnchainedStaking *UnchainedStakingCaller) StakerToSigner(opts *bind.CallOpts, staker common.Address) (common.Address, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "stakerToSigner", staker) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// StakerToSigner is a free data retrieval call binding the contract method 0xc7bcae78. -// -// Solidity: function stakerToSigner(address staker) view returns(address) -func (_UnchainedStaking *UnchainedStakingSession) StakerToSigner(staker common.Address) (common.Address, error) { - return _UnchainedStaking.Contract.StakerToSigner(&_UnchainedStaking.CallOpts, staker) -} - -// StakerToSigner is a free data retrieval call binding the contract method 0xc7bcae78. -// -// Solidity: function stakerToSigner(address staker) view returns(address) -func (_UnchainedStaking *UnchainedStakingCallerSession) StakerToSigner(staker common.Address) (common.Address, error) { - return _UnchainedStaking.Contract.StakerToSigner(&_UnchainedStaking.CallOpts, staker) -} - -// Verify is a free data retrieval call binding the contract method 0x6e0b9e40. -// -// Solidity: function verify((address,address,address,address,uint256,uint256,uint256) eip712SetParam, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCaller) Verify(opts *bind.CallOpts, eip712SetParam UnchainedStakingEIP712SetParams, signature UnchainedStakingSignature) (bool, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "verify", eip712SetParam, signature) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// Verify is a free data retrieval call binding the contract method 0x6e0b9e40. -// -// Solidity: function verify((address,address,address,address,uint256,uint256,uint256) eip712SetParam, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingSession) Verify(eip712SetParam UnchainedStakingEIP712SetParams, signature UnchainedStakingSignature) (bool, error) { - return _UnchainedStaking.Contract.Verify(&_UnchainedStaking.CallOpts, eip712SetParam, signature) -} - -// Verify is a free data retrieval call binding the contract method 0x6e0b9e40. -// -// Solidity: function verify((address,address,address,address,uint256,uint256,uint256) eip712SetParam, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCallerSession) Verify(eip712SetParam UnchainedStakingEIP712SetParams, signature UnchainedStakingSignature) (bool, error) { - return _UnchainedStaking.Contract.Verify(&_UnchainedStaking.CallOpts, eip712SetParam, signature) -} - -// Verify0 is a free data retrieval call binding the contract method 0x709eb01b. -// -// Solidity: function verify((address,uint256,uint256,uint256) eip712SetNftPrice, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCaller) Verify0(opts *bind.CallOpts, eip712SetNftPrice UnchainedStakingEIP712SetNftPrice, signature UnchainedStakingSignature) (bool, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "verify0", eip712SetNftPrice, signature) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// Verify0 is a free data retrieval call binding the contract method 0x709eb01b. -// -// Solidity: function verify((address,uint256,uint256,uint256) eip712SetNftPrice, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingSession) Verify0(eip712SetNftPrice UnchainedStakingEIP712SetNftPrice, signature UnchainedStakingSignature) (bool, error) { - return _UnchainedStaking.Contract.Verify0(&_UnchainedStaking.CallOpts, eip712SetNftPrice, signature) -} - -// Verify0 is a free data retrieval call binding the contract method 0x709eb01b. -// -// Solidity: function verify((address,uint256,uint256,uint256) eip712SetNftPrice, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCallerSession) Verify0(eip712SetNftPrice UnchainedStakingEIP712SetNftPrice, signature UnchainedStakingSignature) (bool, error) { - return _UnchainedStaking.Contract.Verify0(&_UnchainedStaking.CallOpts, eip712SetNftPrice, signature) -} - -// Verify1 is a free data retrieval call binding the contract method 0x7856cc70. -// -// Solidity: function verify((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCaller) Verify1(opts *bind.CallOpts, eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (bool, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "verify1", eip712SetSigner, stakerSignature, signerSignature) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// Verify1 is a free data retrieval call binding the contract method 0x7856cc70. -// -// Solidity: function verify((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingSession) Verify1(eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (bool, error) { - return _UnchainedStaking.Contract.Verify1(&_UnchainedStaking.CallOpts, eip712SetSigner, stakerSignature, signerSignature) -} - -// Verify1 is a free data retrieval call binding the contract method 0x7856cc70. -// -// Solidity: function verify((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCallerSession) Verify1(eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (bool, error) { - return _UnchainedStaking.Contract.Verify1(&_UnchainedStaking.CallOpts, eip712SetSigner, stakerSignature, signerSignature) -} - -// Verify2 is a free data retrieval call binding the contract method 0xb7543d3e. -// -// Solidity: function verify((address,address,address,uint256,uint256[],uint256[]) eip712Transfer, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCaller) Verify2(opts *bind.CallOpts, eip712Transfer UnchainedStakingEIP712Transfer, signature UnchainedStakingSignature) (bool, error) { - var out []interface{} - err := _UnchainedStaking.contract.Call(opts, &out, "verify2", eip712Transfer, signature) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// Verify2 is a free data retrieval call binding the contract method 0xb7543d3e. -// -// Solidity: function verify((address,address,address,uint256,uint256[],uint256[]) eip712Transfer, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingSession) Verify2(eip712Transfer UnchainedStakingEIP712Transfer, signature UnchainedStakingSignature) (bool, error) { - return _UnchainedStaking.Contract.Verify2(&_UnchainedStaking.CallOpts, eip712Transfer, signature) -} - -// Verify2 is a free data retrieval call binding the contract method 0xb7543d3e. -// -// Solidity: function verify((address,address,address,uint256,uint256[],uint256[]) eip712Transfer, (uint8,bytes32,bytes32) signature) view returns(bool) -func (_UnchainedStaking *UnchainedStakingCallerSession) Verify2(eip712Transfer UnchainedStakingEIP712Transfer, signature UnchainedStakingSignature) (bool, error) { - return _UnchainedStaking.Contract.Verify2(&_UnchainedStaking.CallOpts, eip712Transfer, signature) -} - -// Extend is a paid mutator transaction binding the contract method 0x9714378c. -// -// Solidity: function extend(uint256 duration) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) Extend(opts *bind.TransactOpts, duration *big.Int) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "extend", duration) -} - -// Extend is a paid mutator transaction binding the contract method 0x9714378c. -// -// Solidity: function extend(uint256 duration) returns() -func (_UnchainedStaking *UnchainedStakingSession) Extend(duration *big.Int) (*types.Transaction, error) { - return _UnchainedStaking.Contract.Extend(&_UnchainedStaking.TransactOpts, duration) -} - -// Extend is a paid mutator transaction binding the contract method 0x9714378c. -// -// Solidity: function extend(uint256 duration) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) Extend(duration *big.Int) (*types.Transaction, error) { - return _UnchainedStaking.Contract.Extend(&_UnchainedStaking.TransactOpts, duration) -} - -// IncreaseStake is a paid mutator transaction binding the contract method 0x0062ad9d. -// -// Solidity: function increaseStake(uint256 amount, uint256[] nftIds) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) IncreaseStake(opts *bind.TransactOpts, amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "increaseStake", amount, nftIds) -} - -// IncreaseStake is a paid mutator transaction binding the contract method 0x0062ad9d. -// -// Solidity: function increaseStake(uint256 amount, uint256[] nftIds) returns() -func (_UnchainedStaking *UnchainedStakingSession) IncreaseStake(amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { - return _UnchainedStaking.Contract.IncreaseStake(&_UnchainedStaking.TransactOpts, amount, nftIds) -} - -// IncreaseStake is a paid mutator transaction binding the contract method 0x0062ad9d. -// -// Solidity: function increaseStake(uint256 amount, uint256[] nftIds) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) IncreaseStake(amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { - return _UnchainedStaking.Contract.IncreaseStake(&_UnchainedStaking.TransactOpts, amount, nftIds) -} - -// RecoverERC20 is a paid mutator transaction binding the contract method 0x1171bda9. -// -// Solidity: function recoverERC20(address token, address recipient, uint256 amount) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) RecoverERC20(opts *bind.TransactOpts, token common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "recoverERC20", token, recipient, amount) -} - -// RecoverERC20 is a paid mutator transaction binding the contract method 0x1171bda9. -// -// Solidity: function recoverERC20(address token, address recipient, uint256 amount) returns() -func (_UnchainedStaking *UnchainedStakingSession) RecoverERC20(token common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _UnchainedStaking.Contract.RecoverERC20(&_UnchainedStaking.TransactOpts, token, recipient, amount) -} - -// RecoverERC20 is a paid mutator transaction binding the contract method 0x1171bda9. -// -// Solidity: function recoverERC20(address token, address recipient, uint256 amount) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) RecoverERC20(token common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _UnchainedStaking.Contract.RecoverERC20(&_UnchainedStaking.TransactOpts, token, recipient, amount) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UnchainedStaking *UnchainedStakingTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "renounceOwnership") -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UnchainedStaking *UnchainedStakingSession) RenounceOwnership() (*types.Transaction, error) { - return _UnchainedStaking.Contract.RenounceOwnership(&_UnchainedStaking.TransactOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _UnchainedStaking.Contract.RenounceOwnership(&_UnchainedStaking.TransactOpts) -} - -// SetBlsAddress is a paid mutator transaction binding the contract method 0x3e5d4675. -// -// Solidity: function setBlsAddress(bytes20 blsAddress) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) SetBlsAddress(opts *bind.TransactOpts, blsAddress [20]byte) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "setBlsAddress", blsAddress) -} - -// SetBlsAddress is a paid mutator transaction binding the contract method 0x3e5d4675. -// -// Solidity: function setBlsAddress(bytes20 blsAddress) returns() -func (_UnchainedStaking *UnchainedStakingSession) SetBlsAddress(blsAddress [20]byte) (*types.Transaction, error) { - return _UnchainedStaking.Contract.SetBlsAddress(&_UnchainedStaking.TransactOpts, blsAddress) -} - -// SetBlsAddress is a paid mutator transaction binding the contract method 0x3e5d4675. -// -// Solidity: function setBlsAddress(bytes20 blsAddress) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) SetBlsAddress(blsAddress [20]byte) (*types.Transaction, error) { - return _UnchainedStaking.Contract.SetBlsAddress(&_UnchainedStaking.TransactOpts, blsAddress) -} - -// SetNftPrices is a paid mutator transaction binding the contract method 0xd43d8d1e. -// -// Solidity: function setNftPrices((address,uint256,uint256,uint256)[] eip712SetNftPrices, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) SetNftPrices(opts *bind.TransactOpts, eip712SetNftPrices []UnchainedStakingEIP712SetNftPrice, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "setNftPrices", eip712SetNftPrices, signatures) -} - -// SetNftPrices is a paid mutator transaction binding the contract method 0xd43d8d1e. -// -// Solidity: function setNftPrices((address,uint256,uint256,uint256)[] eip712SetNftPrices, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingSession) SetNftPrices(eip712SetNftPrices []UnchainedStakingEIP712SetNftPrice, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.Contract.SetNftPrices(&_UnchainedStaking.TransactOpts, eip712SetNftPrices, signatures) -} - -// SetNftPrices is a paid mutator transaction binding the contract method 0xd43d8d1e. -// -// Solidity: function setNftPrices((address,uint256,uint256,uint256)[] eip712SetNftPrices, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) SetNftPrices(eip712SetNftPrices []UnchainedStakingEIP712SetNftPrice, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.Contract.SetNftPrices(&_UnchainedStaking.TransactOpts, eip712SetNftPrices, signatures) -} - -// SetParams is a paid mutator transaction binding the contract method 0x642ca50f. -// -// Solidity: function setParams((address,address,address,address,uint256,uint256,uint256)[] eip712SetParams, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) SetParams(opts *bind.TransactOpts, eip712SetParams []UnchainedStakingEIP712SetParams, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "setParams", eip712SetParams, signatures) -} - -// SetParams is a paid mutator transaction binding the contract method 0x642ca50f. -// -// Solidity: function setParams((address,address,address,address,uint256,uint256,uint256)[] eip712SetParams, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingSession) SetParams(eip712SetParams []UnchainedStakingEIP712SetParams, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.Contract.SetParams(&_UnchainedStaking.TransactOpts, eip712SetParams, signatures) -} - -// SetParams is a paid mutator transaction binding the contract method 0x642ca50f. -// -// Solidity: function setParams((address,address,address,address,uint256,uint256,uint256)[] eip712SetParams, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) SetParams(eip712SetParams []UnchainedStakingEIP712SetParams, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.Contract.SetParams(&_UnchainedStaking.TransactOpts, eip712SetParams, signatures) -} - -// SetSigner is a paid mutator transaction binding the contract method 0xd9d35a4d. -// -// Solidity: function setSigner((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) SetSigner(opts *bind.TransactOpts, eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "setSigner", eip712SetSigner, stakerSignature, signerSignature) -} - -// SetSigner is a paid mutator transaction binding the contract method 0xd9d35a4d. -// -// Solidity: function setSigner((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) returns() -func (_UnchainedStaking *UnchainedStakingSession) SetSigner(eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.Contract.SetSigner(&_UnchainedStaking.TransactOpts, eip712SetSigner, stakerSignature, signerSignature) -} - -// SetSigner is a paid mutator transaction binding the contract method 0xd9d35a4d. -// -// Solidity: function setSigner((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) SetSigner(eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.Contract.SetSigner(&_UnchainedStaking.TransactOpts, eip712SetSigner, stakerSignature, signerSignature) -} - -// Stake is a paid mutator transaction binding the contract method 0x9debdddc. -// -// Solidity: function stake(uint256 duration, uint256 amount, uint256[] nftIds) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) Stake(opts *bind.TransactOpts, duration *big.Int, amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "stake", duration, amount, nftIds) -} - -// Stake is a paid mutator transaction binding the contract method 0x9debdddc. -// -// Solidity: function stake(uint256 duration, uint256 amount, uint256[] nftIds) returns() -func (_UnchainedStaking *UnchainedStakingSession) Stake(duration *big.Int, amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { - return _UnchainedStaking.Contract.Stake(&_UnchainedStaking.TransactOpts, duration, amount, nftIds) -} - -// Stake is a paid mutator transaction binding the contract method 0x9debdddc. -// -// Solidity: function stake(uint256 duration, uint256 amount, uint256[] nftIds) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) Stake(duration *big.Int, amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { - return _UnchainedStaking.Contract.Stake(&_UnchainedStaking.TransactOpts, duration, amount, nftIds) -} - -// Transfer is a paid mutator transaction binding the contract method 0xdc668266. -// -// Solidity: function transfer((address,address,address,uint256,uint256[],uint256[])[] eip712Transferes, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) Transfer(opts *bind.TransactOpts, eip712Transferes []UnchainedStakingEIP712Transfer, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "transfer", eip712Transferes, signatures) -} - -// Transfer is a paid mutator transaction binding the contract method 0xdc668266. -// -// Solidity: function transfer((address,address,address,uint256,uint256[],uint256[])[] eip712Transferes, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingSession) Transfer(eip712Transferes []UnchainedStakingEIP712Transfer, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.Contract.Transfer(&_UnchainedStaking.TransactOpts, eip712Transferes, signatures) -} - -// Transfer is a paid mutator transaction binding the contract method 0xdc668266. -// -// Solidity: function transfer((address,address,address,uint256,uint256[],uint256[])[] eip712Transferes, (uint8,bytes32,bytes32)[] signatures) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) Transfer(eip712Transferes []UnchainedStakingEIP712Transfer, signatures []UnchainedStakingSignature) (*types.Transaction, error) { - return _UnchainedStaking.Contract.Transfer(&_UnchainedStaking.TransactOpts, eip712Transferes, signatures) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UnchainedStaking *UnchainedStakingTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "transferOwnership", newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UnchainedStaking *UnchainedStakingSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _UnchainedStaking.Contract.TransferOwnership(&_UnchainedStaking.TransactOpts, newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _UnchainedStaking.Contract.TransferOwnership(&_UnchainedStaking.TransactOpts, newOwner) -} - -// Unstake is a paid mutator transaction binding the contract method 0x2def6620. -// -// Solidity: function unstake() returns() -func (_UnchainedStaking *UnchainedStakingTransactor) Unstake(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UnchainedStaking.contract.Transact(opts, "unstake") -} - -// Unstake is a paid mutator transaction binding the contract method 0x2def6620. -// -// Solidity: function unstake() returns() -func (_UnchainedStaking *UnchainedStakingSession) Unstake() (*types.Transaction, error) { - return _UnchainedStaking.Contract.Unstake(&_UnchainedStaking.TransactOpts) -} - -// Unstake is a paid mutator transaction binding the contract method 0x2def6620. -// -// Solidity: function unstake() returns() -func (_UnchainedStaking *UnchainedStakingTransactorSession) Unstake() (*types.Transaction, error) { - return _UnchainedStaking.Contract.Unstake(&_UnchainedStaking.TransactOpts) -} - -// UnchainedStakingBlsAddressChangedIterator is returned from FilterBlsAddressChanged and is used to iterate over the raw logs and unpacked data for BlsAddressChanged events raised by the UnchainedStaking contract. -type UnchainedStakingBlsAddressChangedIterator struct { - Event *UnchainedStakingBlsAddressChanged // 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 *UnchainedStakingBlsAddressChangedIterator) 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(UnchainedStakingBlsAddressChanged) - 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(UnchainedStakingBlsAddressChanged) - 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 *UnchainedStakingBlsAddressChangedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingBlsAddressChangedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingBlsAddressChanged represents a BlsAddressChanged event raised by the UnchainedStaking contract. -type UnchainedStakingBlsAddressChanged struct { - User common.Address - From [32]byte - To [32]byte - Raw types.Log // Blockchain specific contextual infos -} - -// FilterBlsAddressChanged is a free log retrieval operation binding the contract event 0xa5c20a3e40dbfce0ccdadcb27e2f561e84ddf0618a41338cc1acb1524780ff39. -// -// Solidity: event BlsAddressChanged(address indexed user, bytes32 indexed from, bytes32 indexed to) -func (_UnchainedStaking *UnchainedStakingFilterer) FilterBlsAddressChanged(opts *bind.FilterOpts, user []common.Address, from [][32]byte, to [][32]byte) (*UnchainedStakingBlsAddressChangedIterator, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } - - logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "BlsAddressChanged", userRule, fromRule, toRule) - if err != nil { - return nil, err - } - return &UnchainedStakingBlsAddressChangedIterator{contract: _UnchainedStaking.contract, event: "BlsAddressChanged", logs: logs, sub: sub}, nil -} - -// WatchBlsAddressChanged is a free log subscription operation binding the contract event 0xa5c20a3e40dbfce0ccdadcb27e2f561e84ddf0618a41338cc1acb1524780ff39. -// -// Solidity: event BlsAddressChanged(address indexed user, bytes32 indexed from, bytes32 indexed to) -func (_UnchainedStaking *UnchainedStakingFilterer) WatchBlsAddressChanged(opts *bind.WatchOpts, sink chan<- *UnchainedStakingBlsAddressChanged, user []common.Address, from [][32]byte, to [][32]byte) (event.Subscription, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - var fromRule []interface{} - for _, fromItem := range from { - fromRule = append(fromRule, fromItem) - } - var toRule []interface{} - for _, toItem := range to { - toRule = append(toRule, toItem) - } - - logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "BlsAddressChanged", userRule, fromRule, toRule) - 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(UnchainedStakingBlsAddressChanged) - if err := _UnchainedStaking.contract.UnpackLog(event, "BlsAddressChanged", 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 -} - -// ParseBlsAddressChanged is a log parse operation binding the contract event 0xa5c20a3e40dbfce0ccdadcb27e2f561e84ddf0618a41338cc1acb1524780ff39. -// -// Solidity: event BlsAddressChanged(address indexed user, bytes32 indexed from, bytes32 indexed to) -func (_UnchainedStaking *UnchainedStakingFilterer) ParseBlsAddressChanged(log types.Log) (*UnchainedStakingBlsAddressChanged, error) { - event := new(UnchainedStakingBlsAddressChanged) - if err := _UnchainedStaking.contract.UnpackLog(event, "BlsAddressChanged", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// UnchainedStakingExtendedIterator is returned from FilterExtended and is used to iterate over the raw logs and unpacked data for Extended events raised by the UnchainedStaking contract. -type UnchainedStakingExtendedIterator struct { - Event *UnchainedStakingExtended // 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 *UnchainedStakingExtendedIterator) 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(UnchainedStakingExtended) - 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(UnchainedStakingExtended) - 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 *UnchainedStakingExtendedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingExtendedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingExtended represents a Extended event raised by the UnchainedStaking contract. -type UnchainedStakingExtended struct { - User common.Address - Unlock *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterExtended is a free log retrieval operation binding the contract event 0xa29fc12cda82ff659de006abb10fa5ee256d922af1661e395e5f2fb6b004387e. -// -// Solidity: event Extended(address indexed user, uint256 unlock) -func (_UnchainedStaking *UnchainedStakingFilterer) FilterExtended(opts *bind.FilterOpts, user []common.Address) (*UnchainedStakingExtendedIterator, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - - logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "Extended", userRule) - if err != nil { - return nil, err - } - return &UnchainedStakingExtendedIterator{contract: _UnchainedStaking.contract, event: "Extended", logs: logs, sub: sub}, nil -} - -// WatchExtended is a free log subscription operation binding the contract event 0xa29fc12cda82ff659de006abb10fa5ee256d922af1661e395e5f2fb6b004387e. -// -// Solidity: event Extended(address indexed user, uint256 unlock) -func (_UnchainedStaking *UnchainedStakingFilterer) WatchExtended(opts *bind.WatchOpts, sink chan<- *UnchainedStakingExtended, user []common.Address) (event.Subscription, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - - logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "Extended", userRule) - 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(UnchainedStakingExtended) - if err := _UnchainedStaking.contract.UnpackLog(event, "Extended", 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 -} - -// ParseExtended is a log parse operation binding the contract event 0xa29fc12cda82ff659de006abb10fa5ee256d922af1661e395e5f2fb6b004387e. -// -// Solidity: event Extended(address indexed user, uint256 unlock) -func (_UnchainedStaking *UnchainedStakingFilterer) ParseExtended(log types.Log) (*UnchainedStakingExtended, error) { - event := new(UnchainedStakingExtended) - if err := _UnchainedStaking.contract.UnpackLog(event, "Extended", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// UnchainedStakingOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the UnchainedStaking contract. -type UnchainedStakingOwnershipTransferredIterator struct { - Event *UnchainedStakingOwnershipTransferred // 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 *UnchainedStakingOwnershipTransferredIterator) 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(UnchainedStakingOwnershipTransferred) - 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(UnchainedStakingOwnershipTransferred) - 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 *UnchainedStakingOwnershipTransferredIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingOwnershipTransferred represents a OwnershipTransferred event raised by the UnchainedStaking contract. -type UnchainedStakingOwnershipTransferred 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 (_UnchainedStaking *UnchainedStakingFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*UnchainedStakingOwnershipTransferredIterator, 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 := _UnchainedStaking.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) - if err != nil { - return nil, err - } - return &UnchainedStakingOwnershipTransferredIterator{contract: _UnchainedStaking.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 (_UnchainedStaking *UnchainedStakingFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *UnchainedStakingOwnershipTransferred, 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 := _UnchainedStaking.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(UnchainedStakingOwnershipTransferred) - if err := _UnchainedStaking.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 (_UnchainedStaking *UnchainedStakingFilterer) ParseOwnershipTransferred(log types.Log) (*UnchainedStakingOwnershipTransferred, error) { - event := new(UnchainedStakingOwnershipTransferred) - if err := _UnchainedStaking.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// UnchainedStakingParamsChangedIterator is returned from FilterParamsChanged and is used to iterate over the raw logs and unpacked data for ParamsChanged events raised by the UnchainedStaking contract. -type UnchainedStakingParamsChangedIterator struct { - Event *UnchainedStakingParamsChanged // 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 *UnchainedStakingParamsChangedIterator) 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(UnchainedStakingParamsChanged) - 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(UnchainedStakingParamsChanged) - 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 *UnchainedStakingParamsChangedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingParamsChangedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingParamsChanged represents a ParamsChanged event raised by the UnchainedStaking contract. -type UnchainedStakingParamsChanged struct { - Token common.Address - Nft common.Address - NftTracker common.Address - Threshold *big.Int - Expiration *big.Int - Voted *big.Int - Nonce *big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterParamsChanged is a free log retrieval operation binding the contract event 0xcccaeb9d161525e3f31950313467c2e9a945a55a1ff09658479fe753054fafe0. -// -// Solidity: event ParamsChanged(address token, address nft, address nftTracker, uint256 threshold, uint256 expiration, uint256 voted, uint256 nonce) -func (_UnchainedStaking *UnchainedStakingFilterer) FilterParamsChanged(opts *bind.FilterOpts) (*UnchainedStakingParamsChangedIterator, error) { - - logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "ParamsChanged") - if err != nil { - return nil, err - } - return &UnchainedStakingParamsChangedIterator{contract: _UnchainedStaking.contract, event: "ParamsChanged", logs: logs, sub: sub}, nil -} - -// WatchParamsChanged is a free log subscription operation binding the contract event 0xcccaeb9d161525e3f31950313467c2e9a945a55a1ff09658479fe753054fafe0. -// -// Solidity: event ParamsChanged(address token, address nft, address nftTracker, uint256 threshold, uint256 expiration, uint256 voted, uint256 nonce) -func (_UnchainedStaking *UnchainedStakingFilterer) WatchParamsChanged(opts *bind.WatchOpts, sink chan<- *UnchainedStakingParamsChanged) (event.Subscription, error) { - - logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "ParamsChanged") - 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(UnchainedStakingParamsChanged) - if err := _UnchainedStaking.contract.UnpackLog(event, "ParamsChanged", 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 -} - -// ParseParamsChanged is a log parse operation binding the contract event 0xcccaeb9d161525e3f31950313467c2e9a945a55a1ff09658479fe753054fafe0. -// -// Solidity: event ParamsChanged(address token, address nft, address nftTracker, uint256 threshold, uint256 expiration, uint256 voted, uint256 nonce) -func (_UnchainedStaking *UnchainedStakingFilterer) ParseParamsChanged(log types.Log) (*UnchainedStakingParamsChanged, error) { - event := new(UnchainedStakingParamsChanged) - if err := _UnchainedStaking.contract.UnpackLog(event, "ParamsChanged", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// UnchainedStakingSignerChangedIterator is returned from FilterSignerChanged and is used to iterate over the raw logs and unpacked data for SignerChanged events raised by the UnchainedStaking contract. -type UnchainedStakingSignerChangedIterator struct { - Event *UnchainedStakingSignerChanged // 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 *UnchainedStakingSignerChangedIterator) 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(UnchainedStakingSignerChanged) - 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(UnchainedStakingSignerChanged) - 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 *UnchainedStakingSignerChangedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingSignerChangedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingSignerChanged represents a SignerChanged event raised by the UnchainedStaking contract. -type UnchainedStakingSignerChanged struct { - Staker common.Address - Signer common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterSignerChanged is a free log retrieval operation binding the contract event 0xeeb293e1f8f3a9db91ade748726387ed1352ca78f5430c5f06fe3d1e1ad50579. -// -// Solidity: event SignerChanged(address indexed staker, address indexed signer) -func (_UnchainedStaking *UnchainedStakingFilterer) FilterSignerChanged(opts *bind.FilterOpts, staker []common.Address, signer []common.Address) (*UnchainedStakingSignerChangedIterator, error) { - - var stakerRule []interface{} - for _, stakerItem := range staker { - stakerRule = append(stakerRule, stakerItem) - } - var signerRule []interface{} - for _, signerItem := range signer { - signerRule = append(signerRule, signerItem) - } - - logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "SignerChanged", stakerRule, signerRule) - if err != nil { - return nil, err - } - return &UnchainedStakingSignerChangedIterator{contract: _UnchainedStaking.contract, event: "SignerChanged", logs: logs, sub: sub}, nil -} - -// WatchSignerChanged is a free log subscription operation binding the contract event 0xeeb293e1f8f3a9db91ade748726387ed1352ca78f5430c5f06fe3d1e1ad50579. -// -// Solidity: event SignerChanged(address indexed staker, address indexed signer) -func (_UnchainedStaking *UnchainedStakingFilterer) WatchSignerChanged(opts *bind.WatchOpts, sink chan<- *UnchainedStakingSignerChanged, staker []common.Address, signer []common.Address) (event.Subscription, error) { - - var stakerRule []interface{} - for _, stakerItem := range staker { - stakerRule = append(stakerRule, stakerItem) - } - var signerRule []interface{} - for _, signerItem := range signer { - signerRule = append(signerRule, signerItem) - } - - logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "SignerChanged", stakerRule, signerRule) - 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(UnchainedStakingSignerChanged) - if err := _UnchainedStaking.contract.UnpackLog(event, "SignerChanged", 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 -} - -// ParseSignerChanged is a log parse operation binding the contract event 0xeeb293e1f8f3a9db91ade748726387ed1352ca78f5430c5f06fe3d1e1ad50579. -// -// Solidity: event SignerChanged(address indexed staker, address indexed signer) -func (_UnchainedStaking *UnchainedStakingFilterer) ParseSignerChanged(log types.Log) (*UnchainedStakingSignerChanged, error) { - event := new(UnchainedStakingSignerChanged) - if err := _UnchainedStaking.contract.UnpackLog(event, "SignerChanged", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// UnchainedStakingStakeIncreasedIterator is returned from FilterStakeIncreased and is used to iterate over the raw logs and unpacked data for StakeIncreased events raised by the UnchainedStaking contract. -type UnchainedStakingStakeIncreasedIterator struct { - Event *UnchainedStakingStakeIncreased // 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 *UnchainedStakingStakeIncreasedIterator) 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(UnchainedStakingStakeIncreased) - 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(UnchainedStakingStakeIncreased) - 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 *UnchainedStakingStakeIncreasedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingStakeIncreasedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingStakeIncreased represents a StakeIncreased event raised by the UnchainedStaking contract. -type UnchainedStakingStakeIncreased struct { - User common.Address - Amount *big.Int - NftIds []*big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterStakeIncreased is a free log retrieval operation binding the contract event 0x26e4d06799c60ba22ec168ee4a9314ed451cf9c78dbf6a5f7bfeaf3c84688f58. -// -// Solidity: event StakeIncreased(address indexed user, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) FilterStakeIncreased(opts *bind.FilterOpts, user []common.Address) (*UnchainedStakingStakeIncreasedIterator, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - - logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "StakeIncreased", userRule) - if err != nil { - return nil, err - } - return &UnchainedStakingStakeIncreasedIterator{contract: _UnchainedStaking.contract, event: "StakeIncreased", logs: logs, sub: sub}, nil -} - -// WatchStakeIncreased is a free log subscription operation binding the contract event 0x26e4d06799c60ba22ec168ee4a9314ed451cf9c78dbf6a5f7bfeaf3c84688f58. -// -// Solidity: event StakeIncreased(address indexed user, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) WatchStakeIncreased(opts *bind.WatchOpts, sink chan<- *UnchainedStakingStakeIncreased, user []common.Address) (event.Subscription, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - - logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "StakeIncreased", userRule) - 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(UnchainedStakingStakeIncreased) - if err := _UnchainedStaking.contract.UnpackLog(event, "StakeIncreased", 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 -} - -// ParseStakeIncreased is a log parse operation binding the contract event 0x26e4d06799c60ba22ec168ee4a9314ed451cf9c78dbf6a5f7bfeaf3c84688f58. -// -// Solidity: event StakeIncreased(address indexed user, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) ParseStakeIncreased(log types.Log) (*UnchainedStakingStakeIncreased, error) { - event := new(UnchainedStakingStakeIncreased) - if err := _UnchainedStaking.contract.UnpackLog(event, "StakeIncreased", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// UnchainedStakingStakedIterator is returned from FilterStaked and is used to iterate over the raw logs and unpacked data for Staked events raised by the UnchainedStaking contract. -type UnchainedStakingStakedIterator struct { - Event *UnchainedStakingStaked // 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 *UnchainedStakingStakedIterator) 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(UnchainedStakingStaked) - 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(UnchainedStakingStaked) - 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 *UnchainedStakingStakedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingStakedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingStaked represents a Staked event raised by the UnchainedStaking contract. -type UnchainedStakingStaked struct { - User common.Address - Unlock *big.Int - Amount *big.Int - NftIds []*big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterStaked is a free log retrieval operation binding the contract event 0x5df5de9ccb680fe3d60088f6d4c3b6d535074c704699377046c743a5b276e171. -// -// Solidity: event Staked(address indexed user, uint256 unlock, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) FilterStaked(opts *bind.FilterOpts, user []common.Address) (*UnchainedStakingStakedIterator, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - - logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "Staked", userRule) - if err != nil { - return nil, err - } - return &UnchainedStakingStakedIterator{contract: _UnchainedStaking.contract, event: "Staked", logs: logs, sub: sub}, nil -} - -// WatchStaked is a free log subscription operation binding the contract event 0x5df5de9ccb680fe3d60088f6d4c3b6d535074c704699377046c743a5b276e171. -// -// Solidity: event Staked(address indexed user, uint256 unlock, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) WatchStaked(opts *bind.WatchOpts, sink chan<- *UnchainedStakingStaked, user []common.Address) (event.Subscription, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - - logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "Staked", userRule) - 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(UnchainedStakingStaked) - if err := _UnchainedStaking.contract.UnpackLog(event, "Staked", 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 -} - -// ParseStaked is a log parse operation binding the contract event 0x5df5de9ccb680fe3d60088f6d4c3b6d535074c704699377046c743a5b276e171. -// -// Solidity: event Staked(address indexed user, uint256 unlock, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) ParseStaked(log types.Log) (*UnchainedStakingStaked, error) { - event := new(UnchainedStakingStaked) - if err := _UnchainedStaking.contract.UnpackLog(event, "Staked", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// UnchainedStakingTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the UnchainedStaking contract. -type UnchainedStakingTransferIterator struct { - Event *UnchainedStakingTransfer // 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 *UnchainedStakingTransferIterator) 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(UnchainedStakingTransfer) - 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(UnchainedStakingTransfer) - 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 *UnchainedStakingTransferIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingTransferIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingTransfer represents a Transfer event raised by the UnchainedStaking contract. -type UnchainedStakingTransfer struct { - From common.Address - To common.Address - Amount *big.Int - NftIds []*big.Int - Nonces []*big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterTransfer is a free log retrieval operation binding the contract event 0x26a79d74e745222aa0f380aabeac7f0a270b037daf3b5fb1b1b66ff7f4c3144f. -// -// Solidity: event Transfer(address from, address to, uint256 amount, uint256[] nftIds, uint256[] nonces) -func (_UnchainedStaking *UnchainedStakingFilterer) FilterTransfer(opts *bind.FilterOpts) (*UnchainedStakingTransferIterator, error) { - - logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "Transfer") - if err != nil { - return nil, err - } - return &UnchainedStakingTransferIterator{contract: _UnchainedStaking.contract, event: "Transfer", logs: logs, sub: sub}, nil -} - -// WatchTransfer is a free log subscription operation binding the contract event 0x26a79d74e745222aa0f380aabeac7f0a270b037daf3b5fb1b1b66ff7f4c3144f. -// -// Solidity: event Transfer(address from, address to, uint256 amount, uint256[] nftIds, uint256[] nonces) -func (_UnchainedStaking *UnchainedStakingFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *UnchainedStakingTransfer) (event.Subscription, error) { - - logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "Transfer") - 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(UnchainedStakingTransfer) - if err := _UnchainedStaking.contract.UnpackLog(event, "Transfer", 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 -} - -// ParseTransfer is a log parse operation binding the contract event 0x26a79d74e745222aa0f380aabeac7f0a270b037daf3b5fb1b1b66ff7f4c3144f. -// -// Solidity: event Transfer(address from, address to, uint256 amount, uint256[] nftIds, uint256[] nonces) -func (_UnchainedStaking *UnchainedStakingFilterer) ParseTransfer(log types.Log) (*UnchainedStakingTransfer, error) { - event := new(UnchainedStakingTransfer) - if err := _UnchainedStaking.contract.UnpackLog(event, "Transfer", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// UnchainedStakingUnStakedIterator is returned from FilterUnStaked and is used to iterate over the raw logs and unpacked data for UnStaked events raised by the UnchainedStaking contract. -type UnchainedStakingUnStakedIterator struct { - Event *UnchainedStakingUnStaked // 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 *UnchainedStakingUnStakedIterator) 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(UnchainedStakingUnStaked) - 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(UnchainedStakingUnStaked) - 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 *UnchainedStakingUnStakedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UnchainedStakingUnStakedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UnchainedStakingUnStaked represents a UnStaked event raised by the UnchainedStaking contract. -type UnchainedStakingUnStaked struct { - User common.Address - Amount *big.Int - NftIds []*big.Int - Raw types.Log // Blockchain specific contextual infos -} - -// FilterUnStaked is a free log retrieval operation binding the contract event 0xef4ce4a0205d268e0effbc76aaabb2ad2509ec58a2e9013645347d3c3cd9be42. -// -// Solidity: event UnStaked(address indexed user, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) FilterUnStaked(opts *bind.FilterOpts, user []common.Address) (*UnchainedStakingUnStakedIterator, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - - logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "UnStaked", userRule) - if err != nil { - return nil, err - } - return &UnchainedStakingUnStakedIterator{contract: _UnchainedStaking.contract, event: "UnStaked", logs: logs, sub: sub}, nil -} - -// WatchUnStaked is a free log subscription operation binding the contract event 0xef4ce4a0205d268e0effbc76aaabb2ad2509ec58a2e9013645347d3c3cd9be42. -// -// Solidity: event UnStaked(address indexed user, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) WatchUnStaked(opts *bind.WatchOpts, sink chan<- *UnchainedStakingUnStaked, user []common.Address) (event.Subscription, error) { - - var userRule []interface{} - for _, userItem := range user { - userRule = append(userRule, userItem) - } - - logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "UnStaked", userRule) - 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(UnchainedStakingUnStaked) - if err := _UnchainedStaking.contract.UnpackLog(event, "UnStaked", 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 -} - -// ParseUnStaked is a log parse operation binding the contract event 0xef4ce4a0205d268e0effbc76aaabb2ad2509ec58a2e9013645347d3c3cd9be42. -// -// Solidity: event UnStaked(address indexed user, uint256 amount, uint256[] nftIds) -func (_UnchainedStaking *UnchainedStakingFilterer) ParseUnStaked(log types.Log) (*UnchainedStakingUnStaked, error) { - event := new(UnchainedStakingUnStaked) - if err := _UnchainedStaking.contract.UnpackLog(event, "UnStaked", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} diff --git a/internal/crypto/ethereum/rpc.go b/internal/crypto/ethereum/rpc.go index f374a14b..bd811cc6 100644 --- a/internal/crypto/ethereum/rpc.go +++ b/internal/crypto/ethereum/rpc.go @@ -19,7 +19,7 @@ import ( type RPC interface { RefreshRPC(network string) GetClient(network string) *ethclient.Client - GetNewStakingContract(network string, address string, refresh bool) (*contracts.UnchainedStaking, error) + GetNewStakingContract(network string, address string, refresh bool) (*contracts.ProofOfStake, error) GetNewUniV3Contract(network string, address string, refresh bool) (*contracts.UniV3, error) GetBlockNumber(ctx context.Context, network string) (uint64, error) } @@ -72,7 +72,7 @@ func (r *repository) RefreshRPC(network string) { r.refreshRPCWithRetries(network, len(r.list)) } -func (r *repository) GetNewStakingContract(network string, address string, refresh bool) (*contracts.UnchainedStaking, error) { +func (r *repository) GetNewStakingContract(network string, address string, refresh bool) (*contracts.ProofOfStake, error) { if refresh { r.RefreshRPC(network) } @@ -82,7 +82,7 @@ func (r *repository) GetNewStakingContract(network string, address string, refre return nil, consts.ErrClientNotFound } - return contracts.NewUnchainedStaking(common.HexToAddress(address), client) + return contracts.NewProofOfStake(common.HexToAddress(address), client) } func (r *repository) GetNewUniV3Contract(network string, address string, refresh bool) (*contracts.UniV3, error) { diff --git a/internal/crypto/ethereum/rpc_mock.go b/internal/crypto/ethereum/rpc_mock.go index 36df1b39..4485b783 100644 --- a/internal/crypto/ethereum/rpc_mock.go +++ b/internal/crypto/ethereum/rpc_mock.go @@ -22,8 +22,8 @@ func (m mockRPC) GetClient(_ string) *ethclient.Client { func (m mockRPC) RefreshRPC(_ string) {} -func (m mockRPC) GetNewStakingContract(_ string, address string, _ bool) (*contracts.UnchainedStaking, error) { - return contracts.NewUnchainedStaking( +func (m mockRPC) GetNewStakingContract(_ string, address string, _ bool) (*contracts.ProofOfStake, error) { + return contracts.NewProofOfStake( common.HexToAddress(address), m.backend, ) diff --git a/internal/service/correctness/correctness.go b/internal/service/correctness/correctness.go index a9c20a35..d40892dc 100644 --- a/internal/service/correctness/correctness.go +++ b/internal/service/correctness/correctness.go @@ -120,7 +120,7 @@ func (s *service) RecordSignature( voted = *big.NewInt(0) } - votingPower, err := s.pos.GetVotingPowerOfPublicKey(ctx, signer.PublicKey) + votingPower, err := s.pos.GetVotingPowerOfEvm(ctx, signer.EvmAddress) if err != nil { utils.Logger. With("Address", address.Calculate(signer.PublicKey[:])). diff --git a/internal/service/evmlog/record.go b/internal/service/evmlog/record.go index c59d03c2..df287afe 100644 --- a/internal/service/evmlog/record.go +++ b/internal/service/evmlog/record.go @@ -65,7 +65,7 @@ func (s *service) RecordSignature( s.consensus.Add(key, make(map[bls12381.G1Affine]big.Int)) } - votingPower, err := s.pos.GetVotingPowerOfPublicKey(ctx, signer.PublicKey) + votingPower, err := s.pos.GetVotingPowerOfEvm(ctx, signer.EvmAddress) if err != nil { utils.Logger. With("Address", address.Calculate(signer.PublicKey[:])). diff --git a/internal/service/pos/eip712.go b/internal/service/pos/eip712.go index 9c42bc7b..aea5c6df 100644 --- a/internal/service/pos/eip712.go +++ b/internal/service/pos/eip712.go @@ -4,81 +4,9 @@ import ( "context" "math/big" - "github.com/TimeleapLabs/unchained/internal/utils" - - "github.com/TimeleapLabs/unchained/internal/crypto/ethereum/contracts" - - "github.com/TimeleapLabs/unchained/internal/config" - "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" ) func (s *service) Slash(ctx context.Context, address [20]byte, to common.Address, amount *big.Int, nftIDs []*big.Int) error { - evmAddress, err := s.posContract.EvmAddressOf(nil, address) - - if err != nil { - utils.Logger. - With("Error", err). - Error("Failed to get EVM address of the staker") - return err - } - - transfer := contracts.UnchainedStakingEIP712Transfer{ - From: evmAddress, - To: to, - Amount: amount, - NftIds: nftIDs, - } - - signature, err := s.eip712Signer.SignTransferRequest(&transfer) - - if err != nil { - utils.Logger. - With("Error", err). - Error("Failed to sign transfer request") - return err - } - - tx, err := s.posContract.Transfer( - nil, - []contracts.UnchainedStakingEIP712Transfer{transfer}, - []contracts.UnchainedStakingSignature{*signature}, - ) - - if err != nil { - utils.Logger. - With("Error", err). - Error("Failed to transfer") - return err - } - - receipt, err := bind.WaitMined( - ctx, - s.ethRPC.GetClient(config.App.ProofOfStake.Chain), - tx, - ) - - if err != nil { - utils.Logger. - With("Error", err). - Error("Failed to wait for transaction to be mined") - return err - } - - if receipt.Status != types.ReceiptStatusSuccessful { - utils.Logger. - With("Error", err). - Error("Transaction failed") - return err - } - - utils.Logger. - With("Address", evmAddress.Hex()). - With("To", to.Hex()). - With("Amount", amount.String()). - With("NftIds", nftIDs). - Info("Slashed") - return nil } diff --git a/internal/service/pos/eip712/sign.go b/internal/service/pos/eip712/sign.go index e10a8114..113e6e88 100644 --- a/internal/service/pos/eip712/sign.go +++ b/internal/service/pos/eip712/sign.go @@ -1,14 +1,13 @@ package eip712 import ( + "fmt" "math/big" - "github.com/TimeleapLabs/unchained/internal/config" - "github.com/TimeleapLabs/unchained/internal/crypto" - - "github.com/TimeleapLabs/unchained/internal/crypto/ethereum/contracts" + "github.com/TimeleapLabs/unchained/internal/crypto/ethereum" "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/signer/core/apitypes" ) @@ -16,87 +15,32 @@ type Signer struct { domain apitypes.TypedDataDomain } -func (s *Signer) SignTransferRequest(request *contracts.UnchainedStakingEIP712Transfer) (*contracts.UnchainedStakingSignature, error) { - data := &apitypes.TypedData{ - Types: Types, - PrimaryType: "Transfer", - Domain: s.domain, - Message: map[string]interface{}{ - "signer": config.App.Secret.EvmAddress, - "from": request.From, - "to": request.To, - "amount": request.Amount, - "nftIds": request.NftIds, - "nonces": request.Nonces, - }, - } - - dataBytes, err := TypedDataToByte(data) +// TODO: Rewrite to use Schnorr signature scheme +func (s *Signer) SignEip712Message(evmSigner *ethereum.Signer, data *apitypes.TypedData) ([]byte, error) { + domainSeparator, err := data.HashStruct("EIP712Domain", data.Domain.Map()) if err != nil { return nil, err } - signedData, err := crypto.Identity.Eth.Sign(dataBytes) + typedDataHash, err := data.HashStruct(data.PrimaryType, data.Message) if err != nil { return nil, err } - return NewUnchainedSignatureFromBytes(signedData), nil -} - -func (s *Signer) SignSetParamsRequest(request *contracts.UnchainedStakingEIP712SetParams) (*contracts.UnchainedStakingSignature, error) { - data := &apitypes.TypedData{ - Types: Types, - PrimaryType: "SetParams", - Domain: s.domain, - Message: map[string]interface{}{ - "requester": config.App.Secret.EvmAddress, - "token": request.Token, - "nft": request.Nft, - "nftTracker": request.NftTracker, - "threshold": request.Threshold, - "expiration": request.Expiration, - "nonce": request.Nonce, - }, - } - - dataBytes, err := TypedDataToByte(data) - if err != nil { - return nil, err - } + message := []byte(fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash))) + messageHash := crypto.Keccak256(message) - signedData, err := crypto.Identity.Eth.Sign(dataBytes) + // This should be replaced with Schnorr signature scheme + signature, err := crypto.Sign(messageHash, evmSigner.PrivateKey) if err != nil { return nil, err } - return NewUnchainedSignatureFromBytes(signedData), nil -} - -func (s *Signer) SignSetNftPriceRequest(request *contracts.UnchainedStakingEIP712SetNftPrice) (*contracts.UnchainedStakingSignature, error) { - data := &apitypes.TypedData{ - Types: Types, - PrimaryType: "SetNftPrice", - Domain: s.domain, - Message: map[string]interface{}{ - "requester": config.App.Secret.EvmAddress, - "nftId": request.NftId, - "price": request.Price, - "nonce": request.Nonce, - }, - } - - dataBytes, err := TypedDataToByte(data) - if err != nil { - return nil, err - } - - signedData, err := crypto.Identity.Eth.Sign(dataBytes) - if err != nil { - return nil, err + if signature[64] < 27 { + signature[64] += 27 } - return NewUnchainedSignatureFromBytes(signedData), nil + return signature, nil } func New(chainID *big.Int, verifyingContract string) *Signer { diff --git a/internal/service/pos/pos.go b/internal/service/pos/pos.go index 6ee505b7..230be205 100644 --- a/internal/service/pos/pos.go +++ b/internal/service/pos/pos.go @@ -11,6 +11,8 @@ import ( "github.com/TimeleapLabs/unchained/internal/service/pos/eip712" "github.com/TimeleapLabs/unchained/internal/utils" "github.com/TimeleapLabs/unchained/internal/utils/address" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" "github.com/puzpuzpuz/xsync/v3" ) @@ -18,12 +20,14 @@ type Service interface { GetTotalVotingPower() (*big.Int, error) GetVotingPowerFromContract(address [20]byte, block *big.Int) (*big.Int, error) GetVotingPower(address [20]byte, block *big.Int) (*big.Int, error) + GetVotingPowerOfEvm(ctx context.Context, evmAddress string) (*big.Int, error) GetVotingPowerOfPublicKey(ctx context.Context, pkBytes [96]byte) (*big.Int, error) + GetSchnorrSigners(ctx context.Context) ([]common.Address, error) } type service struct { ethRPC ethereum.RPC - posContract *contracts.UnchainedStaking + posContract *contracts.ProofOfStake votingPowers *xsync.MapOf[[20]byte, *big.Int] lastUpdated *xsync.MapOf[[20]byte, *big.Int] base *big.Int @@ -31,19 +35,21 @@ type service struct { } func (s *service) GetTotalVotingPower() (*big.Int, error) { - return s.posContract.GetTotalVotingPower(nil) + return new(big.Int).Mul(big.NewInt(5e10), big.NewInt(1e18)), nil + //return s.posContract.GetTotalVotingPower(nil) } func (s *service) GetVotingPowerFromContract(address [20]byte, block *big.Int) (*big.Int, error) { - votingPower, err := s.posContract.GetVotingPower(nil, address) + stake, err := s.posContract.GetStake(nil, address) + //votingPower, err := s.posContract.GetVotingPower(nil, address) if err != nil { - return votingPower, err + return stake.Amount, err } - s.votingPowers.Store(address, votingPower) + s.votingPowers.Store(address, stake.Amount) s.lastUpdated.Store(address, block) - return votingPower, nil + return stake.Amount, nil } func (s *service) minBase(power *big.Int) *big.Int { @@ -74,6 +80,19 @@ func (s *service) GetVotingPower(address [20]byte, block *big.Int) (*big.Int, er return s.base, nil } +func (s *service) GetVotingPowerOfEvm(ctx context.Context, evmAddress string) (*big.Int, error) { + block, err := s.ethRPC.GetBlockNumber(ctx, config.App.ProofOfStake.Chain) + if err != nil { + return nil, err + } + address := common.HexToAddress(evmAddress) + return s.GetVotingPower(address, big.NewInt(int64(block))) +} + +func (s *service) GetSchnorrSigners(ctx context.Context) ([]common.Address, error) { + return s.posContract.GetValidators(&bind.CallOpts{Context: ctx}) +} + func (s *service) GetVotingPowerOfPublicKey(ctx context.Context, pkBytes [96]byte) (*big.Int, error) { _, addrHex := address.CalculateHex(pkBytes[:]) block, err := s.ethRPC.GetBlockNumber(ctx, config.App.ProofOfStake.Chain) @@ -132,15 +151,16 @@ func New(ethRPC ethereum.RPC) Service { With("Network", utils.BigIntToFloat(total)). Info("PoS") - chainID, err := s.posContract.GetChainId(nil) - if err != nil { - utils.Logger. - With("Error", err). - Error("Failed to get chain ID") + // chainID, err := s.posContract.GetChainId(nil) + // if err != nil { + // utils.Logger. + // With("Error", err). + // Error("Failed to get chain ID") - panic(err) - } + // panic(err) + // } + chainID := big.NewInt(421614) s.eip712Signer = eip712.New(chainID, config.App.ProofOfStake.Address) return s diff --git a/internal/service/uniswap/record.go b/internal/service/uniswap/record.go index 04c03f09..849142dc 100644 --- a/internal/service/uniswap/record.go +++ b/internal/service/uniswap/record.go @@ -58,7 +58,7 @@ func (s *service) RecordSignature( voted = *big.NewInt(0) } - votingPower, err := s.pos.GetVotingPowerOfPublicKey(ctx, signer.PublicKey) + votingPower, err := s.pos.GetVotingPowerOfEvm(ctx, signer.EvmAddress) if err != nil { utils.Logger. With("Address", address.Calculate(signer.PublicKey[:])). From 328c6b8ffcc5a5c66c81251ac8b3ce250c9f872c Mon Sep 17 00:00:00 2001 From: Pouya Date: Mon, 3 Jun 2024 13:43:32 +0200 Subject: [PATCH 15/29] =?UTF-8?q?=F0=9F=8E=A8=20style:=20fix=20lint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/service/pos/pos.go | 4 ++-- internal/service/pos/pos_mock.go | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/internal/service/pos/pos.go b/internal/service/pos/pos.go index 230be205..657a05c9 100644 --- a/internal/service/pos/pos.go +++ b/internal/service/pos/pos.go @@ -36,12 +36,12 @@ type service struct { func (s *service) GetTotalVotingPower() (*big.Int, error) { return new(big.Int).Mul(big.NewInt(5e10), big.NewInt(1e18)), nil - //return s.posContract.GetTotalVotingPower(nil) + // return s.posContract.GetTotalVotingPower(nil) } func (s *service) GetVotingPowerFromContract(address [20]byte, block *big.Int) (*big.Int, error) { stake, err := s.posContract.GetStake(nil, address) - //votingPower, err := s.posContract.GetVotingPower(nil, address) + // votingPower, err := s.posContract.GetVotingPower(nil, address) if err != nil { return stake.Amount, err } diff --git a/internal/service/pos/pos_mock.go b/internal/service/pos/pos_mock.go index b72480b7..06a088cb 100644 --- a/internal/service/pos/pos_mock.go +++ b/internal/service/pos/pos_mock.go @@ -4,6 +4,7 @@ import ( "context" "math/big" + "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/mock" ) @@ -30,3 +31,8 @@ func (m *MockService) GetVotingPowerOfPublicKey(_ context.Context, pkBytes [96]b args := m.Called(pkBytes) return big.NewInt(int64(args.Int(0))), args.Error(1) } + +func (m *MockService) GetSchnorrSigners(_ context.Context) ([]common.Address, error) { + args := m.Called() + return args.Get(0).([]common.Address), args.Error(1) +} From 38ee040140e5b4abfda4fc5bb026ff602f2b8bc6 Mon Sep 17 00:00:00 2001 From: Pouya Date: Mon, 3 Jun 2024 13:45:02 +0200 Subject: [PATCH 16/29] =?UTF-8?q?=E2=9C=85=20test:=20fix=20mock=20contract?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/service/pos/eip712.go | 2 +- internal/service/pos/pos_mock.go | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/service/pos/eip712.go b/internal/service/pos/eip712.go index aea5c6df..9168a31d 100644 --- a/internal/service/pos/eip712.go +++ b/internal/service/pos/eip712.go @@ -7,6 +7,6 @@ import ( "github.com/ethereum/go-ethereum/common" ) -func (s *service) Slash(ctx context.Context, address [20]byte, to common.Address, amount *big.Int, nftIDs []*big.Int) error { +func (s *service) Slash(_ context.Context, _ [20]byte, _ common.Address, _ *big.Int, _ []*big.Int) error { return nil } diff --git a/internal/service/pos/pos_mock.go b/internal/service/pos/pos_mock.go index 06a088cb..2021089b 100644 --- a/internal/service/pos/pos_mock.go +++ b/internal/service/pos/pos_mock.go @@ -27,6 +27,11 @@ func (m *MockService) GetVotingPower(address [20]byte, block *big.Int) (*big.Int return big.NewInt(int64(args.Int(0))), args.Error(1) } +func (m *MockService) GetVotingPowerOfEvm(address [20]byte, block *big.Int) (*big.Int, error) { + args := m.Called(address, block) + return big.NewInt(int64(args.Int(0))), args.Error(1) +} + func (m *MockService) GetVotingPowerOfPublicKey(_ context.Context, pkBytes [96]byte) (*big.Int, error) { args := m.Called(pkBytes) return big.NewInt(int64(args.Int(0))), args.Error(1) From b680a5917f8c68d19d3a816516a6edf0cbf373c2 Mon Sep 17 00:00:00 2001 From: Pouya Date: Mon, 3 Jun 2024 13:46:22 +0200 Subject: [PATCH 17/29] =?UTF-8?q?=E2=9C=85=20test:=20fix=20mock=20modules?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/service/pos/pos_mock.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/pos/pos_mock.go b/internal/service/pos/pos_mock.go index 2021089b..2cf30251 100644 --- a/internal/service/pos/pos_mock.go +++ b/internal/service/pos/pos_mock.go @@ -27,8 +27,8 @@ func (m *MockService) GetVotingPower(address [20]byte, block *big.Int) (*big.Int return big.NewInt(int64(args.Int(0))), args.Error(1) } -func (m *MockService) GetVotingPowerOfEvm(address [20]byte, block *big.Int) (*big.Int, error) { - args := m.Called(address, block) +func (m *MockService) GetVotingPowerOfEvm(ctx context.Context, evmAddress string) (*big.Int, error) { + args := m.Called(ctx, evmAddress) return big.NewInt(int64(args.Int(0))), args.Error(1) } From b22bee0dbb01e0ed63c2bb90539701a7e1393c59 Mon Sep 17 00:00:00 2001 From: Nathalie Casati Date: Sun, 28 Apr 2024 20:17:32 +0200 Subject: [PATCH 18/29] fix: display help correctly when no arguments are entered --- docker/unchained.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/unchained.sh b/docker/unchained.sh index ed549f15..a2a3bc45 100755 --- a/docker/unchained.sh +++ b/docker/unchained.sh @@ -30,7 +30,7 @@ if ! docker compose version &>/dev/null; then exit 1 fi -if [ ! $1 == 'worker' ] && [ ! $1 == 'standalone' ]; then #&& [ ! $1 == 'remote' ] && [ ! $1 == 'lite' ] || [ -z $2 ]; then +if [ ! $1 == 'worker' ] && [ ! $1 == 'standalone' ] || [ -z $1 ] || [ -z $2 ] ; then #&& [ ! $1 == 'remote' ] && [ ! $1 == 'lite' ] || [ -z $2 ]; then usage exit 1 fi From 0bc74d44450b780063210cc8924467fc33453b7c Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Sat, 11 May 2024 19:21:08 +0330 Subject: [PATCH 19/29] =?UTF-8?q?=E2=9C=A8=20feat(signers):=20gather=20all?= =?UTF-8?q?=20signers=20behind=20an=20interface=20and=20write=20first=20im?= =?UTF-8?q?plmnt=20of=20tss=20>>>=20=E2=8F=B0=202d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/handler/broker.go | 2 +- cmd/handler/consumer.go | 2 +- go.mod | 12 +- internal/crypto/ethereum/identity.go | 2 +- internal/crypto/identity.go | 21 ++-- internal/crypto/tss/identity.go | 158 +++++++++++++++++++++++++++ internal/crypto/tss/identity_test.go | 125 +++++++++++++++++++++ 7 files changed, 307 insertions(+), 15 deletions(-) create mode 100644 internal/crypto/tss/identity.go create mode 100644 internal/crypto/tss/identity_test.go diff --git a/cmd/handler/broker.go b/cmd/handler/broker.go index 33a48403..9e95a507 100644 --- a/cmd/handler/broker.go +++ b/cmd/handler/broker.go @@ -28,7 +28,7 @@ func WithBrokerCmd(cmd *cobra.Command) { cmd.AddCommand(broker) } -// init loads CLI flags of broker command. +// init loads CLI flags of broker command func init() { broker.Flags().StringP( "broker", diff --git a/cmd/handler/consumer.go b/cmd/handler/consumer.go index b62e0444..e6e1ea95 100644 --- a/cmd/handler/consumer.go +++ b/cmd/handler/consumer.go @@ -34,7 +34,7 @@ func WithConsumerCmd(cmd *cobra.Command) { cmd.AddCommand(consumer) } -// init loads CLI flags of consumer command. +// init loads CLI flags of consumer command func init() { consumer.Flags().StringP( "broker", diff --git a/go.mod b/go.mod index 8ceadd97..2df968d1 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( entgo.io/contrib v0.4.6-0.20240215171353-eff33e4dca0b entgo.io/ent v0.13.1 github.com/99designs/gqlgen v0.17.45 + github.com/bnb-chain/tss-lib v1.3.5 github.com/btcsuite/btcutil v1.0.2 github.com/bytemare/crypto v0.5.2 github.com/bytemare/frost v0.0.0-20231127024126-bc6f7874b253 @@ -18,10 +19,12 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/ilyakaznacheev/cleanenv v1.5.0 github.com/jackc/pgx/v5 v5.5.5 + github.com/lastingasset/tss-lib v0.0.0-20221022151431-0bdbdcdfba56 github.com/lib/pq v1.10.9 github.com/lmittmann/tint v1.0.4 github.com/mattn/go-colorable v0.1.13 github.com/peterldowns/pgtestdb v0.0.14 + github.com/pkg/errors v0.9.1 github.com/pouya-eghbali/go-sia/v2 v2.1.0 github.com/puzpuzpuz/xsync/v3 v3.1.0 github.com/spf13/cobra v1.8.0 @@ -42,6 +45,7 @@ require ( github.com/Microsoft/go-winio v0.6.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect github.com/agext/levenshtein v1.2.3 // indirect + github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -52,6 +56,8 @@ require ( github.com/bytemare/hash2curve v0.2.2 // indirect github.com/bytemare/secp256k1 v0.1.0 // indirect github.com/bytemare/secret-sharing v0.1.0 // indirect + github.com/btcsuite/btcd v0.20.1-beta // indirect + github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cockroachdb/errors v1.8.1 // indirect github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f // indirect @@ -65,6 +71,7 @@ require ( github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect + github.com/decred/dcrd/dcrec/edwards/v2 v2.0.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect @@ -94,6 +101,7 @@ require ( github.com/holiman/uint256 v1.2.4 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/ipfs/go-log v0.0.1 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect @@ -111,7 +119,8 @@ require ( github.com/mitchellh/pointerstructure v1.2.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/pkg/errors v0.9.1 // indirect + github.com/opentracing/opentracing-go v1.1.0 // indirect + github.com/otiai10/primes v0.0.0-20180210170552-f6d2a1ba97c4 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.12.0 // indirect github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a // indirect @@ -135,6 +144,7 @@ require ( github.com/urfave/cli/v2 v2.27.1 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zclconf/go-cty v1.14.4 // indirect diff --git a/internal/crypto/ethereum/identity.go b/internal/crypto/ethereum/identity.go index 84a9c56a..2e9246f7 100644 --- a/internal/crypto/ethereum/identity.go +++ b/internal/crypto/ethereum/identity.go @@ -16,7 +16,7 @@ type Signer struct { Address string } -func (s *Signer) Verify(_ []byte, _ []byte, _ []byte) (bool, error) { +func (s *Signer) Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) { // TODO implement me panic("implement me") } diff --git a/internal/crypto/identity.go b/internal/crypto/identity.go index 53674c43..431deb24 100644 --- a/internal/crypto/identity.go +++ b/internal/crypto/identity.go @@ -6,6 +6,7 @@ import ( "github.com/TimeleapLabs/unchained/internal/config" "github.com/TimeleapLabs/unchained/internal/crypto/bls" "github.com/TimeleapLabs/unchained/internal/crypto/ethereum" + "github.com/TimeleapLabs/unchained/internal/crypto/tss" "github.com/TimeleapLabs/unchained/internal/model" ) @@ -20,6 +21,7 @@ type Signer interface { type MachineIdentity struct { Bls Signer Eth Signer + Tss Signer } // Identity is a global variable that holds machine identity. @@ -71,17 +73,14 @@ func WithEvmSigner() func(machineIdentity *MachineIdentity) error { } // WithTssSigner initialize and will add Tss identity to machine identity. -// func WithTssSigner(signers []string, minThreshold int) func(machineIdentity *MachineIdentity) error { -// return func(machineIdentity *MachineIdentity) error { -// machineIdentity.Tss = tss.NewIdentity( -// signers, -// minThreshold, -// ) -// //machineIdentity.Tss.WriteConfigs() -// -// return nil -// } -//} +func WithTssSigner(signers []string, minThreshold int) func(machineIdentity *MachineIdentity) error { + return func(machineIdentity *MachineIdentity) error { + machineIdentity.Tss = tss.NewIdentity(signers, minThreshold) + //machineIdentity.Tss.WriteConfigs() + + return nil + } +} // WithBlsIdentity initialize and will add Bls identity to machine identity. func WithBlsIdentity() func(machineIdentity *MachineIdentity) error { diff --git a/internal/crypto/tss/identity.go b/internal/crypto/tss/identity.go new file mode 100644 index 00000000..4afa40e0 --- /dev/null +++ b/internal/crypto/tss/identity.go @@ -0,0 +1,158 @@ +package tss + +import ( + "github.com/TimeleapLabs/unchained/internal/consts" + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/bnb-chain/tss-lib/common" + "github.com/bnb-chain/tss-lib/ecdsa/keygen" + "github.com/bnb-chain/tss-lib/ecdsa/signing" + "github.com/bnb-chain/tss-lib/tss" + "math/big" +) + +// Signer represents a TSS identity. +type Signer struct { + ctx *tss.PeerContext + PartyID *tss.PartyID + keyParty *keygen.LocalParty + localPartySaved *keygen.LocalPartySaveData + result chan keygen.LocalPartySaveData + minThreshold int + numberOfPeers int +} + +type MessageSigner struct { + party *signing.LocalParty +} + +func (s *Signer) Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) { + //TODO implement me + panic("implement me") +} + +func (s *Signer) WriteConfigs() { + //TODO implement me + panic("implement me") +} + +// NewSigning will sign a data with tss secret and return signed data. +func (s *Signer) NewSigning(data []byte, out chan tss.Message, end chan<- common.SignatureData) (*MessageSigner, error) { + if !s.localPartySaved.ValidateWithProof() { + return &MessageSigner{}, consts.ErrSignerIsNotReady + } + + dataBig := new(big.Int).SetBytes(data) + + params := tss.NewParameters(tss.S256(), s.ctx, s.PartyID, s.numberOfPeers, s.minThreshold) + signer := &MessageSigner{ + party: signing.NewLocalParty(dataBig, params, *s.localPartySaved, out, end).(*signing.LocalParty), + } + + go func(signer *MessageSigner) { + err := signer.party.Start() + if err != nil { + panic(err) + } + }(signer) + + return signer, nil +} + +func (s *MessageSigner) AckSignature(msg tss.Message) error { + if s.party.PartyID() == msg.GetFrom() { + return nil + } + + bz, _, err := msg.WireBytes() + if err != nil { + utils.Logger.Error(err.Error()) + return err + } + + pMsg, err := tss.ParseWireMessage(bz, msg.GetFrom(), msg.IsBroadcast()) + if err != nil { + utils.Logger.Error(err.Error()) + return err + } + + isOK, err := s.party.Update(pMsg) + if err != nil && !isOK { + utils.Logger.Error(err.Error()) + return err + } + + return nil +} + +func (s *Signer) Update(msg tss.Message) error { + if s.keyParty.PartyID() == msg.GetFrom() { + return nil + } + + bz, _, err := msg.WireBytes() + if err != nil { + utils.Logger.Error(err.Error()) + return err + } + + pMsg, err := tss.ParseWireMessage(bz, msg.GetFrom(), msg.IsBroadcast()) + if err != nil { + utils.Logger.Error(err.Error()) + return err + } + + isOK, err := s.keyParty.Update(pMsg) + if err != nil && !isOK { + utils.Logger.Error(err.Error()) + return err + } + + return nil +} + +// NewIdentity creates a new BLS identity. +func NewIdentity(signerID int, signers []string, outCh chan tss.Message, done chan struct{}, minThreshold int) *Signer { + partyIDs := make(tss.UnSortedPartyIDs, len(signers)) + for i, signer := range signers { + party := tss.NewPartyID(signer, signer, big.NewInt(int64(i+1))) + partyIDs[i] = party + } + + signer := &Signer{ + minThreshold: minThreshold, + numberOfPeers: len(signers), + //rawPartyID: signers[signerID], + PartyID: partyIDs[signerID], + result: make(chan keygen.LocalPartySaveData, len(signers)), + } + + sortedPartyIDs := tss.SortPartyIDs(partyIDs) + + signer.ctx = tss.NewPeerContext(sortedPartyIDs) + + signer.keyParty = keygen.NewLocalParty( + tss.NewParameters(tss.S256(), signer.ctx, sortedPartyIDs[signerID], len(signers), minThreshold), + outCh, + signer.result, + ).(*keygen.LocalParty) + + go func(signer *Signer) { + err := signer.keyParty.Start() + if err != nil { + panic(err) + } + utils.Logger.With("ID", signer.PartyID.Moniker).Info("New Tss party started") + + for { + select { + case save := <-signer.result: + signer.localPartySaved = &save + done <- struct{}{} + break + } + } + + }(signer) + + return signer +} diff --git a/internal/crypto/tss/identity_test.go b/internal/crypto/tss/identity_test.go new file mode 100644 index 00000000..9d25f842 --- /dev/null +++ b/internal/crypto/tss/identity_test.go @@ -0,0 +1,125 @@ +package tss + +import ( + "fmt" + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/bnb-chain/tss-lib/common" + "github.com/bnb-chain/tss-lib/tss" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + "testing" +) + +const ( + numOfSigners = 4 + minNumOfSigners = 2 +) + +var ( + testData = []byte("HELLO hello") + secondTestData = []byte("HELLO hello 2") + signers = []string{} +) + +type TssIdentityTestSuite struct { + suite.Suite + parties []*Signer +} + +func (s *TssIdentityTestSuite) SetupTest() { + utils.SetupLogger("info") + + for i := 0; i < numOfSigners; i++ { + signers = append(signers, fmt.Sprintf("signer-%d", i)) + } + + outCh := make(chan tss.Message, len(signers)) + wg := make(chan struct{}) + + for i := 0; i < numOfSigners; i++ { + party := NewIdentity(i, signers, outCh, wg, minNumOfSigners) + s.parties = append(s.parties, party) + } + + wait := 0 +keygen: + for { + select { + case msg := <-outCh: + dest := msg.GetTo() + + if dest == nil { // broadcast! + for _, P := range s.parties { + if P.PartyID.Index == msg.GetFrom().Index { + continue + } + + go P.Update(msg) + } + } else { // point-to-point! + if dest[0].Index == msg.GetFrom().Index { + fmt.Printf("party %d tried to send a message to itself (%d)", dest[0].Index, msg.GetFrom().Index) + return + } + go s.parties[dest[0].Index].Update(msg) + } + + case <-wg: + wait++ + if wait == numOfSigners { + break keygen + } + } + } +} + +func (s *TssIdentityTestSuite) TestSign() { + outCh := make(chan tss.Message, len(s.parties)) + endCh := make(chan common.SignatureData, len(s.parties)) + msgSigners := []*MessageSigner{} + + for i := 0; i < numOfSigners; i++ { + go func() { + signer, err := s.parties[i].NewSigning(testData, outCh, endCh) + assert.NoError(s.T(), err) + + msgSigners = append(msgSigners, signer) + }() + } + + // wait := 0 + //signing: + for { + select { + case msg := <-outCh: + dest := msg.GetTo() + if dest == nil { + for _, P := range msgSigners { + if P.party.PartyID().Index == msg.GetFrom().Index { + continue + } + + go P.AckSignature(msg) + } + } else { + if dest[0].Index == msg.GetFrom().Index { + common.Logger.Fatalf("party %d tried to send a message to itself (%d)", dest[0].Index, msg.GetFrom().Index) + } + + go msgSigners[dest[0].Index].AckSignature(msg) + } + case <-endCh: + fmt.Println("end") + } + } + + //s.Run("Should verify the message correctly", func() { + // isVerified, err := s.identity.Verify() + // assert.NoError(s.T(), err) + // assert.True(s.T(), isVerified) + //}) +} + +func TestTssIdentitySuite(t *testing.T) { + suite.Run(t, new(TssIdentityTestSuite)) +} From 9c476845e45418cf5168d6c515c86f486a7cb926 Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Sat, 18 May 2024 22:24:03 +0330 Subject: [PATCH 20/29] =?UTF-8?q?=E2=9C=A8=20feat(frost):=20remove=20tss?= =?UTF-8?q?=20signer=20and=20add=20frost=20algorithm=20>>>=20=E2=8F=B0=201?= =?UTF-8?q?.5d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/crypto/bls/bls.go | 47 ---- internal/crypto/bls/identity.go | 130 ---------- internal/crypto/bls/identity_test.go | 77 ------ internal/crypto/ethereum/contracts/UniV3.go | 251 -------------------- internal/crypto/ethereum/identity.go | 89 ------- internal/crypto/identity.go | 93 -------- internal/crypto/identity_test.go | 32 --- internal/crypto/tss/identity.go | 158 ------------ internal/crypto/tss/identity_test.go | 125 ---------- 9 files changed, 1002 deletions(-) delete mode 100644 internal/crypto/bls/bls.go delete mode 100644 internal/crypto/bls/identity.go delete mode 100644 internal/crypto/bls/identity_test.go delete mode 100644 internal/crypto/ethereum/contracts/UniV3.go delete mode 100644 internal/crypto/ethereum/identity.go delete mode 100644 internal/crypto/identity.go delete mode 100644 internal/crypto/identity_test.go delete mode 100644 internal/crypto/tss/identity.go delete mode 100644 internal/crypto/tss/identity_test.go diff --git a/internal/crypto/bls/bls.go b/internal/crypto/bls/bls.go deleted file mode 100644 index 39ac22a0..00000000 --- a/internal/crypto/bls/bls.go +++ /dev/null @@ -1,47 +0,0 @@ -package bls - -import ( - bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" -) - -func Hash(message []byte) (bls12381.G1Affine, error) { - dst := []byte("UNCHAINED") - return bls12381.HashToG1(message, dst) -} - -func RecoverSignature(bytes [48]byte) (bls12381.G1Affine, error) { - signature := new(bls12381.G1Affine) - _, err := signature.SetBytes(bytes[:]) - return *signature, err -} - -func RecoverPublicKey(bytes [96]byte) (bls12381.G2Affine, error) { - pk := new(bls12381.G2Affine) - _, err := pk.SetBytes(bytes[:]) - return *pk, err -} - -func AggregateSignatures(signatures [][]byte) ([]byte, error) { - signaturesBls := []bls12381.G1Affine{} - - for _, signature := range signatures { - signatureBls, err := RecoverSignature([48]byte(signature)) - if err != nil { - return nil, err - } - - signaturesBls = append(signaturesBls, signatureBls) - } - - aggregated := new(bls12381.G1Jac).FromAffine(&signaturesBls[0]) - - for _, sig := range signaturesBls[1:] { - sigJac := new(bls12381.G1Jac).FromAffine(&sig) - aggregated.AddAssign(sigJac) - } - - aggregatedAffine := new(bls12381.G1Affine).FromJacobian(aggregated) - aggregatedAffineByte := aggregatedAffine.Bytes() - - return aggregatedAffineByte[:], nil -} diff --git a/internal/crypto/bls/identity.go b/internal/crypto/bls/identity.go deleted file mode 100644 index 74ed867f..00000000 --- a/internal/crypto/bls/identity.go +++ /dev/null @@ -1,130 +0,0 @@ -package bls - -import ( - "crypto/rand" - "encoding/hex" - "math/big" - - "github.com/TimeleapLabs/unchained/internal/consts" - - "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/btcsuite/btcutil/base58" - bls12381_fr "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" - - "github.com/TimeleapLabs/unchained/internal/utils/address" - - "github.com/TimeleapLabs/unchained/internal/config" - bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" -) - -// Signer represents a BLS identity. -type Signer struct { - Name string - SecretKey *big.Int - PublicKey *bls12381.G2Affine - ShortPublicKey *bls12381.G1Affine - - g2Aff bls12381.G2Affine - g1Aff bls12381.G1Affine -} - -// Sign will sign a data with bls secret and return signed data. -func (s *Signer) Sign(data []byte) ([]byte, error) { - hashedMessage, err := Hash(data) - if err != nil { - panic(err) - } - - signature := new(bls12381.G1Affine).ScalarMultiplication(&hashedMessage, s.SecretKey).Bytes() - - return signature[:], err -} - -// WriteConfigs writes the secret key, public key and address to the global config object. -func (s *Signer) WriteConfigs() { - pkBytes := s.PublicKey.Bytes() - config.App.Secret.SecretKey = hex.EncodeToString(s.SecretKey.Bytes()) - config.App.Secret.PublicKey = hex.EncodeToString(pkBytes[:]) - config.App.Secret.Address = address.Calculate(pkBytes[:]) -} - -// Verify verifies the signature of a message belongs to the public key. -func (s *Signer) Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) { - signatureBls, err := RecoverSignature([48]byte(signature)) - if err != nil { - utils.Logger.With("Err", err).Error("Can't recover bls signature") - return false, consts.ErrInternalError - } - - publicKeyBls, err := RecoverPublicKey([96]byte(publicKey)) - if err != nil { - utils.Logger.With("Err", err).Error("Can't recover pub-key") - return false, consts.ErrInternalError - } - - messageBls, err := Hash(hashedMessage) - if err != nil { - utils.Logger.With("Err", err).Error("Can't convert message to hash") - return false, consts.ErrInternalError - } - - pairingSigG2, err := bls12381.Pair( - []bls12381.G1Affine{signatureBls}, - []bls12381.G2Affine{s.g2Aff}) - if err != nil { - return false, err - } - - pairingHmPk, pairingError := bls12381.Pair( - []bls12381.G1Affine{messageBls}, - []bls12381.G2Affine{publicKeyBls}) - - ok := pairingSigG2.Equal(&pairingHmPk) - - return ok, pairingError -} - -// NewIdentity creates a new BLS identity. -func NewIdentity() *Signer { - s := &Signer{ - SecretKey: new(big.Int), - } - - if config.App.Secret.SecretKey == "" && !config.App.System.AllowGenerateSecrets { - panic("BLS secret key is not provided and secrets generation is not allowed") - } - - _, _, s.g1Aff, s.g2Aff = bls12381.Generators() - - if config.App.Secret.SecretKey != "" { - decoded, err := hex.DecodeString(config.App.Secret.SecretKey) - if err != nil { - // TODO: Backwards compatibility with base58 encoded secret keys - // Remove this after a few releases - decoded = base58.Decode(config.App.Secret.SecretKey) - } - - s.SecretKey.SetBytes(decoded) - s.PublicKey = new(bls12381.G2Affine).ScalarMultiplication(&s.g2Aff, s.SecretKey) - } else { - // generate a random point in G2 - g2Order := bls12381_fr.Modulus() - sk, err := rand.Int(rand.Reader, g2Order) - if err != nil { - panic(err) - } - - pk := new(bls12381.G2Affine).ScalarMultiplication(&s.g2Aff, sk) - - s.SecretKey = sk - s.PublicKey = pk - } - - s.ShortPublicKey = new(bls12381.G1Affine).ScalarMultiplication(&s.g1Aff, s.SecretKey) - - utils.Logger. - With("Address", s.ShortPublicKey.String()). - Info("Unchained identity initialized") - - return s -} diff --git a/internal/crypto/bls/identity_test.go b/internal/crypto/bls/identity_test.go deleted file mode 100644 index 0b530354..00000000 --- a/internal/crypto/bls/identity_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package bls - -import ( - "crypto/rand" - "testing" - - "github.com/TimeleapLabs/unchained/internal/config" - "github.com/TimeleapLabs/unchained/internal/utils" - bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" - bls12381_fr "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" -) - -var ( - testData = []byte("HELLO hello") - secondTestData = []byte("HELLO hello 2") -) - -type BlsIdentityTestSuite struct { - suite.Suite - identity *Signer -} - -func (s *BlsIdentityTestSuite) SetupTest() { - utils.SetupLogger("info") - - config.App.System.AllowGenerateSecrets = true - s.identity = NewIdentity() -} - -func (s *BlsIdentityTestSuite) TestSign() { - signedData, err := s.identity.Sign(testData) - assert.NoError(s.T(), err) - - publicKey := s.identity.PublicKey.Bytes() - - s.Run("Should verify the message correctly", func() { - isVerified, err := s.identity.Verify(signedData, testData, publicKey[:]) - assert.NoError(s.T(), err) - assert.True(s.T(), isVerified) - }) - - s.Run("Should not verify the message because of wrong data case", func() { - isVerified, err := s.identity.Verify(signedData, secondTestData, publicKey[:]) - assert.NoError(s.T(), err) - assert.False(s.T(), isVerified) - }) - - s.Run("Should not verify the message because of wrong data case", func() { - signedSecondData, err := s.identity.Sign(secondTestData) - assert.NoError(s.T(), err) - - isVerified, err := s.identity.Verify(signedSecondData, testData, publicKey[:]) - assert.NoError(s.T(), err) - assert.False(s.T(), isVerified) - }) - - s.Run("Should not verify the message because publicKey is not belong to this message", func() { - _, _, _, g2Aff := bls12381.Generators() - g2Order := bls12381_fr.Modulus() - sk, err := rand.Int(rand.Reader, g2Order) - if err != nil { - panic(err) - } - - pk := new(bls12381.G2Affine).ScalarMultiplication(&g2Aff, sk).Bytes() - - isVerified, err := s.identity.Verify(signedData, secondTestData, pk[:]) - assert.NoError(s.T(), err) - assert.False(s.T(), isVerified) - }) -} - -func TestBlsIdentitySuite(t *testing.T) { - suite.Run(t, new(BlsIdentityTestSuite)) -} diff --git a/internal/crypto/ethereum/contracts/UniV3.go b/internal/crypto/ethereum/contracts/UniV3.go deleted file mode 100644 index 087ab06e..00000000 --- a/internal/crypto/ethereum/contracts/UniV3.go +++ /dev/null @@ -1,251 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package contracts - -import ( - "errors" - "math/big" - "strings" - - 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" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription - _ = abi.ConvertType -) - -// UniV3MetaData contains all meta data concerning the UniV3 contract. -var UniV3MetaData = &bind.MetaData{ - ABI: "[{\"type\":\"function\",\"name\":\"slot0\",\"constant\":true,\"stateMutability\":\"view\",\"payable\":false,\"inputs\":[],\"outputs\":[{\"type\":\"uint160\",\"name\":\"sqrtPriceX96\"},{\"type\":\"int24\",\"name\":\"tick\"},{\"type\":\"uint16\",\"name\":\"observationIndex\"},{\"type\":\"uint16\",\"name\":\"observationCardinality\"},{\"type\":\"uint16\",\"name\":\"observationCardinalityNext\"},{\"type\":\"uint8\",\"name\":\"feeProtocol\"},{\"type\":\"bool\",\"name\":\"unlocked\"}]}]", -} - -// UniV3ABI is the input ABI used to generate the binding from. -// Deprecated: Use UniV3MetaData.ABI instead. -var UniV3ABI = UniV3MetaData.ABI - -// UniV3 is an auto generated Go binding around an Ethereum contract. -type UniV3 struct { - UniV3Caller // Read-only binding to the contract - UniV3Transactor // Write-only binding to the contract - UniV3Filterer // Log filterer for contract events -} - -// UniV3Caller is an auto generated read-only Go binding around an Ethereum contract. -type UniV3Caller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// UniV3Transactor is an auto generated write-only Go binding around an Ethereum contract. -type UniV3Transactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// UniV3Filterer is an auto generated log filtering Go binding around an Ethereum contract events. -type UniV3Filterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// UniV3Session is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type UniV3Session struct { - Contract *UniV3 // 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 -} - -// UniV3CallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type UniV3CallerSession struct { - Contract *UniV3Caller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// UniV3TransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type UniV3TransactorSession struct { - Contract *UniV3Transactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// UniV3Raw is an auto generated low-level Go binding around an Ethereum contract. -type UniV3Raw struct { - Contract *UniV3 // Generic contract binding to access the raw methods on -} - -// UniV3CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type UniV3CallerRaw struct { - Contract *UniV3Caller // Generic read-only contract binding to access the raw methods on -} - -// UniV3TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type UniV3TransactorRaw struct { - Contract *UniV3Transactor // Generic write-only contract binding to access the raw methods on -} - -// NewUniV3 creates a new instance of UniV3, bound to a specific deployed contract. -func NewUniV3(address common.Address, backend bind.ContractBackend) (*UniV3, error) { - contract, err := bindUniV3(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &UniV3{UniV3Caller: UniV3Caller{contract: contract}, UniV3Transactor: UniV3Transactor{contract: contract}, UniV3Filterer: UniV3Filterer{contract: contract}}, nil -} - -// NewUniV3Caller creates a new read-only instance of UniV3, bound to a specific deployed contract. -func NewUniV3Caller(address common.Address, caller bind.ContractCaller) (*UniV3Caller, error) { - contract, err := bindUniV3(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &UniV3Caller{contract: contract}, nil -} - -// NewUniV3Transactor creates a new write-only instance of UniV3, bound to a specific deployed contract. -func NewUniV3Transactor(address common.Address, transactor bind.ContractTransactor) (*UniV3Transactor, error) { - contract, err := bindUniV3(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &UniV3Transactor{contract: contract}, nil -} - -// NewUniV3Filterer creates a new log filterer instance of UniV3, bound to a specific deployed contract. -func NewUniV3Filterer(address common.Address, filterer bind.ContractFilterer) (*UniV3Filterer, error) { - contract, err := bindUniV3(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &UniV3Filterer{contract: contract}, nil -} - -// bindUniV3 binds a generic wrapper to an already deployed contract. -func bindUniV3(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := UniV3MetaData.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 (_UniV3 *UniV3Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UniV3.Contract.UniV3Caller.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 (_UniV3 *UniV3Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UniV3.Contract.UniV3Transactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_UniV3 *UniV3Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UniV3.Contract.UniV3Transactor.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 (_UniV3 *UniV3CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UniV3.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 (_UniV3 *UniV3TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UniV3.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_UniV3 *UniV3TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UniV3.Contract.contract.Transact(opts, method, params...) -} - -// Slot0 is a free data retrieval call binding the contract method 0x3850c7bd. -// -// Solidity: function slot0() view returns(uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked) -func (_UniV3 *UniV3Caller) Slot0(opts *bind.CallOpts) (struct { - SqrtPriceX96 *big.Int - Tick *big.Int - ObservationIndex uint16 - ObservationCardinality uint16 - ObservationCardinalityNext uint16 - FeeProtocol uint8 - Unlocked bool -}, error) { - var out []interface{} - err := _UniV3.contract.Call(opts, &out, "slot0") - - outstruct := new(struct { - SqrtPriceX96 *big.Int - Tick *big.Int - ObservationIndex uint16 - ObservationCardinality uint16 - ObservationCardinalityNext uint16 - FeeProtocol uint8 - Unlocked bool - }) - if err != nil { - return *outstruct, err - } - - outstruct.SqrtPriceX96 = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.Tick = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.ObservationIndex = *abi.ConvertType(out[2], new(uint16)).(*uint16) - outstruct.ObservationCardinality = *abi.ConvertType(out[3], new(uint16)).(*uint16) - outstruct.ObservationCardinalityNext = *abi.ConvertType(out[4], new(uint16)).(*uint16) - outstruct.FeeProtocol = *abi.ConvertType(out[5], new(uint8)).(*uint8) - outstruct.Unlocked = *abi.ConvertType(out[6], new(bool)).(*bool) - - return *outstruct, err - -} - -// Slot0 is a free data retrieval call binding the contract method 0x3850c7bd. -// -// Solidity: function slot0() view returns(uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked) -func (_UniV3 *UniV3Session) Slot0() (struct { - SqrtPriceX96 *big.Int - Tick *big.Int - ObservationIndex uint16 - ObservationCardinality uint16 - ObservationCardinalityNext uint16 - FeeProtocol uint8 - Unlocked bool -}, error) { - return _UniV3.Contract.Slot0(&_UniV3.CallOpts) -} - -// Slot0 is a free data retrieval call binding the contract method 0x3850c7bd. -// -// Solidity: function slot0() view returns(uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked) -func (_UniV3 *UniV3CallerSession) Slot0() (struct { - SqrtPriceX96 *big.Int - Tick *big.Int - ObservationIndex uint16 - ObservationCardinality uint16 - ObservationCardinalityNext uint16 - FeeProtocol uint8 - Unlocked bool -}, error) { - return _UniV3.Contract.Slot0(&_UniV3.CallOpts) -} diff --git a/internal/crypto/ethereum/identity.go b/internal/crypto/ethereum/identity.go deleted file mode 100644 index 2e9246f7..00000000 --- a/internal/crypto/ethereum/identity.go +++ /dev/null @@ -1,89 +0,0 @@ -package ethereum - -import ( - "crypto/ecdsa" - - "github.com/TimeleapLabs/unchained/internal/config" - "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" -) - -// Signer represents an Ethereum identity. -type Signer struct { - PublicKey *ecdsa.PublicKey - PrivateKey *ecdsa.PrivateKey - Address string -} - -func (s *Signer) Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) { - // TODO implement me - panic("implement me") -} - -// WriteConfigs writes the secret key, public key and address to the global config object. -func (s *Signer) WriteConfigs() { - privateKeyBytes := crypto.FromECDSA(s.PrivateKey) - config.App.Secret.EvmPrivateKey = hexutil.Encode(privateKeyBytes)[2:] - config.App.Secret.EvmAddress = s.Address -} - -func (s *Signer) Sign(data []byte) ([]byte, error) { - signature, err := crypto.Sign(data, s.PrivateKey) - if err != nil { - return nil, err - } - - if signature[64] < 27 { - signature[64] += 27 - } - - return signature, nil -} - -// NewIdentity creates a new Ethereum identity. -func NewIdentity() *Signer { - var privateKey *ecdsa.PrivateKey - var err error - - if config.App.Secret.EvmPrivateKey == "" && !config.App.System.AllowGenerateSecrets { - panic("EVM private key is not provided and secrets generation is not allowed") - } - - if config.App.Secret.EvmPrivateKey != "" { - privateKey, err = crypto.HexToECDSA(config.App.Secret.EvmPrivateKey) - if err != nil { - utils.Logger. - With("Error", err). - Error("Can't decode EVM private key") - - panic(err) - } - } else { - privateKey, err = crypto.GenerateKey() - if err != nil { - utils.Logger. - With("Error", err). - Error("Can't generate EVM private key") - - panic(err) - } - } - - publicKeyECDSA, ok := privateKey.Public().(*ecdsa.PublicKey) - if !ok { - panic("Can't assert type: publicKey is not of type *ecdsa.PublicKey") - } - - s := &Signer{ - PublicKey: publicKeyECDSA, - PrivateKey: privateKey, - Address: crypto.PubkeyToAddress(*publicKeyECDSA).Hex(), - } - - utils.Logger. - With("Address", s.Address). - Info("EVM identity initialized") - - return s -} diff --git a/internal/crypto/identity.go b/internal/crypto/identity.go deleted file mode 100644 index 431deb24..00000000 --- a/internal/crypto/identity.go +++ /dev/null @@ -1,93 +0,0 @@ -package crypto - -import ( - "encoding/hex" - - "github.com/TimeleapLabs/unchained/internal/config" - "github.com/TimeleapLabs/unchained/internal/crypto/bls" - "github.com/TimeleapLabs/unchained/internal/crypto/ethereum" - "github.com/TimeleapLabs/unchained/internal/crypto/tss" - "github.com/TimeleapLabs/unchained/internal/model" -) - -// Signer represents a Signing method. -type Signer interface { - Sign(data []byte) ([]byte, error) - Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) - WriteConfigs() -} - -// MachineIdentity holds machine identity and provide and manage keys. -type MachineIdentity struct { - Bls Signer - Eth Signer - Tss Signer -} - -// Identity is a global variable that holds machine identity. -var Identity = &MachineIdentity{} - -// Option represents a function that can add new identity to machine identity. -type Option func(identity *MachineIdentity) error - -// InitMachineIdentity loads all provided identities and save them to secret file. -func InitMachineIdentity(options ...Option) { - for _, option := range options { - err := option(Identity) - if err != nil { - panic(err) - } - } - - if config.App.System.AllowGenerateSecrets { - err := config.App.Secret.Save() - if err != nil { - panic(err) - } - } -} - -// ExportEvmSigner returns EVM signer from machine identity. -func (i *MachineIdentity) ExportEvmSigner() *model.Signer { - blsPublicKey, err := hex.DecodeString(config.App.Secret.PublicKey) - if err != nil { - panic(err) - } - - return &model.Signer{ - Name: config.App.System.Name, - EvmAddress: config.App.Secret.EvmAddress, - PublicKey: [96]byte(blsPublicKey), - ShortPublicKey: config.App.Secret.ShortPublicKey, - } -} - -// WithEvmSigner initialize and will add Evm identity to machine identity. -func WithEvmSigner() func(machineIdentity *MachineIdentity) error { - return func(machineIdentity *MachineIdentity) error { - machineIdentity.Eth = ethereum.NewIdentity() - machineIdentity.Eth.WriteConfigs() - - return nil - } -} - -// WithTssSigner initialize and will add Tss identity to machine identity. -func WithTssSigner(signers []string, minThreshold int) func(machineIdentity *MachineIdentity) error { - return func(machineIdentity *MachineIdentity) error { - machineIdentity.Tss = tss.NewIdentity(signers, minThreshold) - //machineIdentity.Tss.WriteConfigs() - - return nil - } -} - -// WithBlsIdentity initialize and will add Bls identity to machine identity. -func WithBlsIdentity() func(machineIdentity *MachineIdentity) error { - return func(machineIdentity *MachineIdentity) error { - machineIdentity.Bls = bls.NewIdentity() - machineIdentity.Bls.WriteConfigs() - - return nil - } -} diff --git a/internal/crypto/identity_test.go b/internal/crypto/identity_test.go deleted file mode 100644 index b0fa65b6..00000000 --- a/internal/crypto/identity_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package crypto - -import ( - "testing" - - "github.com/TimeleapLabs/unchained/internal/config" - "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/stretchr/testify/assert" -) - -const SamplePrivateKey = "3b885a8a8f043724abfa865eccd38f536887d9ea1c08a742720e810f38a86872" - -func TestEvmSignerWithoutGeneratePrivateKey(t *testing.T) { - utils.SetupLogger("info") - config.App.Secret.EvmPrivateKey = SamplePrivateKey - - InitMachineIdentity( - WithEvmSigner(), - ) - - assert.Equal(t, config.App.Secret.EvmPrivateKey, SamplePrivateKey) -} - -func TestEvmSignerWithGeneratePrivateKey(t *testing.T) { - utils.SetupLogger("info") - config.App.Secret.EvmPrivateKey = "" - - InitMachineIdentity( - WithEvmSigner(), - ) - assert.NotEmpty(t, config.App.Secret.EvmPrivateKey) -} diff --git a/internal/crypto/tss/identity.go b/internal/crypto/tss/identity.go deleted file mode 100644 index 4afa40e0..00000000 --- a/internal/crypto/tss/identity.go +++ /dev/null @@ -1,158 +0,0 @@ -package tss - -import ( - "github.com/TimeleapLabs/unchained/internal/consts" - "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/bnb-chain/tss-lib/common" - "github.com/bnb-chain/tss-lib/ecdsa/keygen" - "github.com/bnb-chain/tss-lib/ecdsa/signing" - "github.com/bnb-chain/tss-lib/tss" - "math/big" -) - -// Signer represents a TSS identity. -type Signer struct { - ctx *tss.PeerContext - PartyID *tss.PartyID - keyParty *keygen.LocalParty - localPartySaved *keygen.LocalPartySaveData - result chan keygen.LocalPartySaveData - minThreshold int - numberOfPeers int -} - -type MessageSigner struct { - party *signing.LocalParty -} - -func (s *Signer) Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) { - //TODO implement me - panic("implement me") -} - -func (s *Signer) WriteConfigs() { - //TODO implement me - panic("implement me") -} - -// NewSigning will sign a data with tss secret and return signed data. -func (s *Signer) NewSigning(data []byte, out chan tss.Message, end chan<- common.SignatureData) (*MessageSigner, error) { - if !s.localPartySaved.ValidateWithProof() { - return &MessageSigner{}, consts.ErrSignerIsNotReady - } - - dataBig := new(big.Int).SetBytes(data) - - params := tss.NewParameters(tss.S256(), s.ctx, s.PartyID, s.numberOfPeers, s.minThreshold) - signer := &MessageSigner{ - party: signing.NewLocalParty(dataBig, params, *s.localPartySaved, out, end).(*signing.LocalParty), - } - - go func(signer *MessageSigner) { - err := signer.party.Start() - if err != nil { - panic(err) - } - }(signer) - - return signer, nil -} - -func (s *MessageSigner) AckSignature(msg tss.Message) error { - if s.party.PartyID() == msg.GetFrom() { - return nil - } - - bz, _, err := msg.WireBytes() - if err != nil { - utils.Logger.Error(err.Error()) - return err - } - - pMsg, err := tss.ParseWireMessage(bz, msg.GetFrom(), msg.IsBroadcast()) - if err != nil { - utils.Logger.Error(err.Error()) - return err - } - - isOK, err := s.party.Update(pMsg) - if err != nil && !isOK { - utils.Logger.Error(err.Error()) - return err - } - - return nil -} - -func (s *Signer) Update(msg tss.Message) error { - if s.keyParty.PartyID() == msg.GetFrom() { - return nil - } - - bz, _, err := msg.WireBytes() - if err != nil { - utils.Logger.Error(err.Error()) - return err - } - - pMsg, err := tss.ParseWireMessage(bz, msg.GetFrom(), msg.IsBroadcast()) - if err != nil { - utils.Logger.Error(err.Error()) - return err - } - - isOK, err := s.keyParty.Update(pMsg) - if err != nil && !isOK { - utils.Logger.Error(err.Error()) - return err - } - - return nil -} - -// NewIdentity creates a new BLS identity. -func NewIdentity(signerID int, signers []string, outCh chan tss.Message, done chan struct{}, minThreshold int) *Signer { - partyIDs := make(tss.UnSortedPartyIDs, len(signers)) - for i, signer := range signers { - party := tss.NewPartyID(signer, signer, big.NewInt(int64(i+1))) - partyIDs[i] = party - } - - signer := &Signer{ - minThreshold: minThreshold, - numberOfPeers: len(signers), - //rawPartyID: signers[signerID], - PartyID: partyIDs[signerID], - result: make(chan keygen.LocalPartySaveData, len(signers)), - } - - sortedPartyIDs := tss.SortPartyIDs(partyIDs) - - signer.ctx = tss.NewPeerContext(sortedPartyIDs) - - signer.keyParty = keygen.NewLocalParty( - tss.NewParameters(tss.S256(), signer.ctx, sortedPartyIDs[signerID], len(signers), minThreshold), - outCh, - signer.result, - ).(*keygen.LocalParty) - - go func(signer *Signer) { - err := signer.keyParty.Start() - if err != nil { - panic(err) - } - utils.Logger.With("ID", signer.PartyID.Moniker).Info("New Tss party started") - - for { - select { - case save := <-signer.result: - signer.localPartySaved = &save - done <- struct{}{} - break - } - } - - }(signer) - - return signer -} diff --git a/internal/crypto/tss/identity_test.go b/internal/crypto/tss/identity_test.go deleted file mode 100644 index 9d25f842..00000000 --- a/internal/crypto/tss/identity_test.go +++ /dev/null @@ -1,125 +0,0 @@ -package tss - -import ( - "fmt" - "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/bnb-chain/tss-lib/common" - "github.com/bnb-chain/tss-lib/tss" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" - "testing" -) - -const ( - numOfSigners = 4 - minNumOfSigners = 2 -) - -var ( - testData = []byte("HELLO hello") - secondTestData = []byte("HELLO hello 2") - signers = []string{} -) - -type TssIdentityTestSuite struct { - suite.Suite - parties []*Signer -} - -func (s *TssIdentityTestSuite) SetupTest() { - utils.SetupLogger("info") - - for i := 0; i < numOfSigners; i++ { - signers = append(signers, fmt.Sprintf("signer-%d", i)) - } - - outCh := make(chan tss.Message, len(signers)) - wg := make(chan struct{}) - - for i := 0; i < numOfSigners; i++ { - party := NewIdentity(i, signers, outCh, wg, minNumOfSigners) - s.parties = append(s.parties, party) - } - - wait := 0 -keygen: - for { - select { - case msg := <-outCh: - dest := msg.GetTo() - - if dest == nil { // broadcast! - for _, P := range s.parties { - if P.PartyID.Index == msg.GetFrom().Index { - continue - } - - go P.Update(msg) - } - } else { // point-to-point! - if dest[0].Index == msg.GetFrom().Index { - fmt.Printf("party %d tried to send a message to itself (%d)", dest[0].Index, msg.GetFrom().Index) - return - } - go s.parties[dest[0].Index].Update(msg) - } - - case <-wg: - wait++ - if wait == numOfSigners { - break keygen - } - } - } -} - -func (s *TssIdentityTestSuite) TestSign() { - outCh := make(chan tss.Message, len(s.parties)) - endCh := make(chan common.SignatureData, len(s.parties)) - msgSigners := []*MessageSigner{} - - for i := 0; i < numOfSigners; i++ { - go func() { - signer, err := s.parties[i].NewSigning(testData, outCh, endCh) - assert.NoError(s.T(), err) - - msgSigners = append(msgSigners, signer) - }() - } - - // wait := 0 - //signing: - for { - select { - case msg := <-outCh: - dest := msg.GetTo() - if dest == nil { - for _, P := range msgSigners { - if P.party.PartyID().Index == msg.GetFrom().Index { - continue - } - - go P.AckSignature(msg) - } - } else { - if dest[0].Index == msg.GetFrom().Index { - common.Logger.Fatalf("party %d tried to send a message to itself (%d)", dest[0].Index, msg.GetFrom().Index) - } - - go msgSigners[dest[0].Index].AckSignature(msg) - } - case <-endCh: - fmt.Println("end") - } - } - - //s.Run("Should verify the message correctly", func() { - // isVerified, err := s.identity.Verify() - // assert.NoError(s.T(), err) - // assert.True(s.T(), isVerified) - //}) -} - -func TestTssIdentitySuite(t *testing.T) { - suite.Run(t, new(TssIdentityTestSuite)) -} From 34b61ca382a95fd43912742b7bbf49b99ebf31ad Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Sat, 18 May 2024 22:24:55 +0330 Subject: [PATCH 21/29] =?UTF-8?q?=E2=9C=A8=20feat(front):=20delete=20tss?= =?UTF-8?q?=20and=20add=20frost=20algothim=20>>>=20=E2=8F=B0=201.5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/crypto/bls/bls.go | 47 + internal/crypto/bls/identity.go | 130 + internal/crypto/bls/identity_test.go | 77 + .../ethereum/contracts/UnchainedStaking.go | 2644 +++++++++++++++++ internal/crypto/ethereum/contracts/UniV3.go | 251 ++ internal/crypto/ethereum/identity.go | 89 + internal/crypto/frost/identity.go | 30 +- internal/crypto/identity.go | 96 + internal/crypto/identity_test.go | 32 + 9 files changed, 3377 insertions(+), 19 deletions(-) create mode 100644 internal/crypto/bls/bls.go create mode 100644 internal/crypto/bls/identity.go create mode 100644 internal/crypto/bls/identity_test.go create mode 100644 internal/crypto/ethereum/contracts/UnchainedStaking.go create mode 100644 internal/crypto/ethereum/contracts/UniV3.go create mode 100644 internal/crypto/ethereum/identity.go create mode 100644 internal/crypto/identity.go create mode 100644 internal/crypto/identity_test.go diff --git a/internal/crypto/bls/bls.go b/internal/crypto/bls/bls.go new file mode 100644 index 00000000..39ac22a0 --- /dev/null +++ b/internal/crypto/bls/bls.go @@ -0,0 +1,47 @@ +package bls + +import ( + bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" +) + +func Hash(message []byte) (bls12381.G1Affine, error) { + dst := []byte("UNCHAINED") + return bls12381.HashToG1(message, dst) +} + +func RecoverSignature(bytes [48]byte) (bls12381.G1Affine, error) { + signature := new(bls12381.G1Affine) + _, err := signature.SetBytes(bytes[:]) + return *signature, err +} + +func RecoverPublicKey(bytes [96]byte) (bls12381.G2Affine, error) { + pk := new(bls12381.G2Affine) + _, err := pk.SetBytes(bytes[:]) + return *pk, err +} + +func AggregateSignatures(signatures [][]byte) ([]byte, error) { + signaturesBls := []bls12381.G1Affine{} + + for _, signature := range signatures { + signatureBls, err := RecoverSignature([48]byte(signature)) + if err != nil { + return nil, err + } + + signaturesBls = append(signaturesBls, signatureBls) + } + + aggregated := new(bls12381.G1Jac).FromAffine(&signaturesBls[0]) + + for _, sig := range signaturesBls[1:] { + sigJac := new(bls12381.G1Jac).FromAffine(&sig) + aggregated.AddAssign(sigJac) + } + + aggregatedAffine := new(bls12381.G1Affine).FromJacobian(aggregated) + aggregatedAffineByte := aggregatedAffine.Bytes() + + return aggregatedAffineByte[:], nil +} diff --git a/internal/crypto/bls/identity.go b/internal/crypto/bls/identity.go new file mode 100644 index 00000000..74ed867f --- /dev/null +++ b/internal/crypto/bls/identity.go @@ -0,0 +1,130 @@ +package bls + +import ( + "crypto/rand" + "encoding/hex" + "math/big" + + "github.com/TimeleapLabs/unchained/internal/consts" + + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/btcsuite/btcutil/base58" + bls12381_fr "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" + + "github.com/TimeleapLabs/unchained/internal/utils/address" + + "github.com/TimeleapLabs/unchained/internal/config" + bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" +) + +// Signer represents a BLS identity. +type Signer struct { + Name string + SecretKey *big.Int + PublicKey *bls12381.G2Affine + ShortPublicKey *bls12381.G1Affine + + g2Aff bls12381.G2Affine + g1Aff bls12381.G1Affine +} + +// Sign will sign a data with bls secret and return signed data. +func (s *Signer) Sign(data []byte) ([]byte, error) { + hashedMessage, err := Hash(data) + if err != nil { + panic(err) + } + + signature := new(bls12381.G1Affine).ScalarMultiplication(&hashedMessage, s.SecretKey).Bytes() + + return signature[:], err +} + +// WriteConfigs writes the secret key, public key and address to the global config object. +func (s *Signer) WriteConfigs() { + pkBytes := s.PublicKey.Bytes() + config.App.Secret.SecretKey = hex.EncodeToString(s.SecretKey.Bytes()) + config.App.Secret.PublicKey = hex.EncodeToString(pkBytes[:]) + config.App.Secret.Address = address.Calculate(pkBytes[:]) +} + +// Verify verifies the signature of a message belongs to the public key. +func (s *Signer) Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) { + signatureBls, err := RecoverSignature([48]byte(signature)) + if err != nil { + utils.Logger.With("Err", err).Error("Can't recover bls signature") + return false, consts.ErrInternalError + } + + publicKeyBls, err := RecoverPublicKey([96]byte(publicKey)) + if err != nil { + utils.Logger.With("Err", err).Error("Can't recover pub-key") + return false, consts.ErrInternalError + } + + messageBls, err := Hash(hashedMessage) + if err != nil { + utils.Logger.With("Err", err).Error("Can't convert message to hash") + return false, consts.ErrInternalError + } + + pairingSigG2, err := bls12381.Pair( + []bls12381.G1Affine{signatureBls}, + []bls12381.G2Affine{s.g2Aff}) + if err != nil { + return false, err + } + + pairingHmPk, pairingError := bls12381.Pair( + []bls12381.G1Affine{messageBls}, + []bls12381.G2Affine{publicKeyBls}) + + ok := pairingSigG2.Equal(&pairingHmPk) + + return ok, pairingError +} + +// NewIdentity creates a new BLS identity. +func NewIdentity() *Signer { + s := &Signer{ + SecretKey: new(big.Int), + } + + if config.App.Secret.SecretKey == "" && !config.App.System.AllowGenerateSecrets { + panic("BLS secret key is not provided and secrets generation is not allowed") + } + + _, _, s.g1Aff, s.g2Aff = bls12381.Generators() + + if config.App.Secret.SecretKey != "" { + decoded, err := hex.DecodeString(config.App.Secret.SecretKey) + if err != nil { + // TODO: Backwards compatibility with base58 encoded secret keys + // Remove this after a few releases + decoded = base58.Decode(config.App.Secret.SecretKey) + } + + s.SecretKey.SetBytes(decoded) + s.PublicKey = new(bls12381.G2Affine).ScalarMultiplication(&s.g2Aff, s.SecretKey) + } else { + // generate a random point in G2 + g2Order := bls12381_fr.Modulus() + sk, err := rand.Int(rand.Reader, g2Order) + if err != nil { + panic(err) + } + + pk := new(bls12381.G2Affine).ScalarMultiplication(&s.g2Aff, sk) + + s.SecretKey = sk + s.PublicKey = pk + } + + s.ShortPublicKey = new(bls12381.G1Affine).ScalarMultiplication(&s.g1Aff, s.SecretKey) + + utils.Logger. + With("Address", s.ShortPublicKey.String()). + Info("Unchained identity initialized") + + return s +} diff --git a/internal/crypto/bls/identity_test.go b/internal/crypto/bls/identity_test.go new file mode 100644 index 00000000..0b530354 --- /dev/null +++ b/internal/crypto/bls/identity_test.go @@ -0,0 +1,77 @@ +package bls + +import ( + "crypto/rand" + "testing" + + "github.com/TimeleapLabs/unchained/internal/config" + "github.com/TimeleapLabs/unchained/internal/utils" + bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" + bls12381_fr "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" +) + +var ( + testData = []byte("HELLO hello") + secondTestData = []byte("HELLO hello 2") +) + +type BlsIdentityTestSuite struct { + suite.Suite + identity *Signer +} + +func (s *BlsIdentityTestSuite) SetupTest() { + utils.SetupLogger("info") + + config.App.System.AllowGenerateSecrets = true + s.identity = NewIdentity() +} + +func (s *BlsIdentityTestSuite) TestSign() { + signedData, err := s.identity.Sign(testData) + assert.NoError(s.T(), err) + + publicKey := s.identity.PublicKey.Bytes() + + s.Run("Should verify the message correctly", func() { + isVerified, err := s.identity.Verify(signedData, testData, publicKey[:]) + assert.NoError(s.T(), err) + assert.True(s.T(), isVerified) + }) + + s.Run("Should not verify the message because of wrong data case", func() { + isVerified, err := s.identity.Verify(signedData, secondTestData, publicKey[:]) + assert.NoError(s.T(), err) + assert.False(s.T(), isVerified) + }) + + s.Run("Should not verify the message because of wrong data case", func() { + signedSecondData, err := s.identity.Sign(secondTestData) + assert.NoError(s.T(), err) + + isVerified, err := s.identity.Verify(signedSecondData, testData, publicKey[:]) + assert.NoError(s.T(), err) + assert.False(s.T(), isVerified) + }) + + s.Run("Should not verify the message because publicKey is not belong to this message", func() { + _, _, _, g2Aff := bls12381.Generators() + g2Order := bls12381_fr.Modulus() + sk, err := rand.Int(rand.Reader, g2Order) + if err != nil { + panic(err) + } + + pk := new(bls12381.G2Affine).ScalarMultiplication(&g2Aff, sk).Bytes() + + isVerified, err := s.identity.Verify(signedData, secondTestData, pk[:]) + assert.NoError(s.T(), err) + assert.False(s.T(), isVerified) + }) +} + +func TestBlsIdentitySuite(t *testing.T) { + suite.Run(t, new(BlsIdentityTestSuite)) +} diff --git a/internal/crypto/ethereum/contracts/UnchainedStaking.go b/internal/crypto/ethereum/contracts/UnchainedStaking.go new file mode 100644 index 00000000..ed3fa3c4 --- /dev/null +++ b/internal/crypto/ethereum/contracts/UnchainedStaking.go @@ -0,0 +1,2644 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contracts + +import ( + "errors" + "math/big" + "strings" + + 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" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// UnchainedStakingEIP712SetNftPrice is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingEIP712SetNftPrice struct { + Requester common.Address + NftId *big.Int + Price *big.Int + Nonce *big.Int +} + +// UnchainedStakingEIP712SetNftPriceKey is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingEIP712SetNftPriceKey struct { + NftId *big.Int + Price *big.Int + Nonce *big.Int +} + +// UnchainedStakingEIP712SetParams is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingEIP712SetParams struct { + Requester common.Address + Token common.Address + Nft common.Address + NftTracker common.Address + Threshold *big.Int + Expiration *big.Int + Nonce *big.Int +} + +// UnchainedStakingEIP712SetParamsKey is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingEIP712SetParamsKey struct { + Token common.Address + Nft common.Address + NftTracker common.Address + Threshold *big.Int + Expiration *big.Int + Nonce *big.Int +} + +// UnchainedStakingEIP712SetSigner is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingEIP712SetSigner struct { + Staker common.Address + Signer common.Address +} + +// UnchainedStakingEIP712Transfer is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingEIP712Transfer struct { + Signer common.Address + From common.Address + To common.Address + Amount *big.Int + NftIds []*big.Int + Nonces []*big.Int +} + +// UnchainedStakingEIP712TransferKey is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingEIP712TransferKey struct { + From common.Address + To common.Address + Amount *big.Int + NftIds []*big.Int + Nonces []*big.Int +} + +// UnchainedStakingNftPriceInfo is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingNftPriceInfo struct { + NftId *big.Int + Price *big.Int + Voted *big.Int + Accepted bool +} + +// UnchainedStakingParamsInfo is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingParamsInfo struct { + Token common.Address + Nft common.Address + NftTracker common.Address + Threshold *big.Int + Expiration *big.Int + Voted *big.Int + Nonce *big.Int + Accepted bool +} + +// UnchainedStakingSignature is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingSignature struct { + V uint8 + R [32]byte + S [32]byte +} + +// UnchainedStakingStake is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingStake struct { + Amount *big.Int + Unlock *big.Int + NftIds []*big.Int +} + +// UnchainedStakingTransferInfo is an auto generated low-level Go binding around an user-defined struct. +type UnchainedStakingTransferInfo struct { + From common.Address + To common.Address + Amount *big.Int + NftIds []*big.Int + Voted *big.Int + Accepted bool + Nonces []*big.Int +} + +// UnchainedStakingMetaData contains all meta data concerning the UnchainedStaking contract. +var UnchainedStakingMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTrackerAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"consensusLock\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"AddressEmptyCode\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AddressInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"AddressInsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AlreadyStaked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AmountZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BlsNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DurationZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ECDSAInvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"ECDSAInvalidSignatureLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"ECDSAInvalidSignatureS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedInnerCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Forbidden\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LengthMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"NonceUsed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotUnlocked\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"OwnableInvalidOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"OwnableUnauthorizedAccount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrancyGuardReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"StakeExpiresBeforeVote\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StakeZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"TopicExpired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"VotingPowerZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNFT\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"from\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"to\",\"type\":\"bytes32\"}],\"name\":\"BlsAddressChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unlock\",\"type\":\"uint256\"}],\"name\":\"Extended\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"ParamsChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"SignerChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"StakeIncreased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"Staked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"UnStaked\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"evm\",\"type\":\"address\"}],\"name\":\"blsAddressOf\",\"outputs\":[{\"internalType\":\"bytes20\",\"name\":\"\",\"type\":\"bytes20\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"bls\",\"type\":\"bytes20\"}],\"name\":\"evmAddressOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"}],\"name\":\"extend\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConsensusThreshold\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"}],\"name\":\"getNftPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getParams\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"accepted\",\"type\":\"bool\"}],\"internalType\":\"structUnchainedStaking.ParamsInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetNftPriceKey\",\"name\":\"key\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"getRequestedSetNftPrice\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetParamsKey\",\"name\":\"key\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"getRequestedSetParams\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.EIP712TransferKey\",\"name\":\"key\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"transferer\",\"type\":\"address\"}],\"name\":\"getRequestedTransfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetNftPriceKey\",\"name\":\"key\",\"type\":\"tuple\"}],\"name\":\"getSetNftPriceData\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"accepted\",\"type\":\"bool\"}],\"internalType\":\"structUnchainedStaking.NftPriceInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetParamsKey\",\"name\":\"key\",\"type\":\"tuple\"}],\"name\":\"getSetParamsData\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"accepted\",\"type\":\"bool\"}],\"internalType\":\"structUnchainedStaking.ParamsInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"evm\",\"type\":\"address\"}],\"name\":\"getStake\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.Stake\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"bls\",\"type\":\"bytes20\"}],\"name\":\"getStake\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.Stake\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalVotingPower\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.EIP712TransferKey\",\"name\":\"key\",\"type\":\"tuple\"}],\"name\":\"getTransferData\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"voted\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"accepted\",\"type\":\"bool\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.TransferInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"bls\",\"type\":\"bytes20\"}],\"name\":\"getVotingPower\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"evm\",\"type\":\"address\"}],\"name\":\"getVotingPower\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"increaseStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes20\",\"name\":\"blsAddress\",\"type\":\"bytes20\"}],\"name\":\"setBlsAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetNftPrice[]\",\"name\":\"eip712SetNftPrices\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"}],\"name\":\"setNftPrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetParams[]\",\"name\":\"eip712SetParams\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"}],\"name\":\"setParams\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"internalType\":\"structUnchainedStaking.EIP712SetSigner\",\"name\":\"eip712SetSigner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"stakerSignature\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signerSignature\",\"type\":\"tuple\"}],\"name\":\"setSigner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"signerToStaker\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"}],\"name\":\"stake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"}],\"name\":\"stakerToSigner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.EIP712Transfer[]\",\"name\":\"eip712Transferes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unstake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nft\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTracker\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetParams\",\"name\":\"eip712SetParam\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signature\",\"type\":\"tuple\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"internalType\":\"structUnchainedStaking.EIP712SetNftPrice\",\"name\":\"eip712SetNftPrice\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signature\",\"type\":\"tuple\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"staker\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"internalType\":\"structUnchainedStaking.EIP712SetSigner\",\"name\":\"eip712SetSigner\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"stakerSignature\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signerSignature\",\"type\":\"tuple\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"nftIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"nonces\",\"type\":\"uint256[]\"}],\"internalType\":\"structUnchainedStaking.EIP712Transfer\",\"name\":\"eip712Transfer\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"internalType\":\"structUnchainedStaking.Signature\",\"name\":\"signature\",\"type\":\"tuple\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +// UnchainedStakingABI is the input ABI used to generate the binding from. +// Deprecated: Use UnchainedStakingMetaData.ABI instead. +var UnchainedStakingABI = UnchainedStakingMetaData.ABI + +// UnchainedStaking is an auto generated Go binding around an Ethereum contract. +type UnchainedStaking struct { + UnchainedStakingCaller // Read-only binding to the contract + UnchainedStakingTransactor // Write-only binding to the contract + UnchainedStakingFilterer // Log filterer for contract events +} + +// UnchainedStakingCaller is an auto generated read-only Go binding around an Ethereum contract. +type UnchainedStakingCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UnchainedStakingTransactor is an auto generated write-only Go binding around an Ethereum contract. +type UnchainedStakingTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UnchainedStakingFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type UnchainedStakingFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UnchainedStakingSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type UnchainedStakingSession struct { + Contract *UnchainedStaking // 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 +} + +// UnchainedStakingCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type UnchainedStakingCallerSession struct { + Contract *UnchainedStakingCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// UnchainedStakingTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type UnchainedStakingTransactorSession struct { + Contract *UnchainedStakingTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// UnchainedStakingRaw is an auto generated low-level Go binding around an Ethereum contract. +type UnchainedStakingRaw struct { + Contract *UnchainedStaking // Generic contract binding to access the raw methods on +} + +// UnchainedStakingCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type UnchainedStakingCallerRaw struct { + Contract *UnchainedStakingCaller // Generic read-only contract binding to access the raw methods on +} + +// UnchainedStakingTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type UnchainedStakingTransactorRaw struct { + Contract *UnchainedStakingTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewUnchainedStaking creates a new instance of UnchainedStaking, bound to a specific deployed contract. +func NewUnchainedStaking(address common.Address, backend bind.ContractBackend) (*UnchainedStaking, error) { + contract, err := bindUnchainedStaking(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &UnchainedStaking{UnchainedStakingCaller: UnchainedStakingCaller{contract: contract}, UnchainedStakingTransactor: UnchainedStakingTransactor{contract: contract}, UnchainedStakingFilterer: UnchainedStakingFilterer{contract: contract}}, nil +} + +// NewUnchainedStakingCaller creates a new read-only instance of UnchainedStaking, bound to a specific deployed contract. +func NewUnchainedStakingCaller(address common.Address, caller bind.ContractCaller) (*UnchainedStakingCaller, error) { + contract, err := bindUnchainedStaking(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &UnchainedStakingCaller{contract: contract}, nil +} + +// NewUnchainedStakingTransactor creates a new write-only instance of UnchainedStaking, bound to a specific deployed contract. +func NewUnchainedStakingTransactor(address common.Address, transactor bind.ContractTransactor) (*UnchainedStakingTransactor, error) { + contract, err := bindUnchainedStaking(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &UnchainedStakingTransactor{contract: contract}, nil +} + +// NewUnchainedStakingFilterer creates a new log filterer instance of UnchainedStaking, bound to a specific deployed contract. +func NewUnchainedStakingFilterer(address common.Address, filterer bind.ContractFilterer) (*UnchainedStakingFilterer, error) { + contract, err := bindUnchainedStaking(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &UnchainedStakingFilterer{contract: contract}, nil +} + +// bindUnchainedStaking binds a generic wrapper to an already deployed contract. +func bindUnchainedStaking(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := UnchainedStakingMetaData.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 (_UnchainedStaking *UnchainedStakingRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _UnchainedStaking.Contract.UnchainedStakingCaller.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 (_UnchainedStaking *UnchainedStakingRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _UnchainedStaking.Contract.UnchainedStakingTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_UnchainedStaking *UnchainedStakingRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _UnchainedStaking.Contract.UnchainedStakingTransactor.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 (_UnchainedStaking *UnchainedStakingCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _UnchainedStaking.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 (_UnchainedStaking *UnchainedStakingTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _UnchainedStaking.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_UnchainedStaking *UnchainedStakingTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _UnchainedStaking.Contract.contract.Transact(opts, method, params...) +} + +// BlsAddressOf is a free data retrieval call binding the contract method 0x9e95a1a5. +// +// Solidity: function blsAddressOf(address evm) view returns(bytes20) +func (_UnchainedStaking *UnchainedStakingCaller) BlsAddressOf(opts *bind.CallOpts, evm common.Address) ([20]byte, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "blsAddressOf", evm) + + if err != nil { + return *new([20]byte), err + } + + out0 := *abi.ConvertType(out[0], new([20]byte)).(*[20]byte) + + return out0, err + +} + +// BlsAddressOf is a free data retrieval call binding the contract method 0x9e95a1a5. +// +// Solidity: function blsAddressOf(address evm) view returns(bytes20) +func (_UnchainedStaking *UnchainedStakingSession) BlsAddressOf(evm common.Address) ([20]byte, error) { + return _UnchainedStaking.Contract.BlsAddressOf(&_UnchainedStaking.CallOpts, evm) +} + +// BlsAddressOf is a free data retrieval call binding the contract method 0x9e95a1a5. +// +// Solidity: function blsAddressOf(address evm) view returns(bytes20) +func (_UnchainedStaking *UnchainedStakingCallerSession) BlsAddressOf(evm common.Address) ([20]byte, error) { + return _UnchainedStaking.Contract.BlsAddressOf(&_UnchainedStaking.CallOpts, evm) +} + +// EvmAddressOf is a free data retrieval call binding the contract method 0x40043ead. +// +// Solidity: function evmAddressOf(bytes20 bls) view returns(address) +func (_UnchainedStaking *UnchainedStakingCaller) EvmAddressOf(opts *bind.CallOpts, bls [20]byte) (common.Address, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "evmAddressOf", bls) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// EvmAddressOf is a free data retrieval call binding the contract method 0x40043ead. +// +// Solidity: function evmAddressOf(bytes20 bls) view returns(address) +func (_UnchainedStaking *UnchainedStakingSession) EvmAddressOf(bls [20]byte) (common.Address, error) { + return _UnchainedStaking.Contract.EvmAddressOf(&_UnchainedStaking.CallOpts, bls) +} + +// EvmAddressOf is a free data retrieval call binding the contract method 0x40043ead. +// +// Solidity: function evmAddressOf(bytes20 bls) view returns(address) +func (_UnchainedStaking *UnchainedStakingCallerSession) EvmAddressOf(bls [20]byte) (common.Address, error) { + return _UnchainedStaking.Contract.EvmAddressOf(&_UnchainedStaking.CallOpts, bls) +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCaller) GetChainId(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getChainId") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingSession) GetChainId() (*big.Int, error) { + return _UnchainedStaking.Contract.GetChainId(&_UnchainedStaking.CallOpts) +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetChainId() (*big.Int, error) { + return _UnchainedStaking.Contract.GetChainId(&_UnchainedStaking.CallOpts) +} + +// GetConsensusThreshold is a free data retrieval call binding the contract method 0xd42791e1. +// +// Solidity: function getConsensusThreshold() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCaller) GetConsensusThreshold(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getConsensusThreshold") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetConsensusThreshold is a free data retrieval call binding the contract method 0xd42791e1. +// +// Solidity: function getConsensusThreshold() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingSession) GetConsensusThreshold() (*big.Int, error) { + return _UnchainedStaking.Contract.GetConsensusThreshold(&_UnchainedStaking.CallOpts) +} + +// GetConsensusThreshold is a free data retrieval call binding the contract method 0xd42791e1. +// +// Solidity: function getConsensusThreshold() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetConsensusThreshold() (*big.Int, error) { + return _UnchainedStaking.Contract.GetConsensusThreshold(&_UnchainedStaking.CallOpts) +} + +// GetNftPrice is a free data retrieval call binding the contract method 0x7bf0989a. +// +// Solidity: function getNftPrice(uint256 nftId) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCaller) GetNftPrice(opts *bind.CallOpts, nftId *big.Int) (*big.Int, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getNftPrice", nftId) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetNftPrice is a free data retrieval call binding the contract method 0x7bf0989a. +// +// Solidity: function getNftPrice(uint256 nftId) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingSession) GetNftPrice(nftId *big.Int) (*big.Int, error) { + return _UnchainedStaking.Contract.GetNftPrice(&_UnchainedStaking.CallOpts, nftId) +} + +// GetNftPrice is a free data retrieval call binding the contract method 0x7bf0989a. +// +// Solidity: function getNftPrice(uint256 nftId) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetNftPrice(nftId *big.Int) (*big.Int, error) { + return _UnchainedStaking.Contract.GetNftPrice(&_UnchainedStaking.CallOpts, nftId) +} + +// GetParams is a free data retrieval call binding the contract method 0x5e615a6b. +// +// Solidity: function getParams() view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingCaller) GetParams(opts *bind.CallOpts) (UnchainedStakingParamsInfo, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getParams") + + if err != nil { + return *new(UnchainedStakingParamsInfo), err + } + + out0 := *abi.ConvertType(out[0], new(UnchainedStakingParamsInfo)).(*UnchainedStakingParamsInfo) + + return out0, err + +} + +// GetParams is a free data retrieval call binding the contract method 0x5e615a6b. +// +// Solidity: function getParams() view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingSession) GetParams() (UnchainedStakingParamsInfo, error) { + return _UnchainedStaking.Contract.GetParams(&_UnchainedStaking.CallOpts) +} + +// GetParams is a free data retrieval call binding the contract method 0x5e615a6b. +// +// Solidity: function getParams() view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetParams() (UnchainedStakingParamsInfo, error) { + return _UnchainedStaking.Contract.GetParams(&_UnchainedStaking.CallOpts) +} + +// GetRequestedSetNftPrice is a free data retrieval call binding the contract method 0x45a6e62f. +// +// Solidity: function getRequestedSetNftPrice((uint256,uint256,uint256) key, address requester) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCaller) GetRequestedSetNftPrice(opts *bind.CallOpts, key UnchainedStakingEIP712SetNftPriceKey, requester common.Address) (bool, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getRequestedSetNftPrice", key, requester) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// GetRequestedSetNftPrice is a free data retrieval call binding the contract method 0x45a6e62f. +// +// Solidity: function getRequestedSetNftPrice((uint256,uint256,uint256) key, address requester) view returns(bool) +func (_UnchainedStaking *UnchainedStakingSession) GetRequestedSetNftPrice(key UnchainedStakingEIP712SetNftPriceKey, requester common.Address) (bool, error) { + return _UnchainedStaking.Contract.GetRequestedSetNftPrice(&_UnchainedStaking.CallOpts, key, requester) +} + +// GetRequestedSetNftPrice is a free data retrieval call binding the contract method 0x45a6e62f. +// +// Solidity: function getRequestedSetNftPrice((uint256,uint256,uint256) key, address requester) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetRequestedSetNftPrice(key UnchainedStakingEIP712SetNftPriceKey, requester common.Address) (bool, error) { + return _UnchainedStaking.Contract.GetRequestedSetNftPrice(&_UnchainedStaking.CallOpts, key, requester) +} + +// GetRequestedSetParams is a free data retrieval call binding the contract method 0x984d92e8. +// +// Solidity: function getRequestedSetParams((address,address,address,uint256,uint256,uint256) key, address requester) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCaller) GetRequestedSetParams(opts *bind.CallOpts, key UnchainedStakingEIP712SetParamsKey, requester common.Address) (bool, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getRequestedSetParams", key, requester) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// GetRequestedSetParams is a free data retrieval call binding the contract method 0x984d92e8. +// +// Solidity: function getRequestedSetParams((address,address,address,uint256,uint256,uint256) key, address requester) view returns(bool) +func (_UnchainedStaking *UnchainedStakingSession) GetRequestedSetParams(key UnchainedStakingEIP712SetParamsKey, requester common.Address) (bool, error) { + return _UnchainedStaking.Contract.GetRequestedSetParams(&_UnchainedStaking.CallOpts, key, requester) +} + +// GetRequestedSetParams is a free data retrieval call binding the contract method 0x984d92e8. +// +// Solidity: function getRequestedSetParams((address,address,address,uint256,uint256,uint256) key, address requester) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetRequestedSetParams(key UnchainedStakingEIP712SetParamsKey, requester common.Address) (bool, error) { + return _UnchainedStaking.Contract.GetRequestedSetParams(&_UnchainedStaking.CallOpts, key, requester) +} + +// GetRequestedTransfer is a free data retrieval call binding the contract method 0xf8560edb. +// +// Solidity: function getRequestedTransfer((address,address,uint256,uint256[],uint256[]) key, address transferer) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCaller) GetRequestedTransfer(opts *bind.CallOpts, key UnchainedStakingEIP712TransferKey, transferer common.Address) (bool, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getRequestedTransfer", key, transferer) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// GetRequestedTransfer is a free data retrieval call binding the contract method 0xf8560edb. +// +// Solidity: function getRequestedTransfer((address,address,uint256,uint256[],uint256[]) key, address transferer) view returns(bool) +func (_UnchainedStaking *UnchainedStakingSession) GetRequestedTransfer(key UnchainedStakingEIP712TransferKey, transferer common.Address) (bool, error) { + return _UnchainedStaking.Contract.GetRequestedTransfer(&_UnchainedStaking.CallOpts, key, transferer) +} + +// GetRequestedTransfer is a free data retrieval call binding the contract method 0xf8560edb. +// +// Solidity: function getRequestedTransfer((address,address,uint256,uint256[],uint256[]) key, address transferer) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetRequestedTransfer(key UnchainedStakingEIP712TransferKey, transferer common.Address) (bool, error) { + return _UnchainedStaking.Contract.GetRequestedTransfer(&_UnchainedStaking.CallOpts, key, transferer) +} + +// GetSetNftPriceData is a free data retrieval call binding the contract method 0xbbb5b849. +// +// Solidity: function getSetNftPriceData((uint256,uint256,uint256) key) view returns((uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingCaller) GetSetNftPriceData(opts *bind.CallOpts, key UnchainedStakingEIP712SetNftPriceKey) (UnchainedStakingNftPriceInfo, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getSetNftPriceData", key) + + if err != nil { + return *new(UnchainedStakingNftPriceInfo), err + } + + out0 := *abi.ConvertType(out[0], new(UnchainedStakingNftPriceInfo)).(*UnchainedStakingNftPriceInfo) + + return out0, err + +} + +// GetSetNftPriceData is a free data retrieval call binding the contract method 0xbbb5b849. +// +// Solidity: function getSetNftPriceData((uint256,uint256,uint256) key) view returns((uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingSession) GetSetNftPriceData(key UnchainedStakingEIP712SetNftPriceKey) (UnchainedStakingNftPriceInfo, error) { + return _UnchainedStaking.Contract.GetSetNftPriceData(&_UnchainedStaking.CallOpts, key) +} + +// GetSetNftPriceData is a free data retrieval call binding the contract method 0xbbb5b849. +// +// Solidity: function getSetNftPriceData((uint256,uint256,uint256) key) view returns((uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetSetNftPriceData(key UnchainedStakingEIP712SetNftPriceKey) (UnchainedStakingNftPriceInfo, error) { + return _UnchainedStaking.Contract.GetSetNftPriceData(&_UnchainedStaking.CallOpts, key) +} + +// GetSetParamsData is a free data retrieval call binding the contract method 0x300fab4f. +// +// Solidity: function getSetParamsData((address,address,address,uint256,uint256,uint256) key) view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingCaller) GetSetParamsData(opts *bind.CallOpts, key UnchainedStakingEIP712SetParamsKey) (UnchainedStakingParamsInfo, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getSetParamsData", key) + + if err != nil { + return *new(UnchainedStakingParamsInfo), err + } + + out0 := *abi.ConvertType(out[0], new(UnchainedStakingParamsInfo)).(*UnchainedStakingParamsInfo) + + return out0, err + +} + +// GetSetParamsData is a free data retrieval call binding the contract method 0x300fab4f. +// +// Solidity: function getSetParamsData((address,address,address,uint256,uint256,uint256) key) view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingSession) GetSetParamsData(key UnchainedStakingEIP712SetParamsKey) (UnchainedStakingParamsInfo, error) { + return _UnchainedStaking.Contract.GetSetParamsData(&_UnchainedStaking.CallOpts, key) +} + +// GetSetParamsData is a free data retrieval call binding the contract method 0x300fab4f. +// +// Solidity: function getSetParamsData((address,address,address,uint256,uint256,uint256) key) view returns((address,address,address,uint256,uint256,uint256,uint256,bool)) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetSetParamsData(key UnchainedStakingEIP712SetParamsKey) (UnchainedStakingParamsInfo, error) { + return _UnchainedStaking.Contract.GetSetParamsData(&_UnchainedStaking.CallOpts, key) +} + +// GetStake is a free data retrieval call binding the contract method 0x7a766460. +// +// Solidity: function getStake(address evm) view returns((uint256,uint256,uint256[])) +func (_UnchainedStaking *UnchainedStakingCaller) GetStake(opts *bind.CallOpts, evm common.Address) (UnchainedStakingStake, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getStake", evm) + + if err != nil { + return *new(UnchainedStakingStake), err + } + + out0 := *abi.ConvertType(out[0], new(UnchainedStakingStake)).(*UnchainedStakingStake) + + return out0, err + +} + +// GetStake is a free data retrieval call binding the contract method 0x7a766460. +// +// Solidity: function getStake(address evm) view returns((uint256,uint256,uint256[])) +func (_UnchainedStaking *UnchainedStakingSession) GetStake(evm common.Address) (UnchainedStakingStake, error) { + return _UnchainedStaking.Contract.GetStake(&_UnchainedStaking.CallOpts, evm) +} + +// GetStake is a free data retrieval call binding the contract method 0x7a766460. +// +// Solidity: function getStake(address evm) view returns((uint256,uint256,uint256[])) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetStake(evm common.Address) (UnchainedStakingStake, error) { + return _UnchainedStaking.Contract.GetStake(&_UnchainedStaking.CallOpts, evm) +} + +// GetStake0 is a free data retrieval call binding the contract method 0xf86fec69. +// +// Solidity: function getStake(bytes20 bls) view returns((uint256,uint256,uint256[])) +func (_UnchainedStaking *UnchainedStakingCaller) GetStake0(opts *bind.CallOpts, bls [20]byte) (UnchainedStakingStake, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getStake0", bls) + + if err != nil { + return *new(UnchainedStakingStake), err + } + + out0 := *abi.ConvertType(out[0], new(UnchainedStakingStake)).(*UnchainedStakingStake) + + return out0, err + +} + +// GetStake0 is a free data retrieval call binding the contract method 0xf86fec69. +// +// Solidity: function getStake(bytes20 bls) view returns((uint256,uint256,uint256[])) +func (_UnchainedStaking *UnchainedStakingSession) GetStake0(bls [20]byte) (UnchainedStakingStake, error) { + return _UnchainedStaking.Contract.GetStake0(&_UnchainedStaking.CallOpts, bls) +} + +// GetStake0 is a free data retrieval call binding the contract method 0xf86fec69. +// +// Solidity: function getStake(bytes20 bls) view returns((uint256,uint256,uint256[])) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetStake0(bls [20]byte) (UnchainedStakingStake, error) { + return _UnchainedStaking.Contract.GetStake0(&_UnchainedStaking.CallOpts, bls) +} + +// GetTotalVotingPower is a free data retrieval call binding the contract method 0x11acc1a7. +// +// Solidity: function getTotalVotingPower() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCaller) GetTotalVotingPower(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getTotalVotingPower") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetTotalVotingPower is a free data retrieval call binding the contract method 0x11acc1a7. +// +// Solidity: function getTotalVotingPower() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingSession) GetTotalVotingPower() (*big.Int, error) { + return _UnchainedStaking.Contract.GetTotalVotingPower(&_UnchainedStaking.CallOpts) +} + +// GetTotalVotingPower is a free data retrieval call binding the contract method 0x11acc1a7. +// +// Solidity: function getTotalVotingPower() view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetTotalVotingPower() (*big.Int, error) { + return _UnchainedStaking.Contract.GetTotalVotingPower(&_UnchainedStaking.CallOpts) +} + +// GetTransferData is a free data retrieval call binding the contract method 0x865e1281. +// +// Solidity: function getTransferData((address,address,uint256,uint256[],uint256[]) key) view returns((address,address,uint256,uint256[],uint256,bool,uint256[])) +func (_UnchainedStaking *UnchainedStakingCaller) GetTransferData(opts *bind.CallOpts, key UnchainedStakingEIP712TransferKey) (UnchainedStakingTransferInfo, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getTransferData", key) + + if err != nil { + return *new(UnchainedStakingTransferInfo), err + } + + out0 := *abi.ConvertType(out[0], new(UnchainedStakingTransferInfo)).(*UnchainedStakingTransferInfo) + + return out0, err + +} + +// GetTransferData is a free data retrieval call binding the contract method 0x865e1281. +// +// Solidity: function getTransferData((address,address,uint256,uint256[],uint256[]) key) view returns((address,address,uint256,uint256[],uint256,bool,uint256[])) +func (_UnchainedStaking *UnchainedStakingSession) GetTransferData(key UnchainedStakingEIP712TransferKey) (UnchainedStakingTransferInfo, error) { + return _UnchainedStaking.Contract.GetTransferData(&_UnchainedStaking.CallOpts, key) +} + +// GetTransferData is a free data retrieval call binding the contract method 0x865e1281. +// +// Solidity: function getTransferData((address,address,uint256,uint256[],uint256[]) key) view returns((address,address,uint256,uint256[],uint256,bool,uint256[])) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetTransferData(key UnchainedStakingEIP712TransferKey) (UnchainedStakingTransferInfo, error) { + return _UnchainedStaking.Contract.GetTransferData(&_UnchainedStaking.CallOpts, key) +} + +// GetVotingPower is a free data retrieval call binding the contract method 0x68eacf93. +// +// Solidity: function getVotingPower(bytes20 bls) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCaller) GetVotingPower(opts *bind.CallOpts, bls [20]byte) (*big.Int, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getVotingPower", bls) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetVotingPower is a free data retrieval call binding the contract method 0x68eacf93. +// +// Solidity: function getVotingPower(bytes20 bls) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingSession) GetVotingPower(bls [20]byte) (*big.Int, error) { + return _UnchainedStaking.Contract.GetVotingPower(&_UnchainedStaking.CallOpts, bls) +} + +// GetVotingPower is a free data retrieval call binding the contract method 0x68eacf93. +// +// Solidity: function getVotingPower(bytes20 bls) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetVotingPower(bls [20]byte) (*big.Int, error) { + return _UnchainedStaking.Contract.GetVotingPower(&_UnchainedStaking.CallOpts, bls) +} + +// GetVotingPower0 is a free data retrieval call binding the contract method 0xbb4d4436. +// +// Solidity: function getVotingPower(address evm) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCaller) GetVotingPower0(opts *bind.CallOpts, evm common.Address) (*big.Int, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "getVotingPower0", evm) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetVotingPower0 is a free data retrieval call binding the contract method 0xbb4d4436. +// +// Solidity: function getVotingPower(address evm) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingSession) GetVotingPower0(evm common.Address) (*big.Int, error) { + return _UnchainedStaking.Contract.GetVotingPower0(&_UnchainedStaking.CallOpts, evm) +} + +// GetVotingPower0 is a free data retrieval call binding the contract method 0xbb4d4436. +// +// Solidity: function getVotingPower(address evm) view returns(uint256) +func (_UnchainedStaking *UnchainedStakingCallerSession) GetVotingPower0(evm common.Address) (*big.Int, error) { + return _UnchainedStaking.Contract.GetVotingPower0(&_UnchainedStaking.CallOpts, evm) +} + +// OnERC721Received is a free data retrieval call binding the contract method 0x150b7a02. +// +// Solidity: function onERC721Received(address , address , uint256 , bytes ) view returns(bytes4) +func (_UnchainedStaking *UnchainedStakingCaller) OnERC721Received(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 []byte) ([4]byte, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "onERC721Received", arg0, arg1, arg2, arg3) + + if err != nil { + return *new([4]byte), err + } + + out0 := *abi.ConvertType(out[0], new([4]byte)).(*[4]byte) + + return out0, err + +} + +// OnERC721Received is a free data retrieval call binding the contract method 0x150b7a02. +// +// Solidity: function onERC721Received(address , address , uint256 , bytes ) view returns(bytes4) +func (_UnchainedStaking *UnchainedStakingSession) OnERC721Received(arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 []byte) ([4]byte, error) { + return _UnchainedStaking.Contract.OnERC721Received(&_UnchainedStaking.CallOpts, arg0, arg1, arg2, arg3) +} + +// OnERC721Received is a free data retrieval call binding the contract method 0x150b7a02. +// +// Solidity: function onERC721Received(address , address , uint256 , bytes ) view returns(bytes4) +func (_UnchainedStaking *UnchainedStakingCallerSession) OnERC721Received(arg0 common.Address, arg1 common.Address, arg2 *big.Int, arg3 []byte) ([4]byte, error) { + return _UnchainedStaking.Contract.OnERC721Received(&_UnchainedStaking.CallOpts, arg0, arg1, arg2, arg3) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_UnchainedStaking *UnchainedStakingCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _UnchainedStaking.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 (_UnchainedStaking *UnchainedStakingSession) Owner() (common.Address, error) { + return _UnchainedStaking.Contract.Owner(&_UnchainedStaking.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_UnchainedStaking *UnchainedStakingCallerSession) Owner() (common.Address, error) { + return _UnchainedStaking.Contract.Owner(&_UnchainedStaking.CallOpts) +} + +// SignerToStaker is a free data retrieval call binding the contract method 0xad5a98c5. +// +// Solidity: function signerToStaker(address signer) view returns(address) +func (_UnchainedStaking *UnchainedStakingCaller) SignerToStaker(opts *bind.CallOpts, signer common.Address) (common.Address, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "signerToStaker", signer) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SignerToStaker is a free data retrieval call binding the contract method 0xad5a98c5. +// +// Solidity: function signerToStaker(address signer) view returns(address) +func (_UnchainedStaking *UnchainedStakingSession) SignerToStaker(signer common.Address) (common.Address, error) { + return _UnchainedStaking.Contract.SignerToStaker(&_UnchainedStaking.CallOpts, signer) +} + +// SignerToStaker is a free data retrieval call binding the contract method 0xad5a98c5. +// +// Solidity: function signerToStaker(address signer) view returns(address) +func (_UnchainedStaking *UnchainedStakingCallerSession) SignerToStaker(signer common.Address) (common.Address, error) { + return _UnchainedStaking.Contract.SignerToStaker(&_UnchainedStaking.CallOpts, signer) +} + +// StakerToSigner is a free data retrieval call binding the contract method 0xc7bcae78. +// +// Solidity: function stakerToSigner(address staker) view returns(address) +func (_UnchainedStaking *UnchainedStakingCaller) StakerToSigner(opts *bind.CallOpts, staker common.Address) (common.Address, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "stakerToSigner", staker) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// StakerToSigner is a free data retrieval call binding the contract method 0xc7bcae78. +// +// Solidity: function stakerToSigner(address staker) view returns(address) +func (_UnchainedStaking *UnchainedStakingSession) StakerToSigner(staker common.Address) (common.Address, error) { + return _UnchainedStaking.Contract.StakerToSigner(&_UnchainedStaking.CallOpts, staker) +} + +// StakerToSigner is a free data retrieval call binding the contract method 0xc7bcae78. +// +// Solidity: function stakerToSigner(address staker) view returns(address) +func (_UnchainedStaking *UnchainedStakingCallerSession) StakerToSigner(staker common.Address) (common.Address, error) { + return _UnchainedStaking.Contract.StakerToSigner(&_UnchainedStaking.CallOpts, staker) +} + +// Verify is a free data retrieval call binding the contract method 0x6e0b9e40. +// +// Solidity: function verify((address,address,address,address,uint256,uint256,uint256) eip712SetParam, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCaller) Verify(opts *bind.CallOpts, eip712SetParam UnchainedStakingEIP712SetParams, signature UnchainedStakingSignature) (bool, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "verify", eip712SetParam, signature) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Verify is a free data retrieval call binding the contract method 0x6e0b9e40. +// +// Solidity: function verify((address,address,address,address,uint256,uint256,uint256) eip712SetParam, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingSession) Verify(eip712SetParam UnchainedStakingEIP712SetParams, signature UnchainedStakingSignature) (bool, error) { + return _UnchainedStaking.Contract.Verify(&_UnchainedStaking.CallOpts, eip712SetParam, signature) +} + +// Verify is a free data retrieval call binding the contract method 0x6e0b9e40. +// +// Solidity: function verify((address,address,address,address,uint256,uint256,uint256) eip712SetParam, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCallerSession) Verify(eip712SetParam UnchainedStakingEIP712SetParams, signature UnchainedStakingSignature) (bool, error) { + return _UnchainedStaking.Contract.Verify(&_UnchainedStaking.CallOpts, eip712SetParam, signature) +} + +// Verify0 is a free data retrieval call binding the contract method 0x709eb01b. +// +// Solidity: function verify((address,uint256,uint256,uint256) eip712SetNftPrice, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCaller) Verify0(opts *bind.CallOpts, eip712SetNftPrice UnchainedStakingEIP712SetNftPrice, signature UnchainedStakingSignature) (bool, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "verify0", eip712SetNftPrice, signature) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Verify0 is a free data retrieval call binding the contract method 0x709eb01b. +// +// Solidity: function verify((address,uint256,uint256,uint256) eip712SetNftPrice, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingSession) Verify0(eip712SetNftPrice UnchainedStakingEIP712SetNftPrice, signature UnchainedStakingSignature) (bool, error) { + return _UnchainedStaking.Contract.Verify0(&_UnchainedStaking.CallOpts, eip712SetNftPrice, signature) +} + +// Verify0 is a free data retrieval call binding the contract method 0x709eb01b. +// +// Solidity: function verify((address,uint256,uint256,uint256) eip712SetNftPrice, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCallerSession) Verify0(eip712SetNftPrice UnchainedStakingEIP712SetNftPrice, signature UnchainedStakingSignature) (bool, error) { + return _UnchainedStaking.Contract.Verify0(&_UnchainedStaking.CallOpts, eip712SetNftPrice, signature) +} + +// Verify1 is a free data retrieval call binding the contract method 0x7856cc70. +// +// Solidity: function verify((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCaller) Verify1(opts *bind.CallOpts, eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (bool, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "verify1", eip712SetSigner, stakerSignature, signerSignature) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Verify1 is a free data retrieval call binding the contract method 0x7856cc70. +// +// Solidity: function verify((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingSession) Verify1(eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (bool, error) { + return _UnchainedStaking.Contract.Verify1(&_UnchainedStaking.CallOpts, eip712SetSigner, stakerSignature, signerSignature) +} + +// Verify1 is a free data retrieval call binding the contract method 0x7856cc70. +// +// Solidity: function verify((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCallerSession) Verify1(eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (bool, error) { + return _UnchainedStaking.Contract.Verify1(&_UnchainedStaking.CallOpts, eip712SetSigner, stakerSignature, signerSignature) +} + +// Verify2 is a free data retrieval call binding the contract method 0xb7543d3e. +// +// Solidity: function verify((address,address,address,uint256,uint256[],uint256[]) eip712Transfer, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCaller) Verify2(opts *bind.CallOpts, eip712Transfer UnchainedStakingEIP712Transfer, signature UnchainedStakingSignature) (bool, error) { + var out []interface{} + err := _UnchainedStaking.contract.Call(opts, &out, "verify2", eip712Transfer, signature) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// Verify2 is a free data retrieval call binding the contract method 0xb7543d3e. +// +// Solidity: function verify((address,address,address,uint256,uint256[],uint256[]) eip712Transfer, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingSession) Verify2(eip712Transfer UnchainedStakingEIP712Transfer, signature UnchainedStakingSignature) (bool, error) { + return _UnchainedStaking.Contract.Verify2(&_UnchainedStaking.CallOpts, eip712Transfer, signature) +} + +// Verify2 is a free data retrieval call binding the contract method 0xb7543d3e. +// +// Solidity: function verify((address,address,address,uint256,uint256[],uint256[]) eip712Transfer, (uint8,bytes32,bytes32) signature) view returns(bool) +func (_UnchainedStaking *UnchainedStakingCallerSession) Verify2(eip712Transfer UnchainedStakingEIP712Transfer, signature UnchainedStakingSignature) (bool, error) { + return _UnchainedStaking.Contract.Verify2(&_UnchainedStaking.CallOpts, eip712Transfer, signature) +} + +// Extend is a paid mutator transaction binding the contract method 0x9714378c. +// +// Solidity: function extend(uint256 duration) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) Extend(opts *bind.TransactOpts, duration *big.Int) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "extend", duration) +} + +// Extend is a paid mutator transaction binding the contract method 0x9714378c. +// +// Solidity: function extend(uint256 duration) returns() +func (_UnchainedStaking *UnchainedStakingSession) Extend(duration *big.Int) (*types.Transaction, error) { + return _UnchainedStaking.Contract.Extend(&_UnchainedStaking.TransactOpts, duration) +} + +// Extend is a paid mutator transaction binding the contract method 0x9714378c. +// +// Solidity: function extend(uint256 duration) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) Extend(duration *big.Int) (*types.Transaction, error) { + return _UnchainedStaking.Contract.Extend(&_UnchainedStaking.TransactOpts, duration) +} + +// IncreaseStake is a paid mutator transaction binding the contract method 0x0062ad9d. +// +// Solidity: function increaseStake(uint256 amount, uint256[] nftIds) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) IncreaseStake(opts *bind.TransactOpts, amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "increaseStake", amount, nftIds) +} + +// IncreaseStake is a paid mutator transaction binding the contract method 0x0062ad9d. +// +// Solidity: function increaseStake(uint256 amount, uint256[] nftIds) returns() +func (_UnchainedStaking *UnchainedStakingSession) IncreaseStake(amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { + return _UnchainedStaking.Contract.IncreaseStake(&_UnchainedStaking.TransactOpts, amount, nftIds) +} + +// IncreaseStake is a paid mutator transaction binding the contract method 0x0062ad9d. +// +// Solidity: function increaseStake(uint256 amount, uint256[] nftIds) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) IncreaseStake(amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { + return _UnchainedStaking.Contract.IncreaseStake(&_UnchainedStaking.TransactOpts, amount, nftIds) +} + +// RecoverERC20 is a paid mutator transaction binding the contract method 0x1171bda9. +// +// Solidity: function recoverERC20(address token, address recipient, uint256 amount) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) RecoverERC20(opts *bind.TransactOpts, token common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "recoverERC20", token, recipient, amount) +} + +// RecoverERC20 is a paid mutator transaction binding the contract method 0x1171bda9. +// +// Solidity: function recoverERC20(address token, address recipient, uint256 amount) returns() +func (_UnchainedStaking *UnchainedStakingSession) RecoverERC20(token common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _UnchainedStaking.Contract.RecoverERC20(&_UnchainedStaking.TransactOpts, token, recipient, amount) +} + +// RecoverERC20 is a paid mutator transaction binding the contract method 0x1171bda9. +// +// Solidity: function recoverERC20(address token, address recipient, uint256 amount) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) RecoverERC20(token common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _UnchainedStaking.Contract.RecoverERC20(&_UnchainedStaking.TransactOpts, token, recipient, amount) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_UnchainedStaking *UnchainedStakingTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_UnchainedStaking *UnchainedStakingSession) RenounceOwnership() (*types.Transaction, error) { + return _UnchainedStaking.Contract.RenounceOwnership(&_UnchainedStaking.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _UnchainedStaking.Contract.RenounceOwnership(&_UnchainedStaking.TransactOpts) +} + +// SetBlsAddress is a paid mutator transaction binding the contract method 0x3e5d4675. +// +// Solidity: function setBlsAddress(bytes20 blsAddress) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) SetBlsAddress(opts *bind.TransactOpts, blsAddress [20]byte) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "setBlsAddress", blsAddress) +} + +// SetBlsAddress is a paid mutator transaction binding the contract method 0x3e5d4675. +// +// Solidity: function setBlsAddress(bytes20 blsAddress) returns() +func (_UnchainedStaking *UnchainedStakingSession) SetBlsAddress(blsAddress [20]byte) (*types.Transaction, error) { + return _UnchainedStaking.Contract.SetBlsAddress(&_UnchainedStaking.TransactOpts, blsAddress) +} + +// SetBlsAddress is a paid mutator transaction binding the contract method 0x3e5d4675. +// +// Solidity: function setBlsAddress(bytes20 blsAddress) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) SetBlsAddress(blsAddress [20]byte) (*types.Transaction, error) { + return _UnchainedStaking.Contract.SetBlsAddress(&_UnchainedStaking.TransactOpts, blsAddress) +} + +// SetNftPrices is a paid mutator transaction binding the contract method 0xd43d8d1e. +// +// Solidity: function setNftPrices((address,uint256,uint256,uint256)[] eip712SetNftPrices, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) SetNftPrices(opts *bind.TransactOpts, eip712SetNftPrices []UnchainedStakingEIP712SetNftPrice, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "setNftPrices", eip712SetNftPrices, signatures) +} + +// SetNftPrices is a paid mutator transaction binding the contract method 0xd43d8d1e. +// +// Solidity: function setNftPrices((address,uint256,uint256,uint256)[] eip712SetNftPrices, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingSession) SetNftPrices(eip712SetNftPrices []UnchainedStakingEIP712SetNftPrice, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.Contract.SetNftPrices(&_UnchainedStaking.TransactOpts, eip712SetNftPrices, signatures) +} + +// SetNftPrices is a paid mutator transaction binding the contract method 0xd43d8d1e. +// +// Solidity: function setNftPrices((address,uint256,uint256,uint256)[] eip712SetNftPrices, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) SetNftPrices(eip712SetNftPrices []UnchainedStakingEIP712SetNftPrice, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.Contract.SetNftPrices(&_UnchainedStaking.TransactOpts, eip712SetNftPrices, signatures) +} + +// SetParams is a paid mutator transaction binding the contract method 0x642ca50f. +// +// Solidity: function setParams((address,address,address,address,uint256,uint256,uint256)[] eip712SetParams, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) SetParams(opts *bind.TransactOpts, eip712SetParams []UnchainedStakingEIP712SetParams, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "setParams", eip712SetParams, signatures) +} + +// SetParams is a paid mutator transaction binding the contract method 0x642ca50f. +// +// Solidity: function setParams((address,address,address,address,uint256,uint256,uint256)[] eip712SetParams, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingSession) SetParams(eip712SetParams []UnchainedStakingEIP712SetParams, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.Contract.SetParams(&_UnchainedStaking.TransactOpts, eip712SetParams, signatures) +} + +// SetParams is a paid mutator transaction binding the contract method 0x642ca50f. +// +// Solidity: function setParams((address,address,address,address,uint256,uint256,uint256)[] eip712SetParams, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) SetParams(eip712SetParams []UnchainedStakingEIP712SetParams, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.Contract.SetParams(&_UnchainedStaking.TransactOpts, eip712SetParams, signatures) +} + +// SetSigner is a paid mutator transaction binding the contract method 0xd9d35a4d. +// +// Solidity: function setSigner((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) SetSigner(opts *bind.TransactOpts, eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "setSigner", eip712SetSigner, stakerSignature, signerSignature) +} + +// SetSigner is a paid mutator transaction binding the contract method 0xd9d35a4d. +// +// Solidity: function setSigner((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) returns() +func (_UnchainedStaking *UnchainedStakingSession) SetSigner(eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.Contract.SetSigner(&_UnchainedStaking.TransactOpts, eip712SetSigner, stakerSignature, signerSignature) +} + +// SetSigner is a paid mutator transaction binding the contract method 0xd9d35a4d. +// +// Solidity: function setSigner((address,address) eip712SetSigner, (uint8,bytes32,bytes32) stakerSignature, (uint8,bytes32,bytes32) signerSignature) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) SetSigner(eip712SetSigner UnchainedStakingEIP712SetSigner, stakerSignature UnchainedStakingSignature, signerSignature UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.Contract.SetSigner(&_UnchainedStaking.TransactOpts, eip712SetSigner, stakerSignature, signerSignature) +} + +// Stake is a paid mutator transaction binding the contract method 0x9debdddc. +// +// Solidity: function stake(uint256 duration, uint256 amount, uint256[] nftIds) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) Stake(opts *bind.TransactOpts, duration *big.Int, amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "stake", duration, amount, nftIds) +} + +// Stake is a paid mutator transaction binding the contract method 0x9debdddc. +// +// Solidity: function stake(uint256 duration, uint256 amount, uint256[] nftIds) returns() +func (_UnchainedStaking *UnchainedStakingSession) Stake(duration *big.Int, amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { + return _UnchainedStaking.Contract.Stake(&_UnchainedStaking.TransactOpts, duration, amount, nftIds) +} + +// Stake is a paid mutator transaction binding the contract method 0x9debdddc. +// +// Solidity: function stake(uint256 duration, uint256 amount, uint256[] nftIds) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) Stake(duration *big.Int, amount *big.Int, nftIds []*big.Int) (*types.Transaction, error) { + return _UnchainedStaking.Contract.Stake(&_UnchainedStaking.TransactOpts, duration, amount, nftIds) +} + +// Transfer is a paid mutator transaction binding the contract method 0xdc668266. +// +// Solidity: function transfer((address,address,address,uint256,uint256[],uint256[])[] eip712Transferes, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) Transfer(opts *bind.TransactOpts, eip712Transferes []UnchainedStakingEIP712Transfer, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "transfer", eip712Transferes, signatures) +} + +// Transfer is a paid mutator transaction binding the contract method 0xdc668266. +// +// Solidity: function transfer((address,address,address,uint256,uint256[],uint256[])[] eip712Transferes, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingSession) Transfer(eip712Transferes []UnchainedStakingEIP712Transfer, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.Contract.Transfer(&_UnchainedStaking.TransactOpts, eip712Transferes, signatures) +} + +// Transfer is a paid mutator transaction binding the contract method 0xdc668266. +// +// Solidity: function transfer((address,address,address,uint256,uint256[],uint256[])[] eip712Transferes, (uint8,bytes32,bytes32)[] signatures) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) Transfer(eip712Transferes []UnchainedStakingEIP712Transfer, signatures []UnchainedStakingSignature) (*types.Transaction, error) { + return _UnchainedStaking.Contract.Transfer(&_UnchainedStaking.TransactOpts, eip712Transferes, signatures) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_UnchainedStaking *UnchainedStakingTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_UnchainedStaking *UnchainedStakingSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _UnchainedStaking.Contract.TransferOwnership(&_UnchainedStaking.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _UnchainedStaking.Contract.TransferOwnership(&_UnchainedStaking.TransactOpts, newOwner) +} + +// Unstake is a paid mutator transaction binding the contract method 0x2def6620. +// +// Solidity: function unstake() returns() +func (_UnchainedStaking *UnchainedStakingTransactor) Unstake(opts *bind.TransactOpts) (*types.Transaction, error) { + return _UnchainedStaking.contract.Transact(opts, "unstake") +} + +// Unstake is a paid mutator transaction binding the contract method 0x2def6620. +// +// Solidity: function unstake() returns() +func (_UnchainedStaking *UnchainedStakingSession) Unstake() (*types.Transaction, error) { + return _UnchainedStaking.Contract.Unstake(&_UnchainedStaking.TransactOpts) +} + +// Unstake is a paid mutator transaction binding the contract method 0x2def6620. +// +// Solidity: function unstake() returns() +func (_UnchainedStaking *UnchainedStakingTransactorSession) Unstake() (*types.Transaction, error) { + return _UnchainedStaking.Contract.Unstake(&_UnchainedStaking.TransactOpts) +} + +// UnchainedStakingBlsAddressChangedIterator is returned from FilterBlsAddressChanged and is used to iterate over the raw logs and unpacked data for BlsAddressChanged events raised by the UnchainedStaking contract. +type UnchainedStakingBlsAddressChangedIterator struct { + Event *UnchainedStakingBlsAddressChanged // 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 *UnchainedStakingBlsAddressChangedIterator) 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(UnchainedStakingBlsAddressChanged) + 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(UnchainedStakingBlsAddressChanged) + 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 *UnchainedStakingBlsAddressChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingBlsAddressChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingBlsAddressChanged represents a BlsAddressChanged event raised by the UnchainedStaking contract. +type UnchainedStakingBlsAddressChanged struct { + User common.Address + From [32]byte + To [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBlsAddressChanged is a free log retrieval operation binding the contract event 0xa5c20a3e40dbfce0ccdadcb27e2f561e84ddf0618a41338cc1acb1524780ff39. +// +// Solidity: event BlsAddressChanged(address indexed user, bytes32 indexed from, bytes32 indexed to) +func (_UnchainedStaking *UnchainedStakingFilterer) FilterBlsAddressChanged(opts *bind.FilterOpts, user []common.Address, from [][32]byte, to [][32]byte) (*UnchainedStakingBlsAddressChangedIterator, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "BlsAddressChanged", userRule, fromRule, toRule) + if err != nil { + return nil, err + } + return &UnchainedStakingBlsAddressChangedIterator{contract: _UnchainedStaking.contract, event: "BlsAddressChanged", logs: logs, sub: sub}, nil +} + +// WatchBlsAddressChanged is a free log subscription operation binding the contract event 0xa5c20a3e40dbfce0ccdadcb27e2f561e84ddf0618a41338cc1acb1524780ff39. +// +// Solidity: event BlsAddressChanged(address indexed user, bytes32 indexed from, bytes32 indexed to) +func (_UnchainedStaking *UnchainedStakingFilterer) WatchBlsAddressChanged(opts *bind.WatchOpts, sink chan<- *UnchainedStakingBlsAddressChanged, user []common.Address, from [][32]byte, to [][32]byte) (event.Subscription, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "BlsAddressChanged", userRule, fromRule, toRule) + 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(UnchainedStakingBlsAddressChanged) + if err := _UnchainedStaking.contract.UnpackLog(event, "BlsAddressChanged", 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 +} + +// ParseBlsAddressChanged is a log parse operation binding the contract event 0xa5c20a3e40dbfce0ccdadcb27e2f561e84ddf0618a41338cc1acb1524780ff39. +// +// Solidity: event BlsAddressChanged(address indexed user, bytes32 indexed from, bytes32 indexed to) +func (_UnchainedStaking *UnchainedStakingFilterer) ParseBlsAddressChanged(log types.Log) (*UnchainedStakingBlsAddressChanged, error) { + event := new(UnchainedStakingBlsAddressChanged) + if err := _UnchainedStaking.contract.UnpackLog(event, "BlsAddressChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UnchainedStakingExtendedIterator is returned from FilterExtended and is used to iterate over the raw logs and unpacked data for Extended events raised by the UnchainedStaking contract. +type UnchainedStakingExtendedIterator struct { + Event *UnchainedStakingExtended // 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 *UnchainedStakingExtendedIterator) 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(UnchainedStakingExtended) + 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(UnchainedStakingExtended) + 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 *UnchainedStakingExtendedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingExtendedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingExtended represents a Extended event raised by the UnchainedStaking contract. +type UnchainedStakingExtended struct { + User common.Address + Unlock *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterExtended is a free log retrieval operation binding the contract event 0xa29fc12cda82ff659de006abb10fa5ee256d922af1661e395e5f2fb6b004387e. +// +// Solidity: event Extended(address indexed user, uint256 unlock) +func (_UnchainedStaking *UnchainedStakingFilterer) FilterExtended(opts *bind.FilterOpts, user []common.Address) (*UnchainedStakingExtendedIterator, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "Extended", userRule) + if err != nil { + return nil, err + } + return &UnchainedStakingExtendedIterator{contract: _UnchainedStaking.contract, event: "Extended", logs: logs, sub: sub}, nil +} + +// WatchExtended is a free log subscription operation binding the contract event 0xa29fc12cda82ff659de006abb10fa5ee256d922af1661e395e5f2fb6b004387e. +// +// Solidity: event Extended(address indexed user, uint256 unlock) +func (_UnchainedStaking *UnchainedStakingFilterer) WatchExtended(opts *bind.WatchOpts, sink chan<- *UnchainedStakingExtended, user []common.Address) (event.Subscription, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "Extended", userRule) + 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(UnchainedStakingExtended) + if err := _UnchainedStaking.contract.UnpackLog(event, "Extended", 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 +} + +// ParseExtended is a log parse operation binding the contract event 0xa29fc12cda82ff659de006abb10fa5ee256d922af1661e395e5f2fb6b004387e. +// +// Solidity: event Extended(address indexed user, uint256 unlock) +func (_UnchainedStaking *UnchainedStakingFilterer) ParseExtended(log types.Log) (*UnchainedStakingExtended, error) { + event := new(UnchainedStakingExtended) + if err := _UnchainedStaking.contract.UnpackLog(event, "Extended", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UnchainedStakingOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the UnchainedStaking contract. +type UnchainedStakingOwnershipTransferredIterator struct { + Event *UnchainedStakingOwnershipTransferred // 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 *UnchainedStakingOwnershipTransferredIterator) 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(UnchainedStakingOwnershipTransferred) + 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(UnchainedStakingOwnershipTransferred) + 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 *UnchainedStakingOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingOwnershipTransferred represents a OwnershipTransferred event raised by the UnchainedStaking contract. +type UnchainedStakingOwnershipTransferred 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 (_UnchainedStaking *UnchainedStakingFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*UnchainedStakingOwnershipTransferredIterator, 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 := _UnchainedStaking.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &UnchainedStakingOwnershipTransferredIterator{contract: _UnchainedStaking.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 (_UnchainedStaking *UnchainedStakingFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *UnchainedStakingOwnershipTransferred, 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 := _UnchainedStaking.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(UnchainedStakingOwnershipTransferred) + if err := _UnchainedStaking.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 (_UnchainedStaking *UnchainedStakingFilterer) ParseOwnershipTransferred(log types.Log) (*UnchainedStakingOwnershipTransferred, error) { + event := new(UnchainedStakingOwnershipTransferred) + if err := _UnchainedStaking.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UnchainedStakingParamsChangedIterator is returned from FilterParamsChanged and is used to iterate over the raw logs and unpacked data for ParamsChanged events raised by the UnchainedStaking contract. +type UnchainedStakingParamsChangedIterator struct { + Event *UnchainedStakingParamsChanged // 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 *UnchainedStakingParamsChangedIterator) 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(UnchainedStakingParamsChanged) + 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(UnchainedStakingParamsChanged) + 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 *UnchainedStakingParamsChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingParamsChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingParamsChanged represents a ParamsChanged event raised by the UnchainedStaking contract. +type UnchainedStakingParamsChanged struct { + Token common.Address + Nft common.Address + NftTracker common.Address + Threshold *big.Int + Expiration *big.Int + Voted *big.Int + Nonce *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterParamsChanged is a free log retrieval operation binding the contract event 0xcccaeb9d161525e3f31950313467c2e9a945a55a1ff09658479fe753054fafe0. +// +// Solidity: event ParamsChanged(address token, address nft, address nftTracker, uint256 threshold, uint256 expiration, uint256 voted, uint256 nonce) +func (_UnchainedStaking *UnchainedStakingFilterer) FilterParamsChanged(opts *bind.FilterOpts) (*UnchainedStakingParamsChangedIterator, error) { + + logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "ParamsChanged") + if err != nil { + return nil, err + } + return &UnchainedStakingParamsChangedIterator{contract: _UnchainedStaking.contract, event: "ParamsChanged", logs: logs, sub: sub}, nil +} + +// WatchParamsChanged is a free log subscription operation binding the contract event 0xcccaeb9d161525e3f31950313467c2e9a945a55a1ff09658479fe753054fafe0. +// +// Solidity: event ParamsChanged(address token, address nft, address nftTracker, uint256 threshold, uint256 expiration, uint256 voted, uint256 nonce) +func (_UnchainedStaking *UnchainedStakingFilterer) WatchParamsChanged(opts *bind.WatchOpts, sink chan<- *UnchainedStakingParamsChanged) (event.Subscription, error) { + + logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "ParamsChanged") + 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(UnchainedStakingParamsChanged) + if err := _UnchainedStaking.contract.UnpackLog(event, "ParamsChanged", 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 +} + +// ParseParamsChanged is a log parse operation binding the contract event 0xcccaeb9d161525e3f31950313467c2e9a945a55a1ff09658479fe753054fafe0. +// +// Solidity: event ParamsChanged(address token, address nft, address nftTracker, uint256 threshold, uint256 expiration, uint256 voted, uint256 nonce) +func (_UnchainedStaking *UnchainedStakingFilterer) ParseParamsChanged(log types.Log) (*UnchainedStakingParamsChanged, error) { + event := new(UnchainedStakingParamsChanged) + if err := _UnchainedStaking.contract.UnpackLog(event, "ParamsChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UnchainedStakingSignerChangedIterator is returned from FilterSignerChanged and is used to iterate over the raw logs and unpacked data for SignerChanged events raised by the UnchainedStaking contract. +type UnchainedStakingSignerChangedIterator struct { + Event *UnchainedStakingSignerChanged // 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 *UnchainedStakingSignerChangedIterator) 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(UnchainedStakingSignerChanged) + 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(UnchainedStakingSignerChanged) + 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 *UnchainedStakingSignerChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingSignerChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingSignerChanged represents a SignerChanged event raised by the UnchainedStaking contract. +type UnchainedStakingSignerChanged struct { + Staker common.Address + Signer common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSignerChanged is a free log retrieval operation binding the contract event 0xeeb293e1f8f3a9db91ade748726387ed1352ca78f5430c5f06fe3d1e1ad50579. +// +// Solidity: event SignerChanged(address indexed staker, address indexed signer) +func (_UnchainedStaking *UnchainedStakingFilterer) FilterSignerChanged(opts *bind.FilterOpts, staker []common.Address, signer []common.Address) (*UnchainedStakingSignerChangedIterator, error) { + + var stakerRule []interface{} + for _, stakerItem := range staker { + stakerRule = append(stakerRule, stakerItem) + } + var signerRule []interface{} + for _, signerItem := range signer { + signerRule = append(signerRule, signerItem) + } + + logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "SignerChanged", stakerRule, signerRule) + if err != nil { + return nil, err + } + return &UnchainedStakingSignerChangedIterator{contract: _UnchainedStaking.contract, event: "SignerChanged", logs: logs, sub: sub}, nil +} + +// WatchSignerChanged is a free log subscription operation binding the contract event 0xeeb293e1f8f3a9db91ade748726387ed1352ca78f5430c5f06fe3d1e1ad50579. +// +// Solidity: event SignerChanged(address indexed staker, address indexed signer) +func (_UnchainedStaking *UnchainedStakingFilterer) WatchSignerChanged(opts *bind.WatchOpts, sink chan<- *UnchainedStakingSignerChanged, staker []common.Address, signer []common.Address) (event.Subscription, error) { + + var stakerRule []interface{} + for _, stakerItem := range staker { + stakerRule = append(stakerRule, stakerItem) + } + var signerRule []interface{} + for _, signerItem := range signer { + signerRule = append(signerRule, signerItem) + } + + logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "SignerChanged", stakerRule, signerRule) + 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(UnchainedStakingSignerChanged) + if err := _UnchainedStaking.contract.UnpackLog(event, "SignerChanged", 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 +} + +// ParseSignerChanged is a log parse operation binding the contract event 0xeeb293e1f8f3a9db91ade748726387ed1352ca78f5430c5f06fe3d1e1ad50579. +// +// Solidity: event SignerChanged(address indexed staker, address indexed signer) +func (_UnchainedStaking *UnchainedStakingFilterer) ParseSignerChanged(log types.Log) (*UnchainedStakingSignerChanged, error) { + event := new(UnchainedStakingSignerChanged) + if err := _UnchainedStaking.contract.UnpackLog(event, "SignerChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UnchainedStakingStakeIncreasedIterator is returned from FilterStakeIncreased and is used to iterate over the raw logs and unpacked data for StakeIncreased events raised by the UnchainedStaking contract. +type UnchainedStakingStakeIncreasedIterator struct { + Event *UnchainedStakingStakeIncreased // 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 *UnchainedStakingStakeIncreasedIterator) 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(UnchainedStakingStakeIncreased) + 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(UnchainedStakingStakeIncreased) + 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 *UnchainedStakingStakeIncreasedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingStakeIncreasedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingStakeIncreased represents a StakeIncreased event raised by the UnchainedStaking contract. +type UnchainedStakingStakeIncreased struct { + User common.Address + Amount *big.Int + NftIds []*big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterStakeIncreased is a free log retrieval operation binding the contract event 0x26e4d06799c60ba22ec168ee4a9314ed451cf9c78dbf6a5f7bfeaf3c84688f58. +// +// Solidity: event StakeIncreased(address indexed user, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) FilterStakeIncreased(opts *bind.FilterOpts, user []common.Address) (*UnchainedStakingStakeIncreasedIterator, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "StakeIncreased", userRule) + if err != nil { + return nil, err + } + return &UnchainedStakingStakeIncreasedIterator{contract: _UnchainedStaking.contract, event: "StakeIncreased", logs: logs, sub: sub}, nil +} + +// WatchStakeIncreased is a free log subscription operation binding the contract event 0x26e4d06799c60ba22ec168ee4a9314ed451cf9c78dbf6a5f7bfeaf3c84688f58. +// +// Solidity: event StakeIncreased(address indexed user, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) WatchStakeIncreased(opts *bind.WatchOpts, sink chan<- *UnchainedStakingStakeIncreased, user []common.Address) (event.Subscription, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "StakeIncreased", userRule) + 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(UnchainedStakingStakeIncreased) + if err := _UnchainedStaking.contract.UnpackLog(event, "StakeIncreased", 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 +} + +// ParseStakeIncreased is a log parse operation binding the contract event 0x26e4d06799c60ba22ec168ee4a9314ed451cf9c78dbf6a5f7bfeaf3c84688f58. +// +// Solidity: event StakeIncreased(address indexed user, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) ParseStakeIncreased(log types.Log) (*UnchainedStakingStakeIncreased, error) { + event := new(UnchainedStakingStakeIncreased) + if err := _UnchainedStaking.contract.UnpackLog(event, "StakeIncreased", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UnchainedStakingStakedIterator is returned from FilterStaked and is used to iterate over the raw logs and unpacked data for Staked events raised by the UnchainedStaking contract. +type UnchainedStakingStakedIterator struct { + Event *UnchainedStakingStaked // 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 *UnchainedStakingStakedIterator) 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(UnchainedStakingStaked) + 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(UnchainedStakingStaked) + 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 *UnchainedStakingStakedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingStakedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingStaked represents a Staked event raised by the UnchainedStaking contract. +type UnchainedStakingStaked struct { + User common.Address + Unlock *big.Int + Amount *big.Int + NftIds []*big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterStaked is a free log retrieval operation binding the contract event 0x5df5de9ccb680fe3d60088f6d4c3b6d535074c704699377046c743a5b276e171. +// +// Solidity: event Staked(address indexed user, uint256 unlock, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) FilterStaked(opts *bind.FilterOpts, user []common.Address) (*UnchainedStakingStakedIterator, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "Staked", userRule) + if err != nil { + return nil, err + } + return &UnchainedStakingStakedIterator{contract: _UnchainedStaking.contract, event: "Staked", logs: logs, sub: sub}, nil +} + +// WatchStaked is a free log subscription operation binding the contract event 0x5df5de9ccb680fe3d60088f6d4c3b6d535074c704699377046c743a5b276e171. +// +// Solidity: event Staked(address indexed user, uint256 unlock, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) WatchStaked(opts *bind.WatchOpts, sink chan<- *UnchainedStakingStaked, user []common.Address) (event.Subscription, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "Staked", userRule) + 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(UnchainedStakingStaked) + if err := _UnchainedStaking.contract.UnpackLog(event, "Staked", 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 +} + +// ParseStaked is a log parse operation binding the contract event 0x5df5de9ccb680fe3d60088f6d4c3b6d535074c704699377046c743a5b276e171. +// +// Solidity: event Staked(address indexed user, uint256 unlock, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) ParseStaked(log types.Log) (*UnchainedStakingStaked, error) { + event := new(UnchainedStakingStaked) + if err := _UnchainedStaking.contract.UnpackLog(event, "Staked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UnchainedStakingTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the UnchainedStaking contract. +type UnchainedStakingTransferIterator struct { + Event *UnchainedStakingTransfer // 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 *UnchainedStakingTransferIterator) 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(UnchainedStakingTransfer) + 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(UnchainedStakingTransfer) + 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 *UnchainedStakingTransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingTransfer represents a Transfer event raised by the UnchainedStaking contract. +type UnchainedStakingTransfer struct { + From common.Address + To common.Address + Amount *big.Int + NftIds []*big.Int + Nonces []*big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0x26a79d74e745222aa0f380aabeac7f0a270b037daf3b5fb1b1b66ff7f4c3144f. +// +// Solidity: event Transfer(address from, address to, uint256 amount, uint256[] nftIds, uint256[] nonces) +func (_UnchainedStaking *UnchainedStakingFilterer) FilterTransfer(opts *bind.FilterOpts) (*UnchainedStakingTransferIterator, error) { + + logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "Transfer") + if err != nil { + return nil, err + } + return &UnchainedStakingTransferIterator{contract: _UnchainedStaking.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0x26a79d74e745222aa0f380aabeac7f0a270b037daf3b5fb1b1b66ff7f4c3144f. +// +// Solidity: event Transfer(address from, address to, uint256 amount, uint256[] nftIds, uint256[] nonces) +func (_UnchainedStaking *UnchainedStakingFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *UnchainedStakingTransfer) (event.Subscription, error) { + + logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "Transfer") + 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(UnchainedStakingTransfer) + if err := _UnchainedStaking.contract.UnpackLog(event, "Transfer", 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 +} + +// ParseTransfer is a log parse operation binding the contract event 0x26a79d74e745222aa0f380aabeac7f0a270b037daf3b5fb1b1b66ff7f4c3144f. +// +// Solidity: event Transfer(address from, address to, uint256 amount, uint256[] nftIds, uint256[] nonces) +func (_UnchainedStaking *UnchainedStakingFilterer) ParseTransfer(log types.Log) (*UnchainedStakingTransfer, error) { + event := new(UnchainedStakingTransfer) + if err := _UnchainedStaking.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UnchainedStakingUnStakedIterator is returned from FilterUnStaked and is used to iterate over the raw logs and unpacked data for UnStaked events raised by the UnchainedStaking contract. +type UnchainedStakingUnStakedIterator struct { + Event *UnchainedStakingUnStaked // 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 *UnchainedStakingUnStakedIterator) 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(UnchainedStakingUnStaked) + 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(UnchainedStakingUnStaked) + 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 *UnchainedStakingUnStakedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UnchainedStakingUnStakedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UnchainedStakingUnStaked represents a UnStaked event raised by the UnchainedStaking contract. +type UnchainedStakingUnStaked struct { + User common.Address + Amount *big.Int + NftIds []*big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUnStaked is a free log retrieval operation binding the contract event 0xef4ce4a0205d268e0effbc76aaabb2ad2509ec58a2e9013645347d3c3cd9be42. +// +// Solidity: event UnStaked(address indexed user, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) FilterUnStaked(opts *bind.FilterOpts, user []common.Address) (*UnchainedStakingUnStakedIterator, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _UnchainedStaking.contract.FilterLogs(opts, "UnStaked", userRule) + if err != nil { + return nil, err + } + return &UnchainedStakingUnStakedIterator{contract: _UnchainedStaking.contract, event: "UnStaked", logs: logs, sub: sub}, nil +} + +// WatchUnStaked is a free log subscription operation binding the contract event 0xef4ce4a0205d268e0effbc76aaabb2ad2509ec58a2e9013645347d3c3cd9be42. +// +// Solidity: event UnStaked(address indexed user, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) WatchUnStaked(opts *bind.WatchOpts, sink chan<- *UnchainedStakingUnStaked, user []common.Address) (event.Subscription, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + + logs, sub, err := _UnchainedStaking.contract.WatchLogs(opts, "UnStaked", userRule) + 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(UnchainedStakingUnStaked) + if err := _UnchainedStaking.contract.UnpackLog(event, "UnStaked", 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 +} + +// ParseUnStaked is a log parse operation binding the contract event 0xef4ce4a0205d268e0effbc76aaabb2ad2509ec58a2e9013645347d3c3cd9be42. +// +// Solidity: event UnStaked(address indexed user, uint256 amount, uint256[] nftIds) +func (_UnchainedStaking *UnchainedStakingFilterer) ParseUnStaked(log types.Log) (*UnchainedStakingUnStaked, error) { + event := new(UnchainedStakingUnStaked) + if err := _UnchainedStaking.contract.UnpackLog(event, "UnStaked", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/internal/crypto/ethereum/contracts/UniV3.go b/internal/crypto/ethereum/contracts/UniV3.go new file mode 100644 index 00000000..087ab06e --- /dev/null +++ b/internal/crypto/ethereum/contracts/UniV3.go @@ -0,0 +1,251 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contracts + +import ( + "errors" + "math/big" + "strings" + + 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" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// UniV3MetaData contains all meta data concerning the UniV3 contract. +var UniV3MetaData = &bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"slot0\",\"constant\":true,\"stateMutability\":\"view\",\"payable\":false,\"inputs\":[],\"outputs\":[{\"type\":\"uint160\",\"name\":\"sqrtPriceX96\"},{\"type\":\"int24\",\"name\":\"tick\"},{\"type\":\"uint16\",\"name\":\"observationIndex\"},{\"type\":\"uint16\",\"name\":\"observationCardinality\"},{\"type\":\"uint16\",\"name\":\"observationCardinalityNext\"},{\"type\":\"uint8\",\"name\":\"feeProtocol\"},{\"type\":\"bool\",\"name\":\"unlocked\"}]}]", +} + +// UniV3ABI is the input ABI used to generate the binding from. +// Deprecated: Use UniV3MetaData.ABI instead. +var UniV3ABI = UniV3MetaData.ABI + +// UniV3 is an auto generated Go binding around an Ethereum contract. +type UniV3 struct { + UniV3Caller // Read-only binding to the contract + UniV3Transactor // Write-only binding to the contract + UniV3Filterer // Log filterer for contract events +} + +// UniV3Caller is an auto generated read-only Go binding around an Ethereum contract. +type UniV3Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UniV3Transactor is an auto generated write-only Go binding around an Ethereum contract. +type UniV3Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UniV3Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type UniV3Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UniV3Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type UniV3Session struct { + Contract *UniV3 // 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 +} + +// UniV3CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type UniV3CallerSession struct { + Contract *UniV3Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// UniV3TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type UniV3TransactorSession struct { + Contract *UniV3Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// UniV3Raw is an auto generated low-level Go binding around an Ethereum contract. +type UniV3Raw struct { + Contract *UniV3 // Generic contract binding to access the raw methods on +} + +// UniV3CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type UniV3CallerRaw struct { + Contract *UniV3Caller // Generic read-only contract binding to access the raw methods on +} + +// UniV3TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type UniV3TransactorRaw struct { + Contract *UniV3Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewUniV3 creates a new instance of UniV3, bound to a specific deployed contract. +func NewUniV3(address common.Address, backend bind.ContractBackend) (*UniV3, error) { + contract, err := bindUniV3(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &UniV3{UniV3Caller: UniV3Caller{contract: contract}, UniV3Transactor: UniV3Transactor{contract: contract}, UniV3Filterer: UniV3Filterer{contract: contract}}, nil +} + +// NewUniV3Caller creates a new read-only instance of UniV3, bound to a specific deployed contract. +func NewUniV3Caller(address common.Address, caller bind.ContractCaller) (*UniV3Caller, error) { + contract, err := bindUniV3(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &UniV3Caller{contract: contract}, nil +} + +// NewUniV3Transactor creates a new write-only instance of UniV3, bound to a specific deployed contract. +func NewUniV3Transactor(address common.Address, transactor bind.ContractTransactor) (*UniV3Transactor, error) { + contract, err := bindUniV3(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &UniV3Transactor{contract: contract}, nil +} + +// NewUniV3Filterer creates a new log filterer instance of UniV3, bound to a specific deployed contract. +func NewUniV3Filterer(address common.Address, filterer bind.ContractFilterer) (*UniV3Filterer, error) { + contract, err := bindUniV3(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &UniV3Filterer{contract: contract}, nil +} + +// bindUniV3 binds a generic wrapper to an already deployed contract. +func bindUniV3(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := UniV3MetaData.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 (_UniV3 *UniV3Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _UniV3.Contract.UniV3Caller.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 (_UniV3 *UniV3Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _UniV3.Contract.UniV3Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_UniV3 *UniV3Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _UniV3.Contract.UniV3Transactor.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 (_UniV3 *UniV3CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _UniV3.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 (_UniV3 *UniV3TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _UniV3.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_UniV3 *UniV3TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _UniV3.Contract.contract.Transact(opts, method, params...) +} + +// Slot0 is a free data retrieval call binding the contract method 0x3850c7bd. +// +// Solidity: function slot0() view returns(uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked) +func (_UniV3 *UniV3Caller) Slot0(opts *bind.CallOpts) (struct { + SqrtPriceX96 *big.Int + Tick *big.Int + ObservationIndex uint16 + ObservationCardinality uint16 + ObservationCardinalityNext uint16 + FeeProtocol uint8 + Unlocked bool +}, error) { + var out []interface{} + err := _UniV3.contract.Call(opts, &out, "slot0") + + outstruct := new(struct { + SqrtPriceX96 *big.Int + Tick *big.Int + ObservationIndex uint16 + ObservationCardinality uint16 + ObservationCardinalityNext uint16 + FeeProtocol uint8 + Unlocked bool + }) + if err != nil { + return *outstruct, err + } + + outstruct.SqrtPriceX96 = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Tick = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.ObservationIndex = *abi.ConvertType(out[2], new(uint16)).(*uint16) + outstruct.ObservationCardinality = *abi.ConvertType(out[3], new(uint16)).(*uint16) + outstruct.ObservationCardinalityNext = *abi.ConvertType(out[4], new(uint16)).(*uint16) + outstruct.FeeProtocol = *abi.ConvertType(out[5], new(uint8)).(*uint8) + outstruct.Unlocked = *abi.ConvertType(out[6], new(bool)).(*bool) + + return *outstruct, err + +} + +// Slot0 is a free data retrieval call binding the contract method 0x3850c7bd. +// +// Solidity: function slot0() view returns(uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked) +func (_UniV3 *UniV3Session) Slot0() (struct { + SqrtPriceX96 *big.Int + Tick *big.Int + ObservationIndex uint16 + ObservationCardinality uint16 + ObservationCardinalityNext uint16 + FeeProtocol uint8 + Unlocked bool +}, error) { + return _UniV3.Contract.Slot0(&_UniV3.CallOpts) +} + +// Slot0 is a free data retrieval call binding the contract method 0x3850c7bd. +// +// Solidity: function slot0() view returns(uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked) +func (_UniV3 *UniV3CallerSession) Slot0() (struct { + SqrtPriceX96 *big.Int + Tick *big.Int + ObservationIndex uint16 + ObservationCardinality uint16 + ObservationCardinalityNext uint16 + FeeProtocol uint8 + Unlocked bool +}, error) { + return _UniV3.Contract.Slot0(&_UniV3.CallOpts) +} diff --git a/internal/crypto/ethereum/identity.go b/internal/crypto/ethereum/identity.go new file mode 100644 index 00000000..84a9c56a --- /dev/null +++ b/internal/crypto/ethereum/identity.go @@ -0,0 +1,89 @@ +package ethereum + +import ( + "crypto/ecdsa" + + "github.com/TimeleapLabs/unchained/internal/config" + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" +) + +// Signer represents an Ethereum identity. +type Signer struct { + PublicKey *ecdsa.PublicKey + PrivateKey *ecdsa.PrivateKey + Address string +} + +func (s *Signer) Verify(_ []byte, _ []byte, _ []byte) (bool, error) { + // TODO implement me + panic("implement me") +} + +// WriteConfigs writes the secret key, public key and address to the global config object. +func (s *Signer) WriteConfigs() { + privateKeyBytes := crypto.FromECDSA(s.PrivateKey) + config.App.Secret.EvmPrivateKey = hexutil.Encode(privateKeyBytes)[2:] + config.App.Secret.EvmAddress = s.Address +} + +func (s *Signer) Sign(data []byte) ([]byte, error) { + signature, err := crypto.Sign(data, s.PrivateKey) + if err != nil { + return nil, err + } + + if signature[64] < 27 { + signature[64] += 27 + } + + return signature, nil +} + +// NewIdentity creates a new Ethereum identity. +func NewIdentity() *Signer { + var privateKey *ecdsa.PrivateKey + var err error + + if config.App.Secret.EvmPrivateKey == "" && !config.App.System.AllowGenerateSecrets { + panic("EVM private key is not provided and secrets generation is not allowed") + } + + if config.App.Secret.EvmPrivateKey != "" { + privateKey, err = crypto.HexToECDSA(config.App.Secret.EvmPrivateKey) + if err != nil { + utils.Logger. + With("Error", err). + Error("Can't decode EVM private key") + + panic(err) + } + } else { + privateKey, err = crypto.GenerateKey() + if err != nil { + utils.Logger. + With("Error", err). + Error("Can't generate EVM private key") + + panic(err) + } + } + + publicKeyECDSA, ok := privateKey.Public().(*ecdsa.PublicKey) + if !ok { + panic("Can't assert type: publicKey is not of type *ecdsa.PublicKey") + } + + s := &Signer{ + PublicKey: publicKeyECDSA, + PrivateKey: privateKey, + Address: crypto.PubkeyToAddress(*publicKeyECDSA).Hex(), + } + + utils.Logger. + With("Address", s.Address). + Info("EVM identity initialized") + + return s +} diff --git a/internal/crypto/frost/identity.go b/internal/crypto/frost/identity.go index 831a92a8..df8367e4 100644 --- a/internal/crypto/frost/identity.go +++ b/internal/crypto/frost/identity.go @@ -2,7 +2,6 @@ package frost import ( "errors" - "github.com/bytemare/crypto" "github.com/bytemare/frost" "github.com/bytemare/frost/dkg" @@ -21,13 +20,8 @@ type DistributedSigner struct { } // Update function will update the identity key about other parties. -func (s *DistributedSigner) Update(msg []byte) ([][]byte, error) { - round1Data, err := s.DecodeRoundOneMessage(msg) - if err != nil { - return nil, err - } - - s.accumulatedMessages = append(s.accumulatedMessages, round1Data) +func (s *DistributedSigner) Update(msg *dkg.Round1Data) ([]*dkg.Round2Data, error) { + s.accumulatedMessages = append(s.accumulatedMessages, msg) if len(s.accumulatedMessages) != s.signerCount { return nil, nil @@ -42,16 +36,10 @@ func (s *DistributedSigner) Update(msg []byte) ([][]byte, error) { return nil, errors.New("number of accept messages is not correct") } - return EncodeRoundTwoMessages(round2Data), nil + return round2Data, nil } -// Finalize function will confirm the identity key about other parties updates. -func (s *DistributedSigner) Finalize(msgByte []byte) error { - msg, err := s.DecodeRoundTwoMessage(msgByte) - if err != nil { - return err - } - +func (s *DistributedSigner) Finalize(msg *dkg.Round2Data) error { if msg.ReceiverIdentifier.Equal(s.currentParticipant.Identifier) == 0 { return nil } @@ -62,6 +50,8 @@ func (s *DistributedSigner) Finalize(msgByte []byte) error { return nil } + // This will, for each participant, return their secret key (which is a share of the global secret signing key), + // the corresponding verification key, and the global public key. participantsSecretKey, _, groupPublicKeyGeneratedInDKG, err := s.currentParticipant.Finalize( s.accumulatedMessages, s.ackMessages, @@ -78,7 +68,7 @@ func (s *DistributedSigner) Finalize(msgByte []byte) error { } // NewIdentity creates a new Frost identity. -func NewIdentity(id int, signerCount int, minSigningCount int) ([]byte, *DistributedSigner) { +func NewIdentity(ID int, signerCount int, minSigningCount int) (*dkg.Round1Data, *DistributedSigner) { signer := DistributedSigner{ accumulatedMessages: make([]*dkg.Round1Data, 0, signerCount), config: frost.Ristretto255.Configuration(), @@ -86,7 +76,7 @@ func NewIdentity(id int, signerCount int, minSigningCount int) ([]byte, *Distrib minSigningCount: minSigningCount, } - signer.ID = signer.config.IDFromInt(id) + signer.ID = signer.config.IDFromInt(ID) signer.currentParticipant = dkg.NewParticipant( signer.config.Ciphersuite, signer.ID, @@ -99,5 +89,7 @@ func NewIdentity(id int, signerCount int, minSigningCount int) ([]byte, *Distrib panic("this is just a test, and it failed") } - return EncodeRoundOneMessage(round1Data), &signer + //signer.accumulatedMessages = append(signer.accumulatedMessages, round1Data) + + return round1Data, &signer } diff --git a/internal/crypto/identity.go b/internal/crypto/identity.go new file mode 100644 index 00000000..971a853c --- /dev/null +++ b/internal/crypto/identity.go @@ -0,0 +1,96 @@ +package crypto + +import ( + "encoding/hex" + + "github.com/TimeleapLabs/unchained/internal/config" + "github.com/TimeleapLabs/unchained/internal/crypto/bls" + "github.com/TimeleapLabs/unchained/internal/crypto/ethereum" + "github.com/TimeleapLabs/unchained/internal/crypto/tss" + "github.com/TimeleapLabs/unchained/internal/model" +) + +// Signer represents a Signing method. +type Signer interface { + Sign(data []byte) ([]byte, error) + Verify(signature []byte, hashedMessage []byte, publicKey []byte) (bool, error) + WriteConfigs() +} + +// MachineIdentity holds machine identity and provide and manage keys. +type MachineIdentity struct { + Bls Signer + Eth Signer + Tss *tss.DistributedSigner +} + +// Identity is a global variable that holds machine identity. +var Identity = &MachineIdentity{} + +// Option represents a function that can add new identity to machine identity. +type Option func(identity *MachineIdentity) error + +// InitMachineIdentity loads all provided identities and save them to secret file. +func InitMachineIdentity(options ...Option) { + for _, option := range options { + err := option(Identity) + if err != nil { + panic(err) + } + } + + if config.App.System.AllowGenerateSecrets { + err := config.App.Secret.Save() + if err != nil { + panic(err) + } + } +} + +// ExportEvmSigner returns EVM signer from machine identity. +func (i *MachineIdentity) ExportEvmSigner() *model.Signer { + blsPublicKey, err := hex.DecodeString(config.App.Secret.PublicKey) + if err != nil { + panic(err) + } + + return &model.Signer{ + Name: config.App.System.Name, + EvmAddress: config.App.Secret.EvmAddress, + PublicKey: [96]byte(blsPublicKey), + ShortPublicKey: config.App.Secret.ShortPublicKey, + } +} + +// WithEvmSigner initialize and will add Evm identity to machine identity. +func WithEvmSigner() func(machineIdentity *MachineIdentity) error { + return func(machineIdentity *MachineIdentity) error { + machineIdentity.Eth = ethereum.NewIdentity() + machineIdentity.Eth.WriteConfigs() + + return nil + } +} + +// WithTssSigner initialize and will add Tss identity to machine identity. +// func WithTssSigner(signers []string, minThreshold int) func(machineIdentity *MachineIdentity) error { +// return func(machineIdentity *MachineIdentity) error { +// machineIdentity.Tss = tss.NewIdentity( +// signers, +// minThreshold, +// ) +// //machineIdentity.Tss.WriteConfigs() +// +// return nil +// } +//} + +// WithBlsIdentity initialize and will add Bls identity to machine identity. +func WithBlsIdentity() func(machineIdentity *MachineIdentity) error { + return func(machineIdentity *MachineIdentity) error { + machineIdentity.Bls = bls.NewIdentity() + machineIdentity.Bls.WriteConfigs() + + return nil + } +} diff --git a/internal/crypto/identity_test.go b/internal/crypto/identity_test.go new file mode 100644 index 00000000..b0fa65b6 --- /dev/null +++ b/internal/crypto/identity_test.go @@ -0,0 +1,32 @@ +package crypto + +import ( + "testing" + + "github.com/TimeleapLabs/unchained/internal/config" + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/stretchr/testify/assert" +) + +const SamplePrivateKey = "3b885a8a8f043724abfa865eccd38f536887d9ea1c08a742720e810f38a86872" + +func TestEvmSignerWithoutGeneratePrivateKey(t *testing.T) { + utils.SetupLogger("info") + config.App.Secret.EvmPrivateKey = SamplePrivateKey + + InitMachineIdentity( + WithEvmSigner(), + ) + + assert.Equal(t, config.App.Secret.EvmPrivateKey, SamplePrivateKey) +} + +func TestEvmSignerWithGeneratePrivateKey(t *testing.T) { + utils.SetupLogger("info") + config.App.Secret.EvmPrivateKey = "" + + InitMachineIdentity( + WithEvmSigner(), + ) + assert.NotEmpty(t, config.App.Secret.EvmPrivateKey) +} From bbfcdba221024b9313b7ca7ea9261fe0b4863b57 Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Wed, 5 Jun 2024 00:43:23 +0330 Subject: [PATCH 22/29] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20=20refactor(handler)?= =?UTF-8?q?:=20seprate=20handler=20DI=20and=20add=20redis=20in=20conn=20st?= =?UTF-8?q?ore=20>>>=20=E2=8F=B0=204h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.sum | 38 ++++ internal/app/broker.go | 13 +- internal/app/worker.go | 5 +- internal/config/model.go | 6 + internal/consts/channels.go | 2 +- internal/consts/opcodes.go | 2 +- internal/crypto/frost/identity.go | 2 +- internal/crypto/identity_test.go | 1 + internal/crypto/multisig/convert.go | 21 +++ internal/crypto/multisig/identity.go | 61 +++++++ internal/crypto/multisig/identity_test.go | 114 ++++++++++++ internal/crypto/multisig/signer.go | 65 +++++++ internal/scheduler/frost.go | 2 +- internal/service/frost/frost.go | 2 +- internal/service/frost/sync.go | 36 ++-- internal/transport/client/client.go | 3 +- internal/transport/client/handler/frost.go | 9 +- internal/transport/client/handler/handler.go | 2 +- internal/transport/client/handler/worker.go | 9 +- internal/transport/database/database.go | 7 + internal/transport/database/redis/redis.go | 50 ++++++ .../server/websocket/handler/correctness.go | 4 +- .../server/websocket/handler/event.go | 4 +- .../server/websocket/handler/handler.go | 18 ++ .../server/websocket/handler/hello.go | 15 +- .../server/websocket/handler/kosk.go | 5 +- .../server/websocket/handler/price.go | 4 +- .../server/websocket/middleware/signature.go | 14 +- .../server/websocket/store/native.go | 51 ++++++ .../transport/server/websocket/store/redis.go | 40 +++++ .../transport/server/websocket/store/store.go | 9 +- .../transport/server/websocket/websocket.go | 165 ++++++++++-------- 32 files changed, 641 insertions(+), 138 deletions(-) create mode 100644 internal/crypto/multisig/convert.go create mode 100644 internal/crypto/multisig/identity.go create mode 100644 internal/crypto/multisig/identity_test.go create mode 100644 internal/crypto/multisig/signer.go create mode 100644 internal/transport/database/redis/redis.go create mode 100644 internal/transport/server/websocket/handler/handler.go create mode 100644 internal/transport/server/websocket/store/native.go create mode 100644 internal/transport/server/websocket/store/redis.go diff --git a/go.sum b/go.sum index e9e02dd2..509c1ac8 100644 --- a/go.sum +++ b/go.sum @@ -93,6 +93,10 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= @@ -154,6 +158,7 @@ github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5U github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -162,6 +167,8 @@ github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJ github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cronokirby/safenum v0.29.0 h1:kf1/8vvN/yQjrZU3tR/vDb5OdIQp2uJ6WvPVbU61J+E= +github.com/cronokirby/safenum v0.29.0/go.mod h1:AWp82xwEqKcnrpJPXPa1m0gF/OY8dzgL17ubUBnVygA= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -169,8 +176,12 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/chaincfg/chainhash v1.0.2/go.mod h1:BpbrGgrPTr3YJYRN3Bm+D9NuaFd+zGyNeIKgrhCXK60= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0 h1:sgNeV1VRMDzs6rzyPpxyM0jp317hnwiq58Filgag2xw= +github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0/go.mod h1:J70FGZSbzsjecRTiTzER+3f1KZLNaXkuv+yeFTKoxM8= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= @@ -181,6 +192,8 @@ github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkz github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -205,6 +218,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fxamacker/cbor/v2 v2.3.0 h1:aM45YGMctNakddNNAezPxDUpv38j44Abh+hifNuqXik= +github.com/fxamacker/cbor/v2 v2.3.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= @@ -238,6 +253,7 @@ github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3a github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= @@ -411,6 +427,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -528,6 +545,8 @@ github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/puzpuzpuz/xsync/v3 v3.1.0 h1:EewKT7/LNac5SLiEblJeUu8z5eERHrmRLnMQL2d7qX4= github.com/puzpuzpuz/xsync/v3 v3.1.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= +github.com/redis/go-redis/v9 v9.5.2 h1:L0L3fcSNReTRGyZ6AqAEN0K56wYeYAwapBIhkvh0f3E= +github.com/redis/go-redis/v9 v9.5.2/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= @@ -537,6 +556,8 @@ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZV github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.23.0/go.mod h1:6c7hFfxPOy7TacJc4Fcdi24/J0NKYGzjG8FWRI916Qo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -586,6 +607,8 @@ github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbe github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/taurusgroup/multi-party-sig v0.6.0-alpha-2021-09-21 h1:MD4GMowDgq+P6K1iWilm+gidphDP3/+chAd11PK3pLU= +github.com/taurusgroup/multi-party-sig v0.6.0-alpha-2021-09-21/go.mod h1:Rc64j33LGdGG1XPEOCU3v2yPkjGbxJgBRv798BZ+rSk= github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4= github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0= github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4= @@ -607,6 +630,8 @@ github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IU github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= @@ -625,6 +650,12 @@ github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY= +github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/blake3 v0.2.0 h1:1SGx3IvKWFUU/xl+/7kjdcjjMcvVSm+3dMo/N42afC8= +github.com/zeebo/blake3 v0.2.0/go.mod h1:G9pM4qQwjRzF1/v7+vabMj/c5mWpGZ2Wzo3Eb4z0pb4= +github.com/zeebo/pcg v1.0.0 h1:dt+dx+HvX8g7Un32rY9XWoYnd0NmKmrIzpHF7qiTDj0= +github.com/zeebo/pcg v1.0.0/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -644,6 +675,7 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -716,6 +748,7 @@ golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= @@ -781,10 +814,14 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201014080544-cc95f250f6bc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -853,6 +890,7 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/app/broker.go b/internal/app/broker.go index 214bccae..6d09e510 100644 --- a/internal/app/broker.go +++ b/internal/app/broker.go @@ -5,8 +5,10 @@ import ( "github.com/TimeleapLabs/unchained/internal/crypto" "github.com/TimeleapLabs/unchained/internal/crypto/ethereum" "github.com/TimeleapLabs/unchained/internal/service/pos" + "github.com/TimeleapLabs/unchained/internal/transport/database/redis" "github.com/TimeleapLabs/unchained/internal/transport/server" "github.com/TimeleapLabs/unchained/internal/transport/server/websocket" + "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/store" "github.com/TimeleapLabs/unchained/internal/utils" ) @@ -26,15 +28,12 @@ func Broker() { ethRPC := ethereum.New() pos.New(ethRPC) - // frostService := frost.New() + redisIns := redis.New() - // scheduler := scheduler.New( - // scheduler.WithFrostEvents(frostService), - //) + nativeSignerRepo := store.New() + redisSignerRepo := store.NewRedisStore(redisIns, nativeSignerRepo) server.New( - websocket.WithWebsocket(), + websocket.WithWebsocket(redisSignerRepo), ) - - // scheduler.Start() } diff --git a/internal/app/worker.go b/internal/app/worker.go index d89cc579..2a286ea6 100644 --- a/internal/app/worker.go +++ b/internal/app/worker.go @@ -8,6 +8,7 @@ import ( "github.com/TimeleapLabs/unchained/internal/repository/postgres" "github.com/TimeleapLabs/unchained/internal/scheduler" evmlogService "github.com/TimeleapLabs/unchained/internal/service/evmlog" + "github.com/TimeleapLabs/unchained/internal/service/frost" "github.com/TimeleapLabs/unchained/internal/service/pos" uniswapService "github.com/TimeleapLabs/unchained/internal/service/uniswap" "github.com/TimeleapLabs/unchained/internal/transport/client" @@ -39,15 +40,17 @@ func Worker() { badger := evmlogService.NewBadger(config.App.System.ContextPath) evmLogService := evmlogService.New(ethRPC, pos, eventLogRepo, signerRepo, badger) uniswapService := uniswapService.New(ethRPC, pos, signerRepo, assetPrice) + frostService := frost.New() scheduler := scheduler.New( scheduler.WithEthLogs(evmLogService), scheduler.WithUniswapEvents(uniswapService), + scheduler.WithFrostEvents(frostService), ) conn.Start() - handler := handler.NewWorkerHandler() + handler := handler.NewWorkerHandler(frostService) client.NewRPC(handler) scheduler.Start() diff --git a/internal/config/model.go b/internal/config/model.go index 2a840806..69da9514 100644 --- a/internal/config/model.go +++ b/internal/config/model.go @@ -93,6 +93,11 @@ type Postgres struct { URL string `env:"DATABASE_URL" yaml:"url"` } +// Redis struct holds all configs to connect to a redis instance. +type Redis struct { + Dsn string `env:"REDIS_DSN" yaml:"dsn"` +} + // Secret struct hold the secret keys of the application and loaded from secret.yaml. type Secret struct { Address string `env:"ADDRESS" yaml:"address"` @@ -110,6 +115,7 @@ type Config struct { Network Network `yaml:"network"` RPC []RPC `yaml:"rpc"` Postgres Postgres `yaml:"postgres"` + Redis Redis `yaml:"redis"` ProofOfStake ProofOfStake `yaml:"pos"` Plugins Plugins `yaml:"plugins"` Secret Secret `yaml:"secret"` diff --git a/internal/consts/channels.go b/internal/consts/channels.go index 616a8650..d68768e6 100644 --- a/internal/consts/channels.go +++ b/internal/consts/channels.go @@ -7,5 +7,5 @@ const ( ChannelPriceReport Channels = "unchained:price_report" ChannelEventLog Channels = "unchained:event_log" ChannelCorrectnessReport Channels = "unchained:correctness_report" - ChannelFrostSignerList Channels = "unchained:frost_signer_list" + ChannelFrostSigner Channels = "unchained:frost_signer" ) diff --git a/internal/consts/opcodes.go b/internal/consts/opcodes.go index 31b60db5..6605b8c1 100644 --- a/internal/consts/opcodes.go +++ b/internal/consts/opcodes.go @@ -24,5 +24,5 @@ const ( OpCodeCorrectnessReport OpCode = 10 OpCodeCorrectnessReportBroadcast OpCode = 11 - OpCodeSendSignerList OpCode = 12 + OpCodeAskIfFrostSigner OpCode = 12 ) diff --git a/internal/crypto/frost/identity.go b/internal/crypto/frost/identity.go index df8367e4..9502802e 100644 --- a/internal/crypto/frost/identity.go +++ b/internal/crypto/frost/identity.go @@ -86,7 +86,7 @@ func NewIdentity(ID int, signerCount int, minSigningCount int) (*dkg.Round1Data, round1Data := signer.currentParticipant.Init() if round1Data.SenderIdentifier.Equal(signer.ID) != 1 { - panic("this is just a test, and it failed") + panic("sender identifier is not correct") } //signer.accumulatedMessages = append(signer.accumulatedMessages, round1Data) diff --git a/internal/crypto/identity_test.go b/internal/crypto/identity_test.go index b0fa65b6..75e9027f 100644 --- a/internal/crypto/identity_test.go +++ b/internal/crypto/identity_test.go @@ -28,5 +28,6 @@ func TestEvmSignerWithGeneratePrivateKey(t *testing.T) { InitMachineIdentity( WithEvmSigner(), ) + assert.NotEmpty(t, config.App.Secret.EvmPrivateKey) } diff --git a/internal/crypto/multisig/convert.go b/internal/crypto/multisig/convert.go new file mode 100644 index 00000000..9276842b --- /dev/null +++ b/internal/crypto/multisig/convert.go @@ -0,0 +1,21 @@ +package multisig + +import ( + "github.com/taurusgroup/multi-party-sig/pkg/party" + "golang.org/x/crypto/sha3" +) + +func NewSignersFromStrings(signers []string) []party.ID { + participantIds := []party.ID{} + for _, signer := range signers { + participantIds = append(participantIds, party.ID(signer)) + } + + return participantIds +} + +func Keccak256(data []byte) []byte { + hash := sha3.NewLegacyKeccak256() + hash.Write(data) + return hash.Sum(nil) +} diff --git a/internal/crypto/multisig/identity.go b/internal/crypto/multisig/identity.go new file mode 100644 index 00000000..87869f7e --- /dev/null +++ b/internal/crypto/multisig/identity.go @@ -0,0 +1,61 @@ +package multisig + +import ( + "github.com/taurusgroup/multi-party-sig/pkg/party" + "github.com/taurusgroup/multi-party-sig/pkg/protocol" + "github.com/taurusgroup/multi-party-sig/protocols/frost" +) + +// DistributedSigner represents a MultiSig identity. +type DistributedSigner struct { + minSigningCount int + + ID party.ID + sessionID string + Signers []party.ID + ackHandler *protocol.MultiHandler + Config *frost.TaprootConfig +} + +// Confirm function will set other parties confirms. +func (d *DistributedSigner) Confirm(msg *protocol.Message) (bool, error) { + // msg := &protocol.Message{} + // err := msg.UnmarshalBinary(msgByte) + // if err != nil { + // utils.Logger.With("err", err).Error("cant unmarshal message") + // return consts.ErrCantDecode + //} + + d.ackHandler.Accept(msg) + + result, err := d.ackHandler.Result() + if err != nil { + if err.Error() == "protocol: not finished" { + return false, nil + } + + return false, err + } + + d.Config = result.(*frost.TaprootConfig) + + return true, nil +} + +// NewIdentity creates a new MultiSig identity. +func NewIdentity(sessionID, id string, signers []string, minSigningCount int) (*DistributedSigner, <-chan *protocol.Message) { + signersIDs := NewSignersFromStrings(signers) + + startSession := frost.KeygenTaproot(party.ID(id), signersIDs, minSigningCount) + handler, err := protocol.NewMultiHandler(startSession, []byte(sessionID)) + if err != nil { + panic("Cant create multi-sig identity: " + err.Error()) + } + + return &DistributedSigner{ + sessionID: sessionID, + Signers: signersIDs, + minSigningCount: minSigningCount, + ackHandler: handler, + }, handler.Listen() +} diff --git a/internal/crypto/multisig/identity_test.go b/internal/crypto/multisig/identity_test.go new file mode 100644 index 00000000..c7138def --- /dev/null +++ b/internal/crypto/multisig/identity_test.go @@ -0,0 +1,114 @@ +package multisig + +import ( + "fmt" + "sync" + "testing" + + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + "github.com/taurusgroup/multi-party-sig/pkg/protocol" +) + +const ( + numOfSigners = 10 + minNumOfSigners = 6 +) + +var ( + sessionID = "sessionID" + testData = []byte("HELLO hello") +) + +type MultiSigIdentityTestSuite struct { + suite.Suite + parties []*DistributedSigner +} + +func (s *MultiSigIdentityTestSuite) SetupTest() { + utils.SetupLogger("info") + + signersIDs := []string{} + for i := 0; i < numOfSigners; i++ { + signersIDs = append(signersIDs, fmt.Sprintf("signer-%d", i)) + } + + channels := []<-chan *protocol.Message{} + for i := 0; i < numOfSigners; i++ { + party, msgCh := NewIdentity(sessionID, fmt.Sprintf("signer-%d", i), signersIDs, minNumOfSigners) + s.parties = append(s.parties, party) + channels = append(channels, msgCh) + } + + wg := sync.WaitGroup{} + for _, channel := range channels { + wg.Add(1) + go func() { + for msg := range channel { + if msg.Broadcast { + for _, p := range s.parties { + isReady, err := p.Confirm(msg) + assert.NoError(s.T(), err) + if isReady { + s.T().Log("Confirmed!") + wg.Done() + } + } + } else { + for _, p := range s.parties { + if msg.IsFor(p.ID) { + isReady, err := p.Confirm(msg) + assert.NoError(s.T(), err) + if isReady { + s.T().Log("Confirmed!") + wg.Done() + } + } + } + } + } + }() + } + + wg.Wait() +} + +func (s *MultiSigIdentityTestSuite) TestSign() { + // signers := []*MessageSigner{} + + // for _, party := range s.parties { + // signer, msgCh, err := party.NewSigner(testData) + // assert.NoError(s.T(), err) + // + // signers = append(signers, signer) + // + // go func() { + // for msg := range msgCh { + // if msg.Broadcast { + // for _, v := range s.parties { + // err = v.Confirm(msg) + // assert.NoError(s.T(), err) + // if err == nil { + // s.T().Log("Confirmed!") + // } + // } + // } else { + // for _, v := range s.parties { + // if msg.IsFor(v.ID) { + // err = v.Confirm(msg) + // assert.NoError(s.T(), err) + // if err == nil { + // s.T().Log("Confirmed!") + // } + // } + // } + // } + // } + // }() + //} +} + +func TestMultiSigIdentitySuite(t *testing.T) { + suite.Run(t, new(MultiSigIdentityTestSuite)) +} diff --git a/internal/crypto/multisig/signer.go b/internal/crypto/multisig/signer.go new file mode 100644 index 00000000..49ab325e --- /dev/null +++ b/internal/crypto/multisig/signer.go @@ -0,0 +1,65 @@ +package multisig + +import ( + "github.com/TimeleapLabs/unchained/internal/consts" + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/taurusgroup/multi-party-sig/pkg/protocol" + "github.com/taurusgroup/multi-party-sig/protocols/frost" +) + +// MessageSigner represents state of signing of a message. +type MessageSigner struct { + ackHandler *protocol.MultiHandler +} + +// Confirm function will set other parties confirms. +func (s *MessageSigner) Confirm(msgByte []byte) error { + msg := &protocol.Message{} + err := msg.UnmarshalBinary(msgByte) + if err != nil { + utils.Logger.With("err", err).Error("cant unmarshal message") + return consts.ErrCantDecode + } + + s.ackHandler.Accept(msg) + + return nil +} + +func (d *DistributedSigner) NewSigner(data []byte) (*MessageSigner, <-chan *protocol.Message, error) { + if d.Config == nil { + return nil, nil, consts.ErrSignerIsNotReady + } + + dataKeccak256 := Keccak256(data) + + startSession := frost.SignTaproot(d.Config, d.Signers, dataKeccak256) + handler, err := protocol.NewMultiHandler(startSession, []byte(d.sessionID)) + if err != nil { + panic(err) + } + + return &MessageSigner{ + ackHandler: handler, + }, handler.Listen(), nil +} + +func decodeMessages(in <-chan *protocol.Message) <-chan []byte { + out := make(chan []byte) + + go func() { + for msg := range in { + msgByte, err := msg.MarshalBinary() + if err != nil { + utils.Logger.With("err", err).Error("cant marshal message") + continue + } + + out <- msgByte + } + + close(out) + }() + + return out +} diff --git a/internal/scheduler/frost.go b/internal/scheduler/frost.go index 2b41774f..9065a0d5 100644 --- a/internal/scheduler/frost.go +++ b/internal/scheduler/frost.go @@ -11,7 +11,7 @@ type FrostSync struct { // Run will trigger by the scheduler and process the Frost sync. func (e *FrostSync) Run() { - err := e.frostService.PushSigners() + err := e.frostService.SyncFrost() if err != nil { panic(err) } diff --git a/internal/service/frost/frost.go b/internal/service/frost/frost.go index 560d43eb..b18716b7 100644 --- a/internal/service/frost/frost.go +++ b/internal/service/frost/frost.go @@ -1,7 +1,7 @@ package frost type Service interface { - PushSigners() error + InitSigner() error } type service struct { diff --git a/internal/service/frost/sync.go b/internal/service/frost/sync.go index 6248b88b..129414c6 100644 --- a/internal/service/frost/sync.go +++ b/internal/service/frost/sync.go @@ -1,32 +1,22 @@ package frost import ( - "encoding/json" - - "github.com/TimeleapLabs/unchained/internal/transport/server/pubsub" - - "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/model" - "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/store" - "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/gorilla/websocket" ) -// PushSigners starts calculating of Frost signers by sending signers list to the Broker. -func (s *service) PushSigners() error { - signers := []model.Signer{} - store.Signers.Range(func(_ *websocket.Conn, value model.Signer) bool { - signers = append(signers, value) - return true - }) - - signersBytes, err := json.Marshal(signers) - if err != nil { - utils.Logger.With("Error", err).Error("Cant marshal signers list") - return consts.ErrInternalError - } - - pubsub.Publish(consts.ChannelFrostSignerList, consts.OpCodeSendSignerList, signersBytes) +// SyncFrost starts calculating of Frost signers by sending signers list to the Broker. +func (s *service) SyncFrost() error { + // signers := []model.Signer{} + // store.Signers.Range(func(_ *websocket.Conn, value model.Signer) bool { + // signers = append(signers, value) + // return true + // }) + // + // signersBytes, err := json.Marshal(signers) + //if err != nil { + // utils.Logger.With("Error", err).Error("Cant marshal signers list") + // return consts.ErrInternalError + //} return nil } diff --git a/internal/transport/client/client.go b/internal/transport/client/client.go index 1c0a4b2c..8f440e98 100644 --- a/internal/transport/client/client.go +++ b/internal/transport/client/client.go @@ -35,6 +35,7 @@ func NewRPC(handler handler.Handler) { case consts.OpCodeKoskChallenge: challenge := handler.Challenge(payload[1:]) conn.Send(consts.OpCodeKoskResult, challenge) + case consts.OpCodePriceReportBroadcast: handler.PriceReport(ctx, payload[1:]) @@ -44,8 +45,6 @@ func NewRPC(handler handler.Handler) { case consts.OpCodeCorrectnessReportBroadcast: handler.CorrectnessReport(ctx, payload[1:]) - case consts.OpCodeSendSignerList: - handler.InitFrostSigner(ctx, payload[1:]) default: utils.Logger. With("Code", payload[0]). diff --git a/internal/transport/client/handler/frost.go b/internal/transport/client/handler/frost.go index 36bf09cc..77c6121d 100644 --- a/internal/transport/client/handler/frost.go +++ b/internal/transport/client/handler/frost.go @@ -4,12 +4,17 @@ import ( "context" ) -func (h *consumer) InitFrostSigner(ctx context.Context, message []byte) { +func (h *consumer) AskIfFrostSigner(ctx context.Context, message []byte) { // packet := new([]model.Signer).FromBytes(message) } -func (w worker) InitFrostSigner(ctx context.Context, message []byte) { +func (w worker) AskIfFrostSigner(ctx context.Context, message []byte) { + err := w.frostService.InitSigner() + if err != nil { + return + } + // packet := new(model.Signers).FromBytes(message) // TODO implement me panic("implement me") diff --git a/internal/transport/client/handler/handler.go b/internal/transport/client/handler/handler.go index cd515593..b435d5ed 100644 --- a/internal/transport/client/handler/handler.go +++ b/internal/transport/client/handler/handler.go @@ -10,5 +10,5 @@ type Handler interface { EventLog(ctx context.Context, message []byte) PriceReport(ctx context.Context, message []byte) - InitFrostSigner(ctx context.Context, message []byte) + AskIfFrostSigner(ctx context.Context, message []byte) } diff --git a/internal/transport/client/handler/worker.go b/internal/transport/client/handler/worker.go index b341e66a..83dca90a 100644 --- a/internal/transport/client/handler/worker.go +++ b/internal/transport/client/handler/worker.go @@ -1,8 +1,13 @@ package handler +import "github.com/TimeleapLabs/unchained/internal/service/frost" + type worker struct { + frostService frost.Service } -func NewWorkerHandler() Handler { - return &worker{} +func NewWorkerHandler(frostService frost.Service) Handler { + return &worker{ + frostService: frostService, + } } diff --git a/internal/transport/database/database.go b/internal/transport/database/database.go index 39ded2c0..8f00e3cf 100644 --- a/internal/transport/database/database.go +++ b/internal/transport/database/database.go @@ -3,6 +3,8 @@ package database import ( "context" + "github.com/redis/go-redis/v9" + "github.com/TimeleapLabs/unchained/internal/ent" ) @@ -10,3 +12,8 @@ type Database interface { GetConnection() *ent.Client HealthCheck(ctx context.Context) bool } + +type IRedisDatabase interface { + GetConnection() *redis.Client + HealthCheck(ctx context.Context) bool +} diff --git a/internal/transport/database/redis/redis.go b/internal/transport/database/redis/redis.go new file mode 100644 index 00000000..09afc368 --- /dev/null +++ b/internal/transport/database/redis/redis.go @@ -0,0 +1,50 @@ +package redis + +import ( + "context" + + "github.com/TimeleapLabs/unchained/internal/config" + "github.com/TimeleapLabs/unchained/internal/transport/database" + "github.com/TimeleapLabs/unchained/internal/utils" + + "github.com/redis/go-redis/v9" +) + +type connection struct { + db *redis.Client +} + +func (c *connection) HealthCheck(ctx context.Context) bool { + if c.db != nil { + return true + } + + status := c.db.Ping(ctx) + if status.Err() != nil { + utils.Logger.Error("HealthCheck: " + status.Err().Error()) + return false + } + + return true +} + +func (c *connection) GetConnection() *redis.Client { + if c.db != nil { + return c.db + } + + utils.Logger.Info("Connecting to Redis") + var err error + opts, err := redis.ParseURL(config.App.Redis.Dsn) + if err != nil { + panic(err) + } + + c.db = redis.NewClient(opts) + + return c.db +} + +func New() database.IRedisDatabase { + return &connection{} +} diff --git a/internal/transport/server/websocket/handler/correctness.go b/internal/transport/server/websocket/handler/correctness.go index 0399b13a..7464d33a 100644 --- a/internal/transport/server/websocket/handler/correctness.go +++ b/internal/transport/server/websocket/handler/correctness.go @@ -6,7 +6,7 @@ import ( "github.com/gorilla/websocket" ) -func CorrectnessRecord(conn *websocket.Conn, payload []byte) ([]byte, error) { +func (h Handler) CorrectnessRecord(conn *websocket.Conn, payload []byte) ([]byte, error) { err := middleware.IsConnectionAuthenticated(conn) if err != nil { return []byte{}, err @@ -14,7 +14,7 @@ func CorrectnessRecord(conn *websocket.Conn, payload []byte) ([]byte, error) { correctness := new(model.CorrectnessReportPacket).FromBytes(payload) - signer, err := middleware.IsMessageValid(conn, correctness.Correctness.Sia().Bytes(), correctness.Signature) + signer, err := h.middleware.IsMessageValid(conn, correctness.Correctness.Sia().Bytes(), correctness.Signature) if err != nil { return []byte{}, err } diff --git a/internal/transport/server/websocket/handler/event.go b/internal/transport/server/websocket/handler/event.go index d2172314..2ebb24ca 100644 --- a/internal/transport/server/websocket/handler/event.go +++ b/internal/transport/server/websocket/handler/event.go @@ -6,7 +6,7 @@ import ( "github.com/gorilla/websocket" ) -func EventLog(conn *websocket.Conn, payload []byte) ([]byte, error) { +func (h Handler) EventLog(conn *websocket.Conn, payload []byte) ([]byte, error) { err := middleware.IsConnectionAuthenticated(conn) if err != nil { return []byte{}, err @@ -14,7 +14,7 @@ func EventLog(conn *websocket.Conn, payload []byte) ([]byte, error) { priceReport := new(model.EventLogReportPacket).FromBytes(payload) - signer, err := middleware.IsMessageValid(conn, priceReport.EventLog.Sia().Bytes(), priceReport.Signature) + signer, err := h.middleware.IsMessageValid(conn, priceReport.EventLog.Sia().Bytes(), priceReport.Signature) if err != nil { return []byte{}, err } diff --git a/internal/transport/server/websocket/handler/handler.go b/internal/transport/server/websocket/handler/handler.go new file mode 100644 index 00000000..b7087458 --- /dev/null +++ b/internal/transport/server/websocket/handler/handler.go @@ -0,0 +1,18 @@ +package handler + +import ( + "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/middleware" + "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/store" +) + +type Handler struct { + middleware middleware.Middleware + clientRepository store.ClientRepository +} + +func NewHandler(middleware middleware.Middleware, clientRepository store.ClientRepository) *Handler { + return &Handler{ + middleware: middleware, + clientRepository: clientRepository, + } +} diff --git a/internal/transport/server/websocket/handler/hello.go b/internal/transport/server/websocket/handler/hello.go index b76d5d4e..9e003323 100644 --- a/internal/transport/server/websocket/handler/hello.go +++ b/internal/transport/server/websocket/handler/hello.go @@ -8,7 +8,7 @@ import ( "github.com/gorilla/websocket" ) -func Hello(conn *websocket.Conn, payload []byte) ([]byte, error) { +func (h Handler) Hello(conn *websocket.Conn, payload []byte) ([]byte, error) { signer := new(model.Signer).FromBytes(payload) if signer.Name == "" { @@ -16,15 +16,12 @@ func Hello(conn *websocket.Conn, payload []byte) ([]byte, error) { return []byte{}, consts.ErrInvalidConfig } - store.Signers.Range(func(conn *websocket.Conn, signerInMap model.Signer) bool { - publicKeyInUse := signerInMap.PublicKey == signer.PublicKey - if publicKeyInUse { - Close(conn) - } - return !publicKeyInUse - }) + preConn, preConnExist := h.clientRepository.GetByPublicKey(signer.PublicKey) + if preConnExist { + Close(preConn) + } - store.Signers.Store(conn, *signer) + h.clientRepository.Set(conn, *signer) // Start KOSK verification challenge := model.ChallengePacket{Random: utils.NewChallenge()} diff --git a/internal/transport/server/websocket/handler/kosk.go b/internal/transport/server/websocket/handler/kosk.go index 8f8e3329..9f724e46 100644 --- a/internal/transport/server/websocket/handler/kosk.go +++ b/internal/transport/server/websocket/handler/kosk.go @@ -3,15 +3,14 @@ package handler import ( "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/model" - "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/middleware" "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/store" "github.com/gorilla/websocket" ) -func Kosk(conn *websocket.Conn, payload []byte) error { +func (h Handler) Kosk(conn *websocket.Conn, payload []byte) error { challenge := new(model.ChallengePacket).FromBytes(payload) - _, err := middleware.IsMessageValid(conn, challenge.Random[:], challenge.Signature) + _, err := h.middleware.IsMessageValid(conn, challenge.Random[:], challenge.Signature) if err != nil { return consts.ErrInvalidKosk } diff --git a/internal/transport/server/websocket/handler/price.go b/internal/transport/server/websocket/handler/price.go index 85eb7c0d..64f8cdf4 100644 --- a/internal/transport/server/websocket/handler/price.go +++ b/internal/transport/server/websocket/handler/price.go @@ -7,7 +7,7 @@ import ( ) // PriceReport check signature of message and return price info. -func PriceReport(conn *websocket.Conn, payload []byte) ([]byte, error) { +func (h Handler) PriceReport(conn *websocket.Conn, payload []byte) ([]byte, error) { err := middleware.IsConnectionAuthenticated(conn) if err != nil { return []byte{}, err @@ -15,7 +15,7 @@ func PriceReport(conn *websocket.Conn, payload []byte) ([]byte, error) { priceReport := new(model.PriceReportPacket).FromBytes(payload) - signer, err := middleware.IsMessageValid(conn, priceReport.PriceInfo.Sia().Bytes(), priceReport.Signature) + signer, err := h.middleware.IsMessageValid(conn, priceReport.PriceInfo.Sia().Bytes(), priceReport.Signature) if err != nil { return []byte{}, err } diff --git a/internal/transport/server/websocket/middleware/signature.go b/internal/transport/server/websocket/middleware/signature.go index cf4fdae1..08fa935d 100644 --- a/internal/transport/server/websocket/middleware/signature.go +++ b/internal/transport/server/websocket/middleware/signature.go @@ -9,8 +9,12 @@ import ( "github.com/gorilla/websocket" ) -func IsMessageValid(conn *websocket.Conn, message []byte, signature [48]byte) (model.Signer, error) { - signer, ok := store.Signers.Load(conn) +type Middleware struct { + signerRepository store.ClientRepository +} + +func (m Middleware) IsMessageValid(conn *websocket.Conn, message []byte, signature [48]byte) (model.Signer, error) { + signer, ok := m.signerRepository.Get(conn) if !ok { return model.Signer{}, consts.ErrMissingHello } @@ -27,3 +31,9 @@ func IsMessageValid(conn *websocket.Conn, message []byte, signature [48]byte) (m return signer, nil } + +func New(signerRepository store.ClientRepository) Middleware { + return Middleware{ + signerRepository: signerRepository, + } +} diff --git a/internal/transport/server/websocket/store/native.go b/internal/transport/server/websocket/store/native.go new file mode 100644 index 00000000..ffd9275d --- /dev/null +++ b/internal/transport/server/websocket/store/native.go @@ -0,0 +1,51 @@ +package store + +import ( + "github.com/TimeleapLabs/unchained/internal/model" + "github.com/gorilla/websocket" + "github.com/puzpuzpuz/xsync/v3" +) + +type NativeStore struct { + signers xsync.MapOf[*websocket.Conn, model.Signer] +} + +func (n *NativeStore) GetByPublicKey(publicKey [96]byte) (*websocket.Conn, bool) { + var connection *websocket.Conn + n.signers.Range(func(conn *websocket.Conn, signerInMap model.Signer) bool { + publicKeyInUse := signerInMap.PublicKey == publicKey + if publicKeyInUse { + connection = conn + } + return !publicKeyInUse + }) + + return connection, connection != nil +} + +func (n *NativeStore) GetAll() []model.Signer { + signers := []model.Signer{} + + n.signers.Range(func(_ *websocket.Conn, value model.Signer) bool { + signers = append(signers, value) + return true + }) + + return signers +} + +func (n *NativeStore) Set(conn *websocket.Conn, signer model.Signer) { + n.signers.Store(conn, signer) +} + +func (n *NativeStore) Remove(conn *websocket.Conn) { + n.signers.Delete(conn) +} + +func (n *NativeStore) Get(conn *websocket.Conn) (model.Signer, bool) { + return n.signers.Load(conn) +} + +func New() ClientRepository { + return &NativeStore{} +} diff --git a/internal/transport/server/websocket/store/redis.go b/internal/transport/server/websocket/store/redis.go new file mode 100644 index 00000000..637a053c --- /dev/null +++ b/internal/transport/server/websocket/store/redis.go @@ -0,0 +1,40 @@ +package store + +import ( + "github.com/TimeleapLabs/unchained/internal/model" + "github.com/TimeleapLabs/unchained/internal/transport/database" + "github.com/gorilla/websocket" + "github.com/redis/go-redis/v9" +) + +type RedisStore struct { + client *redis.Client + fallback ClientRepository +} + +func (r RedisStore) GetAll() []model.Signer { + return r.fallback.GetAll() +} + +func (r RedisStore) GetByPublicKey(publicKey [96]byte) (*websocket.Conn, bool) { + return r.fallback.GetByPublicKey(publicKey) +} + +func (r RedisStore) Set(conn *websocket.Conn, signer model.Signer) { + r.fallback.Set(conn, signer) +} + +func (r RedisStore) Remove(conn *websocket.Conn) { + r.fallback.Remove(conn) +} + +func (r RedisStore) Get(conn *websocket.Conn) (model.Signer, bool) { + return r.fallback.Get(conn) +} + +func NewRedisStore(db database.IRedisDatabase, fallback ClientRepository) ClientRepository { + return &RedisStore{ + client: db.GetConnection(), + fallback: fallback, + } +} diff --git a/internal/transport/server/websocket/store/store.go b/internal/transport/server/websocket/store/store.go index 6bf69d7e..b7febd30 100644 --- a/internal/transport/server/websocket/store/store.go +++ b/internal/transport/server/websocket/store/store.go @@ -8,4 +8,11 @@ import ( ) var Challenges = xsync.NewMapOf[*websocket.Conn, model.ChallengePacket]() -var Signers = xsync.NewMapOf[*websocket.Conn, model.Signer]() + +type ClientRepository interface { + Set(conn *websocket.Conn, signer model.Signer) + Remove(conn *websocket.Conn) + Get(conn *websocket.Conn) (model.Signer, bool) + GetAll() []model.Signer + GetByPublicKey(publicKey [96]byte) (*websocket.Conn, bool) +} diff --git a/internal/transport/server/websocket/websocket.go b/internal/transport/server/websocket/websocket.go index f94cd296..293a5045 100644 --- a/internal/transport/server/websocket/websocket.go +++ b/internal/transport/server/websocket/websocket.go @@ -5,6 +5,8 @@ import ( "fmt" "net/http" + "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/middleware" + "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/transport/server/pubsub" "github.com/TimeleapLabs/unchained/internal/utils" @@ -16,100 +18,115 @@ import ( var upgrader = websocket.Upgrader{} -func WithWebsocket() func() { +func WithWebsocket( + signerRepository store.ClientRepository, +) func() { return func() { utils.Logger.Info("Starting a websocket server") versionedRoot := fmt.Sprintf("/%s", consts.ProtocolVersion) - http.HandleFunc(versionedRoot, multiplexer) + http.HandleFunc( + versionedRoot, + multiplexer( + signerRepository, + handler.NewHandler( + middleware.New(signerRepository), + signerRepository, + ), + )) } } -func multiplexer(w http.ResponseWriter, r *http.Request) { - conn, err := upgrader.Upgrade(w, r, nil) - if err != nil { - utils.Logger.Error("Can't upgrade the HTTP connection: %v", err) - return - } - - ctx, cancel := context.WithCancel(context.TODO()) - - defer store.Signers.Delete(conn) - defer store.Challenges.Delete(conn) - defer cancel() - - for { - messageType, payload, err := conn.ReadMessage() +func multiplexer( + signerRepository store.ClientRepository, + serverHandler *handler.Handler, +) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + conn, err := upgrader.Upgrade(w, r, nil) if err != nil { - utils.Logger.Error("Can't read message: %v", err) - - err := conn.Close() - if err != nil { - utils.Logger.Error("Can't close connection: %v", err) - } - - break + utils.Logger.Error("Can't upgrade the HTTP connection: %v", err) + return } - if len(payload) == 0 { - continue - } + ctx, cancel := context.WithCancel(context.TODO()) - switch consts.OpCode(payload[0]) { - case consts.OpCodeHello: - utils.Logger.With("IP", conn.RemoteAddr().String()).Info("New Client Registered") - result, err := handler.Hello(conn, payload[1:]) - if err != nil { - handler.SendError(conn, messageType, consts.OpCodeError, err) - continue - } + defer signerRepository.Remove(conn) + defer store.Challenges.Delete(conn) + defer cancel() - handler.SendMessage(conn, messageType, consts.OpCodeFeedback, "conf.ok") - handler.Send(conn, messageType, consts.OpCodeKoskChallenge, result) - case consts.OpCodePriceReport: - result, err := handler.PriceReport(conn, payload[1:]) + for { + messageType, payload, err := conn.ReadMessage() if err != nil { - handler.SendError(conn, messageType, consts.OpCodeError, err) - continue - } + utils.Logger.Error("Can't read message: %v", err) - pubsub.Publish(consts.ChannelPriceReport, consts.OpCodePriceReportBroadcast, result) - handler.SendMessage(conn, messageType, consts.OpCodeFeedback, "signature.accepted") - case consts.OpCodeEventLog: - result, err := handler.EventLog(conn, payload[1:]) - if err != nil { - handler.SendError(conn, messageType, consts.OpCodeError, err) - continue - } + err := conn.Close() + if err != nil { + utils.Logger.Error("Can't close connection: %v", err) + } - pubsub.Publish(consts.ChannelEventLog, consts.OpCodeEventLogBroadcast, result) - handler.SendMessage(conn, messageType, consts.OpCodeFeedback, "signature.accepted") - case consts.OpCodeCorrectnessReport: - result, err := handler.CorrectnessRecord(conn, payload[1:]) - if err != nil { - handler.SendError(conn, messageType, consts.OpCodeError, err) - continue + break } - pubsub.Publish(consts.ChannelCorrectnessReport, consts.OpCodeCorrectnessReportBroadcast, result) - handler.SendMessage(conn, messageType, consts.OpCodeFeedback, "signature.accepted") - case consts.OpCodeKoskResult: - err := handler.Kosk(conn, payload[1:]) - if err != nil { - handler.SendError(conn, messageType, consts.OpCodeError, err) + if len(payload) == 0 { continue } - handler.SendMessage(conn, messageType, consts.OpCodeFeedback, "kosk.ok") - case consts.OpCodeRegisterConsumer: - utils.Logger. - With("IP", conn.RemoteAddr().String()). - With("Channel", string(payload[1:])). - Info("New Consumer registered") - - go handler.BroadcastListener(ctx, conn, pubsub.Subscribe(string(payload[1:]))) - default: - handler.SendError(conn, messageType, consts.OpCodeError, consts.ErrNotSupportedInstruction) + switch consts.OpCode(payload[0]) { + case consts.OpCodeHello: + utils.Logger.With("IP", conn.RemoteAddr().String()).Info("New Client Registered") + result, err := serverHandler.Hello(conn, payload[1:]) + if err != nil { + handler.SendError(conn, messageType, consts.OpCodeError, err) + continue + } + + handler.SendMessage(conn, messageType, consts.OpCodeFeedback, "conf.ok") + handler.Send(conn, messageType, consts.OpCodeKoskChallenge, result) + case consts.OpCodePriceReport: + result, err := serverHandler.PriceReport(conn, payload[1:]) + if err != nil { + handler.SendError(conn, messageType, consts.OpCodeError, err) + continue + } + + pubsub.Publish(consts.ChannelPriceReport, consts.OpCodePriceReportBroadcast, result) + handler.SendMessage(conn, messageType, consts.OpCodeFeedback, "signature.accepted") + case consts.OpCodeEventLog: + result, err := serverHandler.EventLog(conn, payload[1:]) + if err != nil { + handler.SendError(conn, messageType, consts.OpCodeError, err) + continue + } + + pubsub.Publish(consts.ChannelEventLog, consts.OpCodeEventLogBroadcast, result) + handler.SendMessage(conn, messageType, consts.OpCodeFeedback, "signature.accepted") + case consts.OpCodeCorrectnessReport: + result, err := serverHandler.CorrectnessRecord(conn, payload[1:]) + if err != nil { + handler.SendError(conn, messageType, consts.OpCodeError, err) + continue + } + + pubsub.Publish(consts.ChannelCorrectnessReport, consts.OpCodeCorrectnessReportBroadcast, result) + handler.SendMessage(conn, messageType, consts.OpCodeFeedback, "signature.accepted") + case consts.OpCodeKoskResult: + err := serverHandler.Kosk(conn, payload[1:]) + if err != nil { + handler.SendError(conn, messageType, consts.OpCodeError, err) + continue + } + + handler.SendMessage(conn, messageType, consts.OpCodeFeedback, "kosk.ok") + case consts.OpCodeRegisterConsumer: + utils.Logger. + With("IP", conn.RemoteAddr().String()). + With("Channel", string(payload[1:])). + Info("New Consumer registered") + + go handler.BroadcastListener(ctx, conn, pubsub.Subscribe(string(payload[1:]))) + default: + handler.SendError(conn, messageType, consts.OpCodeError, consts.ErrNotSupportedInstruction) + } } } } From 62c5c0fa69a22a20d7345976e300b29ee29d5a74 Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Fri, 7 Jun 2024 08:18:21 +0330 Subject: [PATCH 23/29] =?UTF-8?q?=E2=9C=A8=20feat(frost-networking):=20add?= =?UTF-8?q?=20network=20mechanism=20to=20init=20frost=20party=20>>>=20?= =?UTF-8?q?=E2=8F=B0=206h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/app/worker.go | 3 +- internal/config/model.go | 3 +- internal/consts/channels.go | 2 +- internal/consts/opcodes.go | 3 +- internal/crypto/identity.go | 9 +-- internal/crypto/multisig/identity.go | 30 +++++++-- internal/crypto/multisig/identity_test.go | 5 +- internal/crypto/multisig/signer.go | 38 +++++------ internal/scheduler/frost.go | 7 +- internal/service/frost/frost.go | 39 +++++++++-- internal/service/frost/sync.go | 64 +++++++++++++------ internal/transport/client/client.go | 6 ++ internal/transport/client/handler/frost.go | 17 +++-- internal/transport/client/handler/handler.go | 3 +- internal/transport/client/store/native.go | 20 ++++++ .../server/websocket/store/native.go | 6 +- .../transport/server/websocket/websocket.go | 14 ++++ 17 files changed, 195 insertions(+), 74 deletions(-) create mode 100644 internal/transport/client/store/native.go diff --git a/internal/app/worker.go b/internal/app/worker.go index 2a286ea6..b1b3545f 100644 --- a/internal/app/worker.go +++ b/internal/app/worker.go @@ -31,6 +31,7 @@ func Worker() { ) ethRPC := ethereum.New() + pos := pos.New(ethRPC) eventLogRepo := postgres.NewEventLog(nil) @@ -40,7 +41,7 @@ func Worker() { badger := evmlogService.NewBadger(config.App.System.ContextPath) evmLogService := evmlogService.New(ethRPC, pos, eventLogRepo, signerRepo, badger) uniswapService := uniswapService.New(ethRPC, pos, signerRepo, assetPrice) - frostService := frost.New() + frostService := frost.New(pos) scheduler := scheduler.New( scheduler.WithEthLogs(evmLogService), diff --git a/internal/config/model.go b/internal/config/model.go index 69da9514..fb1a4a19 100644 --- a/internal/config/model.go +++ b/internal/config/model.go @@ -37,6 +37,7 @@ type EthLog struct { // Frost struct represent all task detail of its plugin. type Frost struct { Schedule time.Duration `yaml:"schedule"` + Session string `yaml:"session"` } // Plugins struct holds all applications plugin configs. @@ -76,7 +77,7 @@ type Token struct { // ProofOfStake struct holds information about POS contract of application. type ProofOfStake struct { Chain string `env:"POS_CHAIN" env-default:"arbitrumSepolia" yaml:"chain"` - Address string `env:"POS_ADDRESS" env-default:"0x965e364987356785b7E89e2Fe7B70f5E5107332d" yaml:"address"` + Address string `env:"POS_ADDRESS" env-default:"0x54550AAfe0df642fbcAde11174250542D0d5FE54" yaml:"address"` Base int64 `env:"POS_BASE" env-default:"1" yaml:"base"` } diff --git a/internal/consts/channels.go b/internal/consts/channels.go index d68768e6..81ba7ad0 100644 --- a/internal/consts/channels.go +++ b/internal/consts/channels.go @@ -7,5 +7,5 @@ const ( ChannelPriceReport Channels = "unchained:price_report" ChannelEventLog Channels = "unchained:event_log" ChannelCorrectnessReport Channels = "unchained:correctness_report" - ChannelFrostSigner Channels = "unchained:frost_signer" + ChannelFrostSigner Channels = "unchained:frost:handshake" ) diff --git a/internal/consts/opcodes.go b/internal/consts/opcodes.go index 6605b8c1..cbe21afb 100644 --- a/internal/consts/opcodes.go +++ b/internal/consts/opcodes.go @@ -24,5 +24,6 @@ const ( OpCodeCorrectnessReport OpCode = 10 OpCodeCorrectnessReportBroadcast OpCode = 11 - OpCodeAskIfFrostSigner OpCode = 12 + OpCodeFrostSignerHandshake OpCode = 12 + OpcodeFrostSignerIsReady OpCode = 13 ) diff --git a/internal/crypto/identity.go b/internal/crypto/identity.go index 971a853c..4ecb6410 100644 --- a/internal/crypto/identity.go +++ b/internal/crypto/identity.go @@ -3,10 +3,11 @@ package crypto import ( "encoding/hex" + "github.com/TimeleapLabs/unchained/internal/crypto/multisig" + "github.com/TimeleapLabs/unchained/internal/config" "github.com/TimeleapLabs/unchained/internal/crypto/bls" "github.com/TimeleapLabs/unchained/internal/crypto/ethereum" - "github.com/TimeleapLabs/unchained/internal/crypto/tss" "github.com/TimeleapLabs/unchained/internal/model" ) @@ -19,9 +20,9 @@ type Signer interface { // MachineIdentity holds machine identity and provide and manage keys. type MachineIdentity struct { - Bls Signer - Eth Signer - Tss *tss.DistributedSigner + Bls Signer + Eth Signer + Frost *multisig.DistributedSigner } // Identity is a global variable that holds machine identity. diff --git a/internal/crypto/multisig/identity.go b/internal/crypto/multisig/identity.go index 87869f7e..1f48a3c0 100644 --- a/internal/crypto/multisig/identity.go +++ b/internal/crypto/multisig/identity.go @@ -1,6 +1,8 @@ package multisig import ( + "github.com/TimeleapLabs/unchained/internal/consts" + "github.com/TimeleapLabs/unchained/internal/utils" "github.com/taurusgroup/multi-party-sig/pkg/party" "github.com/taurusgroup/multi-party-sig/pkg/protocol" "github.com/taurusgroup/multi-party-sig/protocols/frost" @@ -17,14 +19,23 @@ type DistributedSigner struct { Config *frost.TaprootConfig } +// ConfirmFromBytes function will set other parties confirms from byte array. +func (d *DistributedSigner) ConfirmFromBytes(msgBytes []byte) (bool, error) { + msg := &protocol.Message{} + err := msg.UnmarshalBinary(msgBytes) + if err != nil { + utils.Logger.With("err", err).Error("cant unmarshal message") + return false, consts.ErrCantDecode + } + + return d.Confirm(msg) +} + // Confirm function will set other parties confirms. func (d *DistributedSigner) Confirm(msg *protocol.Message) (bool, error) { - // msg := &protocol.Message{} - // err := msg.UnmarshalBinary(msgByte) - // if err != nil { - // utils.Logger.With("err", err).Error("cant unmarshal message") - // return consts.ErrCantDecode - //} + if !msg.IsFor(d.ID) { + return false, consts.ErrInvalidSignature + } d.ackHandler.Accept(msg) @@ -37,7 +48,12 @@ func (d *DistributedSigner) Confirm(msg *protocol.Message) (bool, error) { return false, err } - d.Config = result.(*frost.TaprootConfig) + var ok bool + d.Config, ok = result.(*frost.TaprootConfig) + if !ok { + utils.Logger.Error("Can't get TaprootConfig") + return false, consts.ErrInternalError + } return true, nil } diff --git a/internal/crypto/multisig/identity_test.go b/internal/crypto/multisig/identity_test.go index c7138def..c197fc32 100644 --- a/internal/crypto/multisig/identity_test.go +++ b/internal/crypto/multisig/identity_test.go @@ -18,7 +18,6 @@ const ( var ( sessionID = "sessionID" - testData = []byte("HELLO hello") ) type MultiSigIdentityTestSuite struct { @@ -44,7 +43,7 @@ func (s *MultiSigIdentityTestSuite) SetupTest() { wg := sync.WaitGroup{} for _, channel := range channels { wg.Add(1) - go func() { + go func(channel <-chan *protocol.Message) { for msg := range channel { if msg.Broadcast { for _, p := range s.parties { @@ -68,7 +67,7 @@ func (s *MultiSigIdentityTestSuite) SetupTest() { } } } - }() + }(channel) } wg.Wait() diff --git a/internal/crypto/multisig/signer.go b/internal/crypto/multisig/signer.go index 49ab325e..3650ae4b 100644 --- a/internal/crypto/multisig/signer.go +++ b/internal/crypto/multisig/signer.go @@ -44,22 +44,22 @@ func (d *DistributedSigner) NewSigner(data []byte) (*MessageSigner, <-chan *prot }, handler.Listen(), nil } -func decodeMessages(in <-chan *protocol.Message) <-chan []byte { - out := make(chan []byte) - - go func() { - for msg := range in { - msgByte, err := msg.MarshalBinary() - if err != nil { - utils.Logger.With("err", err).Error("cant marshal message") - continue - } - - out <- msgByte - } - - close(out) - }() - - return out -} +// func decodeMessages(in <-chan *protocol.Message) <-chan []byte { +// out := make(chan []byte) +// +// go func() { +// for msg := range in { +// msgByte, err := msg.MarshalBinary() +// if err != nil { +// utils.Logger.With("err", err).Error("cant marshal message") +// continue +// } +// +// out <- msgByte +// } +// +// close(out) +// }() +// +// return out +//} diff --git a/internal/scheduler/frost.go b/internal/scheduler/frost.go index 9065a0d5..16bc056c 100644 --- a/internal/scheduler/frost.go +++ b/internal/scheduler/frost.go @@ -1,7 +1,10 @@ package scheduler import ( + "context" + "github.com/TimeleapLabs/unchained/internal/service/frost" + "github.com/TimeleapLabs/unchained/internal/utils" ) // FrostSync is a scheduler for syncing signer of Frost and keep task's dependencies. @@ -11,7 +14,9 @@ type FrostSync struct { // Run will trigger by the scheduler and process the Frost sync. func (e *FrostSync) Run() { - err := e.frostService.SyncFrost() + utils.Logger.Info("Start synchronizing frost signers") + ctx := context.TODO() + err := e.frostService.SyncSigners(ctx) if err != nil { panic(err) } diff --git a/internal/service/frost/frost.go b/internal/service/frost/frost.go index b18716b7..91b6223d 100644 --- a/internal/service/frost/frost.go +++ b/internal/service/frost/frost.go @@ -1,14 +1,43 @@ package frost +import ( + "context" + + "github.com/TimeleapLabs/unchained/internal/consts" + "github.com/TimeleapLabs/unchained/internal/crypto" + "github.com/TimeleapLabs/unchained/internal/service/pos" + "github.com/TimeleapLabs/unchained/internal/transport/client/conn" + "github.com/TimeleapLabs/unchained/internal/utils" +) + type Service interface { - InitSigner() error + SyncSigners(ctx context.Context) error + ConfirmHandshake(ctx context.Context, message []byte) error } type service struct { - reserveSigners []bool - currentSigners []bool + pos pos.Service + + // reserveSigners []bool + // currentSigners []bool +} + +func (s *service) ConfirmHandshake(_ context.Context, message []byte) error { + isReady, err := crypto.Identity.Frost.ConfirmFromBytes(message) + if err != nil { + utils.Logger.With("Error", err).Error("Can't confirm handshake message") + return err + } + + if isReady { + conn.SendMessage(consts.OpcodeFrostSignerIsReady, crypto.Identity.ExportEvmSigner().EvmAddress) + } + + return nil } -func New() Service { - return &service{} +func New(pos pos.Service) Service { + return &service{ + pos: pos, + } } diff --git a/internal/service/frost/sync.go b/internal/service/frost/sync.go index 129414c6..b9ade132 100644 --- a/internal/service/frost/sync.go +++ b/internal/service/frost/sync.go @@ -1,31 +1,57 @@ package frost import ( - "github.com/TimeleapLabs/unchained/internal/model" + "context" + + "github.com/TimeleapLabs/unchained/internal/config" + "github.com/TimeleapLabs/unchained/internal/consts" + "github.com/TimeleapLabs/unchained/internal/crypto" + "github.com/TimeleapLabs/unchained/internal/crypto/multisig" + "github.com/TimeleapLabs/unchained/internal/transport/client/conn" + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/taurusgroup/multi-party-sig/pkg/protocol" ) -// SyncFrost starts calculating of Frost signers by sending signers list to the Broker. -func (s *service) SyncFrost() error { - // signers := []model.Signer{} - // store.Signers.Range(func(_ *websocket.Conn, value model.Signer) bool { - // signers = append(signers, value) - // return true - // }) - // - // signersBytes, err := json.Marshal(signers) - //if err != nil { - // utils.Logger.With("Error", err).Error("Cant marshal signers list") - // return consts.ErrInternalError - //} +// SyncSigners starts calculating of Frost signers by sending signers list to the Broker. +func (s *service) SyncSigners(ctx context.Context) error { + addresses, err := s.pos.GetSchnorrSigners(ctx) + if err != nil { + utils.Logger.With("Error", err).Error("Cant get signers list") + return err + } + + minSignerCount := (len(addresses) / 2) + 1 + + var handshakeMessageCh <-chan *protocol.Message + crypto.Identity.Frost, handshakeMessageCh = multisig.NewIdentity( + config.App.Plugins.Frost.Session, + crypto.Identity.ExportEvmSigner().EvmAddress, + addressArrayToStringArray(addresses), + minSignerCount, + ) + + go s.CoordinateHandshake(handshakeMessageCh) return nil } -// SyncSigners Get list of signers and check power of voting them and generate a new list (if there is difference) of signers which have power. -func (s *service) SyncSigners(signers []model.Signer) error { - // TODO: get power of list items and delete no power ones. +func (s *service) CoordinateHandshake(ch <-chan *protocol.Message) { + for msg := range ch { + msgBytes, err := msg.MarshalBinary() + if err != nil { + utils.Logger.With("Error", err).Error("Cant marshal handshake message") + } - // TODO: check the final list with previous one, and replace it if it have difference + conn.Send(consts.OpCodeFrostSignerHandshake, msgBytes) + } +} - return nil +func addressArrayToStringArray(addresses []common.Address) []string { + strAddresses := make([]string, 0, len(addresses)) + for _, address := range addresses { + strAddresses = append(strAddresses, address.String()) + } + + return strAddresses } diff --git a/internal/transport/client/client.go b/internal/transport/client/client.go index 8f440e98..91bd6289 100644 --- a/internal/transport/client/client.go +++ b/internal/transport/client/client.go @@ -45,6 +45,12 @@ func NewRPC(handler handler.Handler) { case consts.OpCodeCorrectnessReportBroadcast: handler.CorrectnessReport(ctx, payload[1:]) + case consts.OpCodeFrostSignerHandshake: + handler.ConfirmFrostHandshake(ctx, payload[1:]) + + case consts.OpcodeFrostSignerIsReady: + handler.StoreOnlineFrostParty(ctx, payload[1:]) + default: utils.Logger. With("Code", payload[0]). diff --git a/internal/transport/client/handler/frost.go b/internal/transport/client/handler/frost.go index 77c6121d..b6145c37 100644 --- a/internal/transport/client/handler/frost.go +++ b/internal/transport/client/handler/frost.go @@ -4,18 +4,17 @@ import ( "context" ) -func (h *consumer) AskIfFrostSigner(ctx context.Context, message []byte) { - // packet := new([]model.Signer).FromBytes(message) +func (h *consumer) ConfirmFrostHandshake(_ context.Context, _ []byte) {} -} - -func (w worker) AskIfFrostSigner(ctx context.Context, message []byte) { - err := w.frostService.InitSigner() +func (w worker) ConfirmFrostHandshake(ctx context.Context, message []byte) { + err := w.frostService.ConfirmHandshake(ctx, message) if err != nil { return } +} + +func (h *consumer) StoreOnlineFrostParty(_ context.Context, _ []byte) { - // packet := new(model.Signers).FromBytes(message) - // TODO implement me - panic("implement me") } + +func (w worker) StoreOnlineFrostParty(_ context.Context, _ []byte) {} diff --git a/internal/transport/client/handler/handler.go b/internal/transport/client/handler/handler.go index b435d5ed..570275a7 100644 --- a/internal/transport/client/handler/handler.go +++ b/internal/transport/client/handler/handler.go @@ -10,5 +10,6 @@ type Handler interface { EventLog(ctx context.Context, message []byte) PriceReport(ctx context.Context, message []byte) - AskIfFrostSigner(ctx context.Context, message []byte) + ConfirmFrostHandshake(ctx context.Context, message []byte) + StoreOnlineFrostParty(ctx context.Context, message []byte) } diff --git a/internal/transport/client/store/native.go b/internal/transport/client/store/native.go new file mode 100644 index 00000000..9e41b4c4 --- /dev/null +++ b/internal/transport/client/store/native.go @@ -0,0 +1,20 @@ +package store + +import ( + "time" + + "github.com/puzpuzpuz/xsync/v3" +) + +type SignerRepository interface { +} + +type NativeStore struct { + signers *xsync.MapOf[string, time.Time] +} + +func New() SignerRepository { + return &NativeStore{ + signers: xsync.NewMapOf[string, time.Time](), + } +} diff --git a/internal/transport/server/websocket/store/native.go b/internal/transport/server/websocket/store/native.go index ffd9275d..aa9fa501 100644 --- a/internal/transport/server/websocket/store/native.go +++ b/internal/transport/server/websocket/store/native.go @@ -7,7 +7,7 @@ import ( ) type NativeStore struct { - signers xsync.MapOf[*websocket.Conn, model.Signer] + signers *xsync.MapOf[*websocket.Conn, model.Signer] } func (n *NativeStore) GetByPublicKey(publicKey [96]byte) (*websocket.Conn, bool) { @@ -47,5 +47,7 @@ func (n *NativeStore) Get(conn *websocket.Conn) (model.Signer, bool) { } func New() ClientRepository { - return &NativeStore{} + return &NativeStore{ + signers: xsync.NewMapOf[*websocket.Conn, model.Signer](), + } } diff --git a/internal/transport/server/websocket/websocket.go b/internal/transport/server/websocket/websocket.go index 293a5045..f62cedba 100644 --- a/internal/transport/server/websocket/websocket.go +++ b/internal/transport/server/websocket/websocket.go @@ -5,6 +5,8 @@ import ( "fmt" "net/http" + "github.com/taurusgroup/multi-party-sig/pkg/protocol" + "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/middleware" "github.com/TimeleapLabs/unchained/internal/consts" @@ -124,6 +126,18 @@ func multiplexer( Info("New Consumer registered") go handler.BroadcastListener(ctx, conn, pubsub.Subscribe(string(payload[1:]))) + case consts.OpCodeFrostSignerHandshake: + msg := &protocol.Message{} + err = msg.UnmarshalBinary(payload[1:]) + if err != nil { + handler.SendError(conn, messageType, consts.OpCodeError, err) + continue + } + + pubsub.Publish(consts.ChannelFrostSigner, consts.OpCodeFrostSignerHandshake, payload[1:]) + case consts.OpcodeFrostSignerIsReady: + pubsub.Publish(consts.ChannelFrostSigner, consts.OpcodeFrostSignerIsReady, payload[1:]) + default: handler.SendError(conn, messageType, consts.OpCodeError, consts.ErrNotSupportedInstruction) } From eace34e0a26ce6b5ab20f56b18e75d2d3857828a Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Fri, 7 Jun 2024 08:33:50 +0330 Subject: [PATCH 24/29] =?UTF-8?q?=F0=9F=94=80=20merge(merge):=20merge=20to?= =?UTF-8?q?=20develop=20>>>=20=E2=8F=B0=2030m?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/handler/broker.go | 2 +- cmd/handler/consumer.go | 2 +- go.mod | 20 ++-- internal/crypto/frost/convert.go | 158 ------------------------- internal/crypto/frost/identity.go | 95 --------------- internal/crypto/frost/identity_test.go | 94 --------------- internal/crypto/frost/signer.go | 107 ----------------- 7 files changed, 11 insertions(+), 467 deletions(-) delete mode 100644 internal/crypto/frost/convert.go delete mode 100644 internal/crypto/frost/identity.go delete mode 100644 internal/crypto/frost/identity_test.go delete mode 100644 internal/crypto/frost/signer.go diff --git a/cmd/handler/broker.go b/cmd/handler/broker.go index 9e95a507..33a48403 100644 --- a/cmd/handler/broker.go +++ b/cmd/handler/broker.go @@ -28,7 +28,7 @@ func WithBrokerCmd(cmd *cobra.Command) { cmd.AddCommand(broker) } -// init loads CLI flags of broker command +// init loads CLI flags of broker command. func init() { broker.Flags().StringP( "broker", diff --git a/cmd/handler/consumer.go b/cmd/handler/consumer.go index e6e1ea95..b62e0444 100644 --- a/cmd/handler/consumer.go +++ b/cmd/handler/consumer.go @@ -34,7 +34,7 @@ func WithConsumerCmd(cmd *cobra.Command) { cmd.AddCommand(consumer) } -// init loads CLI flags of consumer command +// init loads CLI flags of consumer command. func init() { consumer.Flags().StringP( "broker", diff --git a/go.mod b/go.mod index 2df968d1..6939bcee 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,6 @@ require ( entgo.io/contrib v0.4.6-0.20240215171353-eff33e4dca0b entgo.io/ent v0.13.1 github.com/99designs/gqlgen v0.17.45 - github.com/bnb-chain/tss-lib v1.3.5 github.com/btcsuite/btcutil v1.0.2 github.com/bytemare/crypto v0.5.2 github.com/bytemare/frost v0.0.0-20231127024126-bc6f7874b253 @@ -19,16 +18,16 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/ilyakaznacheev/cleanenv v1.5.0 github.com/jackc/pgx/v5 v5.5.5 - github.com/lastingasset/tss-lib v0.0.0-20221022151431-0bdbdcdfba56 github.com/lib/pq v1.10.9 github.com/lmittmann/tint v1.0.4 github.com/mattn/go-colorable v0.1.13 github.com/peterldowns/pgtestdb v0.0.14 - github.com/pkg/errors v0.9.1 github.com/pouya-eghbali/go-sia/v2 v2.1.0 github.com/puzpuzpuz/xsync/v3 v3.1.0 + github.com/redis/go-redis/v9 v9.5.2 github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.9.0 + github.com/taurusgroup/multi-party-sig v0.6.0-alpha-2021-09-21 github.com/vektah/gqlparser/v2 v2.5.11 golang.org/x/crypto v0.21.0 golang.org/x/sync v0.6.0 @@ -45,7 +44,6 @@ require ( github.com/Microsoft/go-winio v0.6.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect github.com/agext/levenshtein v1.2.3 // indirect - github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -56,8 +54,6 @@ require ( github.com/bytemare/hash2curve v0.2.2 // indirect github.com/bytemare/secp256k1 v0.1.0 // indirect github.com/bytemare/secret-sharing v0.1.0 // indirect - github.com/btcsuite/btcd v0.20.1-beta // indirect - github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cockroachdb/errors v1.8.1 // indirect github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f // indirect @@ -69,15 +65,18 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect + github.com/cronokirby/safenum v0.29.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect - github.com/decred/dcrd/dcrec/edwards/v2 v2.0.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/ethereum/c-kzg-4844 v1.0.0 // indirect github.com/fjl/memsize v0.0.2 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fxamacker/cbor/v2 v2.3.0 // indirect github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect github.com/go-ole/go-ole v1.3.0 // indirect @@ -101,7 +100,6 @@ require ( github.com/holiman/uint256 v1.2.4 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/ipfs/go-log v0.0.1 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect @@ -119,8 +117,7 @@ require ( github.com/mitchellh/pointerstructure v1.2.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/opentracing/opentracing-go v1.1.0 // indirect - github.com/otiai10/primes v0.0.0-20180210170552-f6d2a1ba97c4 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.12.0 // indirect github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a // indirect @@ -144,10 +141,11 @@ require ( github.com/urfave/cli/v2 v2.27.1 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc // indirect + github.com/x448/float16 v0.8.4 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zclconf/go-cty v1.14.4 // indirect + github.com/zeebo/blake3 v0.2.0 // indirect go.opencensus.io v0.24.0 // indirect golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 // indirect golang.org/x/mod v0.16.0 // indirect diff --git a/internal/crypto/frost/convert.go b/internal/crypto/frost/convert.go deleted file mode 100644 index 6b6aee8c..00000000 --- a/internal/crypto/frost/convert.go +++ /dev/null @@ -1,158 +0,0 @@ -package frost - -import ( - "encoding/hex" - - "github.com/TimeleapLabs/unchained/internal/consts" - "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/bytemare/crypto" - "github.com/bytemare/frost" - "github.com/bytemare/frost/dkg" -) - -// DecodeCommitment will decode commitment from bytes. -func (s *MessageSigner) DecodeCommitment(data []byte) (*frost.Commitment, error) { - scalarLen := s.participant.Ciphersuite.Group.ScalarLength() - commitment := &frost.Commitment{ - Identifier: s.participant.Ciphersuite.Group.NewScalar(), - HidingNonce: s.participant.Ciphersuite.Group.NewElement(), - BindingNonce: s.participant.Ciphersuite.Group.NewElement(), - } - - err := commitment.Identifier.Decode(data[:scalarLen]) - if err != nil { - utils.Logger.With("err", err, "value", hex.EncodeToString(data[:scalarLen])).Error("cant decode commitment identifier") - return nil, err - } - - err = commitment.HidingNonce.Decode(data[scalarLen : scalarLen*2]) - if err != nil { - utils.Logger.With("err", err, "value", hex.EncodeToString(data[:scalarLen])).Error("cant decode commitment hiding_nonce") - // return nil, err - } - - err = commitment.BindingNonce.Decode(data[scalarLen*2 : scalarLen*3]) - if err != nil { - utils.Logger.With("err", err, "value", hex.EncodeToString(data[:scalarLen])).Error("cant decode commitment binding_nonce") - return nil, err - } - - return commitment, nil -} - -// DecodeSignature will decode signature from bytes. -func (s *MessageSigner) DecodeSignature(data []byte) (*frost.Signature, error) { - signature := frost.Signature{ - R: s.participant.Ciphersuite.Group.NewElement(), - Z: s.participant.Ciphersuite.Group.NewScalar(), - } - err := signature.Decode(s.participant.Ciphersuite.Group, data) - if err != nil { - utils.Logger.With("err", err).Error("cant decode signature") - return &signature, consts.ErrCantDecode - } - - return &signature, nil -} - -func EncodeRoundOneMessage(message *dkg.Round1Data) []byte { - commitment := []byte{} - for _, commit := range message.Commitment { - commitment = append(commitment, commit.Encode()...) - } - - out := []byte{} - out = append(out, message.SenderIdentifier.Encode()...) - out = append(out, message.ProofOfKnowledge.Encode()...) - out = append(out, commitment...) - - return out -} - -func EncodeRoundTwoMessages(message []*dkg.Round2Data) [][]byte { - out := [][]byte{} - - for _, msg := range message { - out = append(out, EncodeRoundTwoMessage(msg)) - } - - return out -} - -func EncodeRoundTwoMessage(message *dkg.Round2Data) []byte { - out := []byte{} - - out = append(out, message.SenderIdentifier.Encode()...) - out = append(out, message.ReceiverIdentifier.Encode()...) - out = append(out, message.SecretShare.Encode()...) - - return out -} - -func (s *DistributedSigner) DecodeRoundTwoMessage(message []byte) (*dkg.Round2Data, error) { - r2Data := &dkg.Round2Data{ - SenderIdentifier: s.config.Ciphersuite.Group.NewScalar(), - ReceiverIdentifier: s.config.Ciphersuite.Group.NewScalar(), - SecretShare: s.config.Ciphersuite.Group.NewScalar(), - } - - err := r2Data.SenderIdentifier.Decode(message[:s.config.Ciphersuite.Group.ScalarLength()]) - if err != nil { - utils.Logger.With("err", err).Error("cant decode sender_identifier") - return nil, err - } - - err = r2Data.ReceiverIdentifier.Decode(message[s.config.Ciphersuite.Group.ScalarLength() : s.config.Ciphersuite.Group.ScalarLength()*2]) - if err != nil { - utils.Logger.With("err", err).Error("cant decode receiver_identifier") - return nil, err - } - - err = r2Data.SecretShare.Decode(message[s.config.Ciphersuite.Group.ScalarLength()*2:]) - if err != nil { - utils.Logger.With("err", err).Error("cant decode secret_share") - return nil, err - } - - return r2Data, nil -} - -func (s *DistributedSigner) DecodeRoundOneMessage(message []byte) (*dkg.Round1Data, error) { - senderBytes := message[:s.config.Ciphersuite.Group.ScalarLength()] - proofBytes := message[s.config.Ciphersuite.Group.ScalarLength() : s.config.Ciphersuite.Group.ScalarLength()+64] - commitmentsBytes := message[s.config.Ciphersuite.Group.ScalarLength()+64:] - - r1Data := &dkg.Round1Data{ - ProofOfKnowledge: frost.Signature{ - R: s.config.Ciphersuite.Group.NewElement(), - Z: s.config.Ciphersuite.Group.NewScalar(), - }, - SenderIdentifier: s.config.Ciphersuite.Group.NewScalar(), - Commitment: []*crypto.Element{}, - } - - for i := 0; i < len(commitmentsBytes); i += s.config.Ciphersuite.Group.ElementLength() { - commitment := s.config.Ciphersuite.Group.NewElement() - err := commitment.Decode(commitmentsBytes[i : i+s.config.Ciphersuite.Group.ElementLength()]) - if err != nil { - utils.Logger.With("err", err).Error("cant decode commitment") - return nil, err - } - - r1Data.Commitment = append(r1Data.Commitment, commitment) - } - - err := r1Data.ProofOfKnowledge.Decode(s.config.Ciphersuite.Group, proofBytes) - if err != nil { - utils.Logger.With("err", err).Error("cant decode proof_of_knowledge") - return nil, err - } - - err = r1Data.SenderIdentifier.Decode(senderBytes) - if err != nil { - utils.Logger.With("err", err).Error("cant decode identifier") - return nil, err - } - - return r1Data, nil -} diff --git a/internal/crypto/frost/identity.go b/internal/crypto/frost/identity.go deleted file mode 100644 index 9502802e..00000000 --- a/internal/crypto/frost/identity.go +++ /dev/null @@ -1,95 +0,0 @@ -package frost - -import ( - "errors" - "github.com/bytemare/crypto" - "github.com/bytemare/frost" - "github.com/bytemare/frost/dkg" -) - -// DistributedSigner represents a Frost identity. -type DistributedSigner struct { - ID *crypto.Scalar - currentParticipant *dkg.Participant - finalParticipant *frost.Participant - accumulatedMessages []*dkg.Round1Data - ackMessages []*dkg.Round2Data - config *frost.Configuration - signerCount int - minSigningCount int -} - -// Update function will update the identity key about other parties. -func (s *DistributedSigner) Update(msg *dkg.Round1Data) ([]*dkg.Round2Data, error) { - s.accumulatedMessages = append(s.accumulatedMessages, msg) - - if len(s.accumulatedMessages) != s.signerCount { - return nil, nil - } - - round2Data, err := s.currentParticipant.Continue(s.accumulatedMessages) - if err != nil { - return nil, err - } - - if len(round2Data) != len(s.accumulatedMessages)-1 { - return nil, errors.New("number of accept messages is not correct") - } - - return round2Data, nil -} - -func (s *DistributedSigner) Finalize(msg *dkg.Round2Data) error { - if msg.ReceiverIdentifier.Equal(s.currentParticipant.Identifier) == 0 { - return nil - } - - s.ackMessages = append(s.ackMessages, msg) - - if len(s.ackMessages) < len(s.accumulatedMessages)-1 { - return nil - } - - // This will, for each participant, return their secret key (which is a share of the global secret signing key), - // the corresponding verification key, and the global public key. - participantsSecretKey, _, groupPublicKeyGeneratedInDKG, err := s.currentParticipant.Finalize( - s.accumulatedMessages, - s.ackMessages, - ) - if err != nil { - return err - } - - s.config.GroupPublicKey = groupPublicKeyGeneratedInDKG - - s.finalParticipant = s.config.Participant(s.ID, participantsSecretKey) - - return nil -} - -// NewIdentity creates a new Frost identity. -func NewIdentity(ID int, signerCount int, minSigningCount int) (*dkg.Round1Data, *DistributedSigner) { - signer := DistributedSigner{ - accumulatedMessages: make([]*dkg.Round1Data, 0, signerCount), - config: frost.Ristretto255.Configuration(), - signerCount: signerCount, - minSigningCount: minSigningCount, - } - - signer.ID = signer.config.IDFromInt(ID) - signer.currentParticipant = dkg.NewParticipant( - signer.config.Ciphersuite, - signer.ID, - signerCount, - minSigningCount, - ) - - round1Data := signer.currentParticipant.Init() - if round1Data.SenderIdentifier.Equal(signer.ID) != 1 { - panic("sender identifier is not correct") - } - - //signer.accumulatedMessages = append(signer.accumulatedMessages, round1Data) - - return round1Data, &signer -} diff --git a/internal/crypto/frost/identity_test.go b/internal/crypto/frost/identity_test.go deleted file mode 100644 index 515a1629..00000000 --- a/internal/crypto/frost/identity_test.go +++ /dev/null @@ -1,94 +0,0 @@ -package frost - -import ( - "testing" - - "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" -) - -const ( - numOfSigners = 10 - minNumOfSigners = 6 -) - -var ( - testData = []byte("HELLO hello") - - signers = []int{} -) - -type FrostIdentityTestSuite struct { - suite.Suite - parties []*DistributedSigner -} - -func (s *FrostIdentityTestSuite) SetupTest() { - utils.SetupLogger("info") - - for i := 0; i < numOfSigners; i++ { - signers = append(signers, i+1) - } - - r1Messages := [][]byte{} - for i := 0; i < numOfSigners; i++ { - r1Msg, party := NewIdentity(signers[i], numOfSigners, minNumOfSigners) - s.parties = append(s.parties, party) - r1Messages = append(r1Messages, r1Msg) - } - - r2Messages := [][]byte{} - for i := 0; i < numOfSigners; i++ { - for j := 0; j < numOfSigners; j++ { - r2Msgs, err := s.parties[i].Update(r1Messages[j]) - assert.NoError(s.T(), err) - - r2Messages = append(r2Messages, r2Msgs...) - } - } - - for k := 0; k < numOfSigners; k++ { - for _, msg := range r2Messages { - err := s.parties[k].Finalize(msg) - assert.NoError(s.T(), err) - } - } -} - -func (s *FrostIdentityTestSuite) TestSign() { - signers := make([]*MessageSigner, 0, minNumOfSigners) - commits := [][]byte{} - - for i := 0; i < minNumOfSigners; i++ { - signer, msg, err := s.parties[i].NewSigner(testData) - assert.NoError(s.T(), err) - - commits = append(commits, msg) - signers = append(signers, signer) - } - - signatureShares := make([][]byte, 0, minNumOfSigners) - - for _, signer := range signers { - for _, commit := range commits { - signature, err := signer.Confirm(commit) - assert.NoError(s.T(), err) - - if signature != nil { - signatureShares = append(signatureShares, signature) - } - } - } - - signature, err := signers[0].Aggregate(signatureShares) - assert.NoError(s.T(), err) - - ok, err := signers[0].Verify(signature) - assert.NoError(s.T(), err) - assert.True(s.T(), ok) -} - -func TestFrostIdentitySuite(t *testing.T) { - suite.Run(t, new(FrostIdentityTestSuite)) -} diff --git a/internal/crypto/frost/signer.go b/internal/crypto/frost/signer.go deleted file mode 100644 index 7548b3f5..00000000 --- a/internal/crypto/frost/signer.go +++ /dev/null @@ -1,107 +0,0 @@ -package frost - -import ( - "errors" - - "github.com/TimeleapLabs/unchained/internal/consts" - "github.com/TimeleapLabs/unchained/internal/utils" - "github.com/bytemare/frost" -) - -// MessageSigner represents state of signing of a message. -type MessageSigner struct { - partySize int - data []byte - commitments frost.CommitmentList - participant *frost.Participant - commitment *frost.Commitment -} - -// Confirm function will set other parties confirms. -func (s *MessageSigner) Confirm(commitmentBytes []byte) ([]byte, error) { - commitment, err := s.DecodeCommitment(commitmentBytes) - if err != nil { - utils.Logger.With("err", err).Error("cant decode commitment") - return nil, consts.ErrCantDecode - } - - s.commitments = append(s.commitments, commitment) - - if len(s.commitments.Participants()) < s.partySize { - return nil, nil - } - - signatureShare, err := s.participant.Sign(s.data, s.commitments) - if err != nil { - utils.Logger.With("err", err).Error("cant sign message") - return nil, consts.ErrCantSign - } - - if !s.participant.VerifySignatureShare( - s.commitment, - s.participant.PublicKey, - signatureShare.SignatureShare, - s.commitments, - s.data, - ) { - return nil, consts.ErrCantVerify - } - - return signatureShare.Encode(), nil -} - -// Aggregate function will generate final signature by combining parties signature shares. -func (s *MessageSigner) Aggregate(signatureSharesBytes [][]byte) ([]byte, error) { - signatureShares := []*frost.SignatureShare{} - - for _, signatureShareBytes := range signatureSharesBytes { - signatureShare, err := frost.Ristretto255.Configuration().DecodeSignatureShare(signatureShareBytes) - if err != nil { - utils.Logger.With("err", err).Error("cant decode signature share") - return nil, consts.ErrCantDecode - } - - signatureShares = append(signatureShares, signatureShare) - } - - signature := s.participant.Aggregate(s.commitments, s.data, signatureShares) - - return signature.Encode(), nil -} - -// Verify function will verify the signature. -func (s *MessageSigner) Verify(signatureBytes []byte) (bool, error) { - signature, err := s.DecodeSignature(signatureBytes) - if err != nil { - return false, err - } - - return frost.Verify( - frost.Ristretto255.Configuration().Ciphersuite, - s.data, - signature, - s.participant.GroupPublicKey, - ), nil -} - -// NewSigner create a new signing state for a message. -func (s *DistributedSigner) NewSigner(data []byte) (*MessageSigner, []byte, error) { - if s.finalParticipant == nil { - return nil, nil, consts.ErrSignerIsNotReady - } - - commitment := s.finalParticipant.Commit() - if commitment.Identifier.Equal(s.finalParticipant.KeyShare.Identifier) != 1 { - return nil, nil, errors.New("identifier is not correct") - } - - signer := &MessageSigner{ - partySize: s.minSigningCount, - data: data, - commitments: make(frost.CommitmentList, 0, s.signerCount), - participant: s.finalParticipant, - commitment: commitment, - } - - return signer, commitment.Encode(), nil -} From d0e23aede94a855cb2f6ec5410768f6c6ada1e6d Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Sat, 8 Jun 2024 19:11:40 +0330 Subject: [PATCH 25/29] =?UTF-8?q?=E2=9C=A8=20feat(consumer-schedule):=20sp?= =?UTF-8?q?lit=20consumer=20to=20create=20schnorr=20consumer=20and=20add?= =?UTF-8?q?=20heartbeat=20task=20>>>=20=E2=8F=B0=204h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/handler/consumer.go | 56 ++++++++++++++++++- internal/app/consumer.go | 53 ++++++++++++------ internal/config/model.go | 5 +- internal/consts/opcodes.go | 1 + internal/scheduler/frost.go | 19 +++++++ internal/scheduler/scheduler.go | 1 + internal/service/frost/frost.go | 5 +- internal/service/frost/sync.go | 1 + .../transport/client/handler/challenge.go | 16 +++++- internal/transport/client/handler/consumer.go | 19 ++++++- .../transport/client/handler/correctness.go | 4 +- internal/transport/client/handler/event.go | 4 +- internal/transport/client/handler/frost.go | 7 ++- internal/transport/client/handler/price.go | 4 +- internal/transport/client/store/native.go | 5 ++ 15 files changed, 167 insertions(+), 33 deletions(-) diff --git a/cmd/handler/consumer.go b/cmd/handler/consumer.go index b62e0444..852f03f1 100644 --- a/cmd/handler/consumer.go +++ b/cmd/handler/consumer.go @@ -17,6 +17,40 @@ var consumer = &cobra.Command{ config.App.Network.BrokerURI = cmd.Flags().Lookup("broker").Value.String() config.App.Network.Bind = cmd.Flags().Lookup("graphql").Value.String() }, +} + +// postgresConsumer represents the consumer command which is run in Postgres Mode. +var postgresConsumer = &cobra.Command{ + Use: "consumer", + Short: "Run the Unchained client for handling postgres in consumer mode", + Long: `Run the Unchained client for handling postgres in consumer mode`, + + PreRun: func(cmd *cobra.Command, _ []string) { + config.App.Network.BrokerURI = cmd.Flags().Lookup("broker").Value.String() + config.App.Network.Bind = cmd.Flags().Lookup("graphql").Value.String() + }, + + Run: func(_ *cobra.Command, _ []string) { + err := config.Load(config.App.System.ConfigPath, config.App.System.SecretsPath) + if err != nil { + panic(err) + } + + utils.SetupLogger(config.App.System.Log) + app.Consumer(app.PostgresConsumer) + }, +} + +// schnorrConsumer represents the consumer command which is run in Schnorr Mode. +var schnorrConsumer = &cobra.Command{ + Use: "schnorr", + Short: "Run the Unchained client for handling schnorr in consumer mode", + Long: `Run the Unchained client for handling schnorr in consumer mode`, + + PreRun: func(cmd *cobra.Command, _ []string) { + config.App.Network.BrokerURI = cmd.Flags().Lookup("broker").Value.String() + config.App.Network.Bind = cmd.Flags().Lookup("graphql").Value.String() + }, Run: func(_ *cobra.Command, _ []string) { err := config.Load(config.App.System.ConfigPath, config.App.System.SecretsPath) @@ -25,25 +59,41 @@ var consumer = &cobra.Command{ } utils.SetupLogger(config.App.System.Log) - app.Consumer() + app.Consumer(app.SchnorrConsumer) }, } // WithConsumerCmd append command of consumer to the root command. func WithConsumerCmd(cmd *cobra.Command) { cmd.AddCommand(consumer) + consumer.AddCommand(postgresConsumer) + consumer.AddCommand(schnorrConsumer) } // init loads CLI flags of consumer command. func init() { - consumer.Flags().StringP( + postgresConsumer.Flags().StringP( + "broker", + "b", + "wss://shinobi.brokers.kenshi.io", + "Unchained broker to connect to", + ) + + postgresConsumer.Flags().StringP( + "graphql", + "g", + "127.0.0.1:8080", + "The graphql server path to bind", + ) + + schnorrConsumer.Flags().StringP( "broker", "b", "wss://shinobi.brokers.kenshi.io", "Unchained broker to connect to", ) - consumer.Flags().StringP( + schnorrConsumer.Flags().StringP( "graphql", "g", "127.0.0.1:8080", diff --git a/internal/app/consumer.go b/internal/app/consumer.go index 726a798d..a2c2cada 100644 --- a/internal/app/consumer.go +++ b/internal/app/consumer.go @@ -12,14 +12,22 @@ import ( "github.com/TimeleapLabs/unchained/internal/transport/client" "github.com/TimeleapLabs/unchained/internal/transport/client/conn" "github.com/TimeleapLabs/unchained/internal/transport/client/handler" + "github.com/TimeleapLabs/unchained/internal/transport/client/store" "github.com/TimeleapLabs/unchained/internal/transport/database/postgres" "github.com/TimeleapLabs/unchained/internal/transport/server" "github.com/TimeleapLabs/unchained/internal/transport/server/gql" "github.com/TimeleapLabs/unchained/internal/utils" ) +type JobType string + +const ( + PostgresConsumer JobType = "postgres" + SchnorrConsumer JobType = "schnorr" +) + // Consumer starts the Unchained consumer and contains its DI. -func Consumer() { +func Consumer(jobType JobType) { utils.Logger. With("Mode", "Consumer"). With("Version", consts.Version). @@ -31,25 +39,36 @@ func Consumer() { crypto.WithBlsIdentity(), ) - ethRPC := ethereum.New() - pos := pos.New(ethRPC) - db := postgres.New() + if jobType == PostgresConsumer { + ethRPC := ethereum.New() + pos := pos.New(ethRPC) + db := postgres.New() - eventLogRepo := postgresRepo.NewEventLog(db) - signerRepo := postgresRepo.NewSigner(db) - assetPrice := postgresRepo.NewAssetPrice(db) - correctnessRepo := postgresRepo.NewCorrectness(db) + eventLogRepo := postgresRepo.NewEventLog(db) + signerRepo := postgresRepo.NewSigner(db) + assetPrice := postgresRepo.NewAssetPrice(db) + correctnessRepo := postgresRepo.NewCorrectness(db) - correctnessService := correctnessService.New(pos, signerRepo, correctnessRepo) - evmLogService := evmlogService.New(ethRPC, pos, eventLogRepo, signerRepo, nil) - uniswapService := uniswapService.New(ethRPC, pos, signerRepo, assetPrice) + correctnessService := correctnessService.New(pos, signerRepo, correctnessRepo) + evmLogService := evmlogService.New(ethRPC, pos, eventLogRepo, signerRepo, nil) + uniswapService := uniswapService.New(ethRPC, pos, signerRepo, assetPrice) - conn.Start() + conn.Start() - handler := handler.NewConsumerHandler(correctnessService, uniswapService, evmLogService) - client.NewRPC(handler) + handler := handler.NewPostgresConsumerHandler(correctnessService, uniswapService, evmLogService) + client.NewRPC(handler) - server.New( - gql.WithGraphQL(db), - ) + server.New( + gql.WithGraphQL(db), + ) + } else { + signerRepo := store.New() + + conn.Start() + + handler := handler.NewSchnorrConsumerHandler(signerRepo) + client.NewRPC(handler) + + select {} + } } diff --git a/internal/config/model.go b/internal/config/model.go index fb1a4a19..9957f4ad 100644 --- a/internal/config/model.go +++ b/internal/config/model.go @@ -36,8 +36,9 @@ type EthLog struct { // Frost struct represent all task detail of its plugin. type Frost struct { - Schedule time.Duration `yaml:"schedule"` - Session string `yaml:"session"` + Schedule time.Duration `yaml:"schedule"` + Heartbeat time.Duration `yaml:"heartbeat"` + Session string `yaml:"session"` } // Plugins struct holds all applications plugin configs. diff --git a/internal/consts/opcodes.go b/internal/consts/opcodes.go index cbe21afb..00b13589 100644 --- a/internal/consts/opcodes.go +++ b/internal/consts/opcodes.go @@ -26,4 +26,5 @@ const ( OpCodeFrostSignerHandshake OpCode = 12 OpcodeFrostSignerIsReady OpCode = 13 + OpCodeFrostSignerHeartBeat OpCode = 14 ) diff --git a/internal/scheduler/frost.go b/internal/scheduler/frost.go index 16bc056c..e8284b6a 100644 --- a/internal/scheduler/frost.go +++ b/internal/scheduler/frost.go @@ -3,6 +3,10 @@ package scheduler import ( "context" + "github.com/TimeleapLabs/unchained/internal/consts" + "github.com/TimeleapLabs/unchained/internal/crypto" + "github.com/TimeleapLabs/unchained/internal/transport/client/conn" + "github.com/TimeleapLabs/unchained/internal/service/frost" "github.com/TimeleapLabs/unchained/internal/utils" ) @@ -12,6 +16,9 @@ type FrostSync struct { frostService frost.Service } +type FrostReadiness struct { +} + // Run will trigger by the scheduler and process the Frost sync. func (e *FrostSync) Run() { utils.Logger.Info("Start synchronizing frost signers") @@ -22,6 +29,11 @@ func (e *FrostSync) Run() { } } +// RunHeartbeatSender will trigger by the scheduler and send heartbeat to show workers readiness. +func (e *FrostReadiness) Run() { + conn.SendMessage(consts.OpCodeFrostSignerHeartBeat, crypto.Identity.ExportEvmSigner().EvmAddress) +} + // NewFrostSync will create a new FrostSync task. func NewFrostSync(frostService frost.Service) *FrostSync { e := FrostSync{ @@ -30,3 +42,10 @@ func NewFrostSync(frostService frost.Service) *FrostSync { return &e } + +// NewFrostReadiness will create a new FrostReadiness task. +func NewFrostReadiness() *FrostReadiness { + e := FrostReadiness{} + + return &e +} diff --git a/internal/scheduler/scheduler.go b/internal/scheduler/scheduler.go index d4f771a9..fd7a34ff 100644 --- a/internal/scheduler/scheduler.go +++ b/internal/scheduler/scheduler.go @@ -75,6 +75,7 @@ func WithFrostEvents(frostService frost.Service) func(s *Scheduler) { return } s.AddTask(config.App.Plugins.Frost.Schedule, NewFrostSync(frostService)) + s.AddTask(config.App.Plugins.Frost.Schedule, NewFrostReadiness()) } } diff --git a/internal/service/frost/frost.go b/internal/service/frost/frost.go index 91b6223d..ecdb271a 100644 --- a/internal/service/frost/frost.go +++ b/internal/service/frost/frost.go @@ -3,6 +3,8 @@ package frost import ( "context" + "github.com/ethereum/go-ethereum/common" + "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/crypto" "github.com/TimeleapLabs/unchained/internal/service/pos" @@ -18,8 +20,7 @@ type Service interface { type service struct { pos pos.Service - // reserveSigners []bool - // currentSigners []bool + currentSigners []common.Address } func (s *service) ConfirmHandshake(_ context.Context, message []byte) error { diff --git a/internal/service/frost/sync.go b/internal/service/frost/sync.go index b9ade132..e68585ab 100644 --- a/internal/service/frost/sync.go +++ b/internal/service/frost/sync.go @@ -22,6 +22,7 @@ func (s *service) SyncSigners(ctx context.Context) error { } minSignerCount := (len(addresses) / 2) + 1 + s.currentSigners = addresses var handshakeMessageCh <-chan *protocol.Message crypto.Identity.Frost, handshakeMessageCh = multisig.NewIdentity( diff --git a/internal/transport/client/handler/challenge.go b/internal/transport/client/handler/challenge.go index ec41609e..c222ca3f 100644 --- a/internal/transport/client/handler/challenge.go +++ b/internal/transport/client/handler/challenge.go @@ -6,7 +6,21 @@ import ( "github.com/TimeleapLabs/unchained/internal/utils" ) -func (h *consumer) Challenge(message []byte) []byte { +func (h *postgresConsumer) Challenge(message []byte) []byte { + challenge := new(model.ChallengePacket).FromBytes(message) + + signature, err := crypto.Identity.Bls.Sign(challenge.Random[:]) + if err != nil { + utils.Logger.Error(err.Error()) + return nil + } + + challenge.Signature = [48]byte(signature) + + return challenge.Sia().Bytes() +} + +func (h *schnorrConsumer) Challenge(message []byte) []byte { challenge := new(model.ChallengePacket).FromBytes(message) signature, err := crypto.Identity.Bls.Sign(challenge.Random[:]) diff --git a/internal/transport/client/handler/consumer.go b/internal/transport/client/handler/consumer.go index abf6aef0..31880760 100644 --- a/internal/transport/client/handler/consumer.go +++ b/internal/transport/client/handler/consumer.go @@ -7,22 +7,35 @@ import ( "github.com/TimeleapLabs/unchained/internal/service/evmlog" "github.com/TimeleapLabs/unchained/internal/service/uniswap" "github.com/TimeleapLabs/unchained/internal/transport/client/conn" + "github.com/TimeleapLabs/unchained/internal/transport/client/store" ) -type consumer struct { +type postgresConsumer struct { correctness correctness.Service uniswap uniswap.Service evmlog evmlog.Service } -func NewConsumerHandler( +type schnorrConsumer struct { + signerRepository store.SignerRepository +} + +func NewSchnorrConsumerHandler( + signerRepository store.SignerRepository, +) Handler { + return &schnorrConsumer{ + signerRepository: signerRepository, + } +} + +func NewPostgresConsumerHandler( correctness correctness.Service, uniswap uniswap.Service, evmlog evmlog.Service, ) Handler { conn.Send(consts.OpCodeRegisterConsumer, []byte(config.App.Network.SubscribedChannel)) - return &consumer{ + return &postgresConsumer{ correctness: correctness, uniswap: uniswap, evmlog: evmlog, diff --git a/internal/transport/client/handler/correctness.go b/internal/transport/client/handler/correctness.go index 7cfdf6b0..525a1056 100644 --- a/internal/transport/client/handler/correctness.go +++ b/internal/transport/client/handler/correctness.go @@ -6,7 +6,7 @@ import ( "github.com/TimeleapLabs/unchained/internal/model" ) -func (h *consumer) CorrectnessReport(ctx context.Context, message []byte) { +func (h *postgresConsumer) CorrectnessReport(ctx context.Context, message []byte) { packet := new(model.BroadcastCorrectnessPacket).FromBytes(message) correctnessHash, err := packet.Info.Bls() @@ -27,4 +27,6 @@ func (h *consumer) CorrectnessReport(ctx context.Context, message []byte) { } } +func (h *schnorrConsumer) CorrectnessReport(_ context.Context, _ []byte) {} + func (w worker) CorrectnessReport(_ context.Context, _ []byte) {} diff --git a/internal/transport/client/handler/event.go b/internal/transport/client/handler/event.go index a397f637..16be34a4 100644 --- a/internal/transport/client/handler/event.go +++ b/internal/transport/client/handler/event.go @@ -6,7 +6,7 @@ import ( "github.com/TimeleapLabs/unchained/internal/model" ) -func (h *consumer) EventLog(ctx context.Context, message []byte) { +func (h *postgresConsumer) EventLog(ctx context.Context, message []byte) { packet := new(model.BroadcastEventPacket).FromBytes(message) eventLogHash, err := packet.Info.Bls() @@ -28,4 +28,6 @@ func (h *consumer) EventLog(ctx context.Context, message []byte) { } } +func (h *schnorrConsumer) EventLog(_ context.Context, _ []byte) {} + func (w worker) EventLog(_ context.Context, _ []byte) {} diff --git a/internal/transport/client/handler/frost.go b/internal/transport/client/handler/frost.go index b6145c37..0c915de8 100644 --- a/internal/transport/client/handler/frost.go +++ b/internal/transport/client/handler/frost.go @@ -4,7 +4,8 @@ import ( "context" ) -func (h *consumer) ConfirmFrostHandshake(_ context.Context, _ []byte) {} +func (h *postgresConsumer) ConfirmFrostHandshake(_ context.Context, _ []byte) {} +func (h *schnorrConsumer) ConfirmFrostHandshake(_ context.Context, _ []byte) {} func (w worker) ConfirmFrostHandshake(ctx context.Context, message []byte) { err := w.frostService.ConfirmHandshake(ctx, message) @@ -13,8 +14,10 @@ func (w worker) ConfirmFrostHandshake(ctx context.Context, message []byte) { } } -func (h *consumer) StoreOnlineFrostParty(_ context.Context, _ []byte) { +func (h *postgresConsumer) StoreOnlineFrostParty(_ context.Context, _ []byte) {} +func (h *schnorrConsumer) StoreOnlineFrostParty(_ context.Context, evmAddressBytes []byte) { + h.signerRepository.SetSignerIsAlive(string(evmAddressBytes)) } func (w worker) StoreOnlineFrostParty(_ context.Context, _ []byte) {} diff --git a/internal/transport/client/handler/price.go b/internal/transport/client/handler/price.go index 535e4603..a5eea832 100644 --- a/internal/transport/client/handler/price.go +++ b/internal/transport/client/handler/price.go @@ -6,7 +6,7 @@ import ( "github.com/TimeleapLabs/unchained/internal/model" ) -func (h *consumer) PriceReport(ctx context.Context, message []byte) { +func (h *postgresConsumer) PriceReport(ctx context.Context, message []byte) { packet := new(model.BroadcastPricePacket).FromBytes(message) priceInfoHash, err := packet.Info.Bls() @@ -28,4 +28,6 @@ func (h *consumer) PriceReport(ctx context.Context, message []byte) { } } +func (h *schnorrConsumer) PriceReport(_ context.Context, _ []byte) {} + func (w worker) PriceReport(_ context.Context, _ []byte) {} diff --git a/internal/transport/client/store/native.go b/internal/transport/client/store/native.go index 9e41b4c4..da422489 100644 --- a/internal/transport/client/store/native.go +++ b/internal/transport/client/store/native.go @@ -7,12 +7,17 @@ import ( ) type SignerRepository interface { + SetSignerIsAlive(evmAddress string) } type NativeStore struct { signers *xsync.MapOf[string, time.Time] } +func (n NativeStore) SetSignerIsAlive(evmAddress string) { + n.signers.Store(evmAddress, time.Now()) +} + func New() SignerRepository { return &NativeStore{ signers: xsync.NewMapOf[string, time.Time](), From 75f94d8afa01d74654c896dc9b2a0482694e6e36 Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Sat, 8 Jun 2024 19:12:17 +0330 Subject: [PATCH 26/29] =?UTF-8?q?=F0=9F=90=9B=20fix(heartbeat):=20add=20an?= =?UTF-8?q?other=20configuration=20to=20set=20heartbeat=20period=20>>>=20?= =?UTF-8?q?=E2=8F=B0=205m?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/scheduler/scheduler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/scheduler/scheduler.go b/internal/scheduler/scheduler.go index fd7a34ff..da27a9ea 100644 --- a/internal/scheduler/scheduler.go +++ b/internal/scheduler/scheduler.go @@ -75,7 +75,7 @@ func WithFrostEvents(frostService frost.Service) func(s *Scheduler) { return } s.AddTask(config.App.Plugins.Frost.Schedule, NewFrostSync(frostService)) - s.AddTask(config.App.Plugins.Frost.Schedule, NewFrostReadiness()) + s.AddTask(config.App.Plugins.Frost.Heartbeat, NewFrostReadiness()) } } From fa28ac0648b9407986d788d77befda8fe3783049 Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Tue, 11 Jun 2024 19:32:27 +0330 Subject: [PATCH 27/29] =?UTF-8?q?=E2=9C=A8=20feat(frost):=20implement=20dk?= =?UTF-8?q?g=20process=20>>>=20=E2=8F=B0=204h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/handler/consumer.go | 56 +------------ internal/app/broker.go | 19 +++-- internal/app/consumer.go | 56 +++++-------- internal/app/worker.go | 4 +- internal/consts/channels.go | 2 +- internal/consts/opcodes.go | 1 + internal/scheduler/frost.go | 10 ++- internal/scheduler/scheduler.go | 14 +++- internal/service/frost/frost.go | 3 +- internal/service/frost/helper.go | 23 +++++ internal/service/frost/helper_test.go | 84 +++++++++++++++++++ internal/service/frost/sync.go | 33 +++++++- internal/service/pos/pos_mock.go | 12 +++ internal/service/pos/pos_test.go | 27 +++--- internal/transport/client/client.go | 5 +- .../transport/client/handler/challenge.go | 18 +--- internal/transport/client/handler/consumer.go | 43 ---------- .../transport/client/handler/correctness.go | 6 +- internal/transport/client/handler/event.go | 6 +- internal/transport/client/handler/frost.go | 25 ++++-- internal/transport/client/handler/handler.go | 41 ++++++++- internal/transport/client/handler/price.go | 6 +- internal/transport/client/handler/worker.go | 13 --- internal/transport/client/store/native.go | 25 ------ .../server/websocket/handler/hello.go | 1 + .../server/websocket/handler/helper.go | 2 +- .../transport/server/websocket/store/store.go | 2 + .../transport/server/websocket/websocket.go | 7 +- 28 files changed, 301 insertions(+), 243 deletions(-) create mode 100644 internal/service/frost/helper.go create mode 100644 internal/service/frost/helper_test.go delete mode 100644 internal/transport/client/handler/consumer.go delete mode 100644 internal/transport/client/handler/worker.go delete mode 100644 internal/transport/client/store/native.go diff --git a/cmd/handler/consumer.go b/cmd/handler/consumer.go index 852f03f1..b62e0444 100644 --- a/cmd/handler/consumer.go +++ b/cmd/handler/consumer.go @@ -17,40 +17,6 @@ var consumer = &cobra.Command{ config.App.Network.BrokerURI = cmd.Flags().Lookup("broker").Value.String() config.App.Network.Bind = cmd.Flags().Lookup("graphql").Value.String() }, -} - -// postgresConsumer represents the consumer command which is run in Postgres Mode. -var postgresConsumer = &cobra.Command{ - Use: "consumer", - Short: "Run the Unchained client for handling postgres in consumer mode", - Long: `Run the Unchained client for handling postgres in consumer mode`, - - PreRun: func(cmd *cobra.Command, _ []string) { - config.App.Network.BrokerURI = cmd.Flags().Lookup("broker").Value.String() - config.App.Network.Bind = cmd.Flags().Lookup("graphql").Value.String() - }, - - Run: func(_ *cobra.Command, _ []string) { - err := config.Load(config.App.System.ConfigPath, config.App.System.SecretsPath) - if err != nil { - panic(err) - } - - utils.SetupLogger(config.App.System.Log) - app.Consumer(app.PostgresConsumer) - }, -} - -// schnorrConsumer represents the consumer command which is run in Schnorr Mode. -var schnorrConsumer = &cobra.Command{ - Use: "schnorr", - Short: "Run the Unchained client for handling schnorr in consumer mode", - Long: `Run the Unchained client for handling schnorr in consumer mode`, - - PreRun: func(cmd *cobra.Command, _ []string) { - config.App.Network.BrokerURI = cmd.Flags().Lookup("broker").Value.String() - config.App.Network.Bind = cmd.Flags().Lookup("graphql").Value.String() - }, Run: func(_ *cobra.Command, _ []string) { err := config.Load(config.App.System.ConfigPath, config.App.System.SecretsPath) @@ -59,41 +25,25 @@ var schnorrConsumer = &cobra.Command{ } utils.SetupLogger(config.App.System.Log) - app.Consumer(app.SchnorrConsumer) + app.Consumer() }, } // WithConsumerCmd append command of consumer to the root command. func WithConsumerCmd(cmd *cobra.Command) { cmd.AddCommand(consumer) - consumer.AddCommand(postgresConsumer) - consumer.AddCommand(schnorrConsumer) } // init loads CLI flags of consumer command. func init() { - postgresConsumer.Flags().StringP( - "broker", - "b", - "wss://shinobi.brokers.kenshi.io", - "Unchained broker to connect to", - ) - - postgresConsumer.Flags().StringP( - "graphql", - "g", - "127.0.0.1:8080", - "The graphql server path to bind", - ) - - schnorrConsumer.Flags().StringP( + consumer.Flags().StringP( "broker", "b", "wss://shinobi.brokers.kenshi.io", "Unchained broker to connect to", ) - schnorrConsumer.Flags().StringP( + consumer.Flags().StringP( "graphql", "g", "127.0.0.1:8080", diff --git a/internal/app/broker.go b/internal/app/broker.go index 6d09e510..61cff02a 100644 --- a/internal/app/broker.go +++ b/internal/app/broker.go @@ -4,8 +4,9 @@ import ( "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/crypto" "github.com/TimeleapLabs/unchained/internal/crypto/ethereum" + "github.com/TimeleapLabs/unchained/internal/scheduler" + "github.com/TimeleapLabs/unchained/internal/service/frost" "github.com/TimeleapLabs/unchained/internal/service/pos" - "github.com/TimeleapLabs/unchained/internal/transport/database/redis" "github.com/TimeleapLabs/unchained/internal/transport/server" "github.com/TimeleapLabs/unchained/internal/transport/server/websocket" "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/store" @@ -26,14 +27,22 @@ func Broker() { ) ethRPC := ethereum.New() - pos.New(ethRPC) + pos := pos.New(ethRPC) - redisIns := redis.New() + //redisIns := redis.New() nativeSignerRepo := store.New() - redisSignerRepo := store.NewRedisStore(redisIns, nativeSignerRepo) + //redisSignerRepo := store.NewRedisStore(redisIns, nativeSignerRepo) + + frostService := frost.New(pos) + + scheduler := scheduler.New( + scheduler.WithFrostEvents(frostService), + ) + + scheduler.Start(false) server.New( - websocket.WithWebsocket(redisSignerRepo), + websocket.WithWebsocket(nativeSignerRepo), ) } diff --git a/internal/app/consumer.go b/internal/app/consumer.go index a2c2cada..106d149a 100644 --- a/internal/app/consumer.go +++ b/internal/app/consumer.go @@ -12,22 +12,14 @@ import ( "github.com/TimeleapLabs/unchained/internal/transport/client" "github.com/TimeleapLabs/unchained/internal/transport/client/conn" "github.com/TimeleapLabs/unchained/internal/transport/client/handler" - "github.com/TimeleapLabs/unchained/internal/transport/client/store" "github.com/TimeleapLabs/unchained/internal/transport/database/postgres" "github.com/TimeleapLabs/unchained/internal/transport/server" "github.com/TimeleapLabs/unchained/internal/transport/server/gql" "github.com/TimeleapLabs/unchained/internal/utils" ) -type JobType string - -const ( - PostgresConsumer JobType = "postgres" - SchnorrConsumer JobType = "schnorr" -) - // Consumer starts the Unchained consumer and contains its DI. -func Consumer(jobType JobType) { +func Consumer() { utils.Logger. With("Mode", "Consumer"). With("Version", consts.Version). @@ -39,36 +31,34 @@ func Consumer(jobType JobType) { crypto.WithBlsIdentity(), ) - if jobType == PostgresConsumer { - ethRPC := ethereum.New() - pos := pos.New(ethRPC) - db := postgres.New() + ethRPC := ethereum.New() + pos := pos.New(ethRPC) + db := postgres.New() - eventLogRepo := postgresRepo.NewEventLog(db) - signerRepo := postgresRepo.NewSigner(db) - assetPrice := postgresRepo.NewAssetPrice(db) - correctnessRepo := postgresRepo.NewCorrectness(db) + eventLogRepo := postgresRepo.NewEventLog(db) + signerRepo := postgresRepo.NewSigner(db) + assetPrice := postgresRepo.NewAssetPrice(db) + correctnessRepo := postgresRepo.NewCorrectness(db) - correctnessService := correctnessService.New(pos, signerRepo, correctnessRepo) - evmLogService := evmlogService.New(ethRPC, pos, eventLogRepo, signerRepo, nil) - uniswapService := uniswapService.New(ethRPC, pos, signerRepo, assetPrice) + correctnessService := correctnessService.New(pos, signerRepo, correctnessRepo) + evmLogService := evmlogService.New(ethRPC, pos, eventLogRepo, signerRepo, nil) + uniswapService := uniswapService.New(ethRPC, pos, signerRepo, assetPrice) - conn.Start() + conn.Start() - handler := handler.NewPostgresConsumerHandler(correctnessService, uniswapService, evmLogService) - client.NewRPC(handler) + client.NewRPC( + handler.NewConsumerHandler(correctnessService, uniswapService, evmLogService), + ) - server.New( - gql.WithGraphQL(db), - ) - } else { - signerRepo := store.New() + server.New( + gql.WithGraphQL(db), + ) - conn.Start() + //signerRepo := store.New() - handler := handler.NewSchnorrConsumerHandler(signerRepo) - client.NewRPC(handler) + //client.NewRPC( + // handler.NewSchnorrConsumerHandler(signerRepo), + //) + // - select {} - } } diff --git a/internal/app/worker.go b/internal/app/worker.go index b1b3545f..e5d1974d 100644 --- a/internal/app/worker.go +++ b/internal/app/worker.go @@ -46,7 +46,7 @@ func Worker() { scheduler := scheduler.New( scheduler.WithEthLogs(evmLogService), scheduler.WithUniswapEvents(uniswapService), - scheduler.WithFrostEvents(frostService), + scheduler.WithFrostHeartbeat(), ) conn.Start() @@ -54,5 +54,5 @@ func Worker() { handler := handler.NewWorkerHandler(frostService) client.NewRPC(handler) - scheduler.Start() + scheduler.Start(true) } diff --git a/internal/consts/channels.go b/internal/consts/channels.go index 81ba7ad0..76ce28d3 100644 --- a/internal/consts/channels.go +++ b/internal/consts/channels.go @@ -7,5 +7,5 @@ const ( ChannelPriceReport Channels = "unchained:price_report" ChannelEventLog Channels = "unchained:event_log" ChannelCorrectnessReport Channels = "unchained:correctness_report" - ChannelFrostSigner Channels = "unchained:frost:handshake" + ChannelFrostSigner Channels = "unchained:frost" ) diff --git a/internal/consts/opcodes.go b/internal/consts/opcodes.go index 00b13589..a6c2864e 100644 --- a/internal/consts/opcodes.go +++ b/internal/consts/opcodes.go @@ -27,4 +27,5 @@ const ( OpCodeFrostSignerHandshake OpCode = 12 OpcodeFrostSignerIsReady OpCode = 13 OpCodeFrostSignerHeartBeat OpCode = 14 + OpcodeFrostSignerOnlines OpCode = 15 ) diff --git a/internal/scheduler/frost.go b/internal/scheduler/frost.go index e8284b6a..bfbb50a7 100644 --- a/internal/scheduler/frost.go +++ b/internal/scheduler/frost.go @@ -8,7 +8,6 @@ import ( "github.com/TimeleapLabs/unchained/internal/transport/client/conn" "github.com/TimeleapLabs/unchained/internal/service/frost" - "github.com/TimeleapLabs/unchained/internal/utils" ) // FrostSync is a scheduler for syncing signer of Frost and keep task's dependencies. @@ -21,16 +20,19 @@ type FrostReadiness struct { // Run will trigger by the scheduler and process the Frost sync. func (e *FrostSync) Run() { - utils.Logger.Info("Start synchronizing frost signers") ctx := context.TODO() - err := e.frostService.SyncSigners(ctx) + err := e.frostService.SendOnlineSigners(ctx) if err != nil { panic(err) } } -// RunHeartbeatSender will trigger by the scheduler and send heartbeat to show workers readiness. +// Run will trigger by the scheduler and send heartbeat to show workers readiness. func (e *FrostReadiness) Run() { + if conn.IsClosed { + return + } + conn.SendMessage(consts.OpCodeFrostSignerHeartBeat, crypto.Identity.ExportEvmSigner().EvmAddress) } diff --git a/internal/scheduler/scheduler.go b/internal/scheduler/scheduler.go index da27a9ea..f1c412c5 100644 --- a/internal/scheduler/scheduler.go +++ b/internal/scheduler/scheduler.go @@ -75,6 +75,14 @@ func WithFrostEvents(frostService frost.Service) func(s *Scheduler) { return } s.AddTask(config.App.Plugins.Frost.Schedule, NewFrostSync(frostService)) + } +} + +func WithFrostHeartbeat() func(s *Scheduler) { + return func(s *Scheduler) { + if config.App.Plugins.Frost == nil { + return + } s.AddTask(config.App.Plugins.Frost.Heartbeat, NewFrostReadiness()) } } @@ -97,8 +105,10 @@ func (s *Scheduler) AddTask(duration time.Duration, task Task) { } // Start starts the scheduler. -func (s *Scheduler) Start() { +func (s *Scheduler) Start(block bool) { s.scheduler.Start() - select {} + if block { + select {} + } } diff --git a/internal/service/frost/frost.go b/internal/service/frost/frost.go index ecdb271a..5134206f 100644 --- a/internal/service/frost/frost.go +++ b/internal/service/frost/frost.go @@ -13,7 +13,8 @@ import ( ) type Service interface { - SyncSigners(ctx context.Context) error + SendOnlineSigners(ctx context.Context) error + SyncSigners(ctx context.Context, onlineSigners []string) error ConfirmHandshake(ctx context.Context, message []byte) error } diff --git a/internal/service/frost/helper.go b/internal/service/frost/helper.go new file mode 100644 index 00000000..2970df8f --- /dev/null +++ b/internal/service/frost/helper.go @@ -0,0 +1,23 @@ +package frost + +import ( + "github.com/ethereum/go-ethereum/common" +) + +func FilterOnlineSigners(signers []common.Address, onlines []string) []common.Address { + for i := 0; i < len(signers); i++ { + isExist := false + for _, online := range onlines { + if online == signers[i].String() { + isExist = true + break + } + } + + if !isExist { + signers = append(signers[:i], signers[i+1:]...) + } + } + + return signers +} diff --git a/internal/service/frost/helper_test.go b/internal/service/frost/helper_test.go new file mode 100644 index 00000000..ff75804f --- /dev/null +++ b/internal/service/frost/helper_test.go @@ -0,0 +1,84 @@ +package frost + +import ( + "github.com/ethereum/go-ethereum/common" + "reflect" + "testing" +) + +func TestFilterOnlineSigners(t *testing.T) { + type args struct { + signers []common.Address + onlines []string + } + tests := []struct { + name string + args args + want []common.Address + }{ + { + name: "Test case 1", + args: args{ + signers: []common.Address{ + common.HexToAddress("0x1"), + common.HexToAddress("0x2"), + common.HexToAddress("0x3"), + }, + onlines: []string{ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000003", + }, + }, + want: []common.Address{ + common.HexToAddress("0x1"), + common.HexToAddress("0x3"), + }, + }, + { + name: "Test case 2", + args: args{ + signers: []common.Address{ + common.HexToAddress("0x1"), + common.HexToAddress("0x2"), + common.HexToAddress("0x3"), + }, + onlines: []string{ + "0x0000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003", + }, + }, + want: []common.Address{ + common.HexToAddress("0x1"), + common.HexToAddress("0x2"), + common.HexToAddress("0x3"), + }, + }, + { + name: "Test case 3", + args: args{ + signers: []common.Address{ + common.HexToAddress("0x1"), + common.HexToAddress("0x2"), + common.HexToAddress("0x3"), + }, + onlines: []string{ + "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003", + }, + }, + want: []common.Address{ + common.HexToAddress("0x2"), + common.HexToAddress("0x3"), + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := FilterOnlineSigners(tt.args.signers, tt.args.onlines); !reflect.DeepEqual(got, tt.want) { + t.Errorf("FilterOnlineSigners() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/internal/service/frost/sync.go b/internal/service/frost/sync.go index e68585ab..102cc7eb 100644 --- a/internal/service/frost/sync.go +++ b/internal/service/frost/sync.go @@ -2,26 +2,51 @@ package frost import ( "context" - + "encoding/json" "github.com/TimeleapLabs/unchained/internal/config" - "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/crypto" "github.com/TimeleapLabs/unchained/internal/crypto/multisig" "github.com/TimeleapLabs/unchained/internal/transport/client/conn" + "github.com/TimeleapLabs/unchained/internal/transport/server/pubsub" + "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/store" + "time" + + "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/utils" "github.com/ethereum/go-ethereum/common" "github.com/taurusgroup/multi-party-sig/pkg/protocol" ) +func (s *service) SendOnlineSigners(ctx context.Context) error { + onlineSigners := []string{} + store.OnlineFrostParties.Range(func(key string, value time.Time) bool { + onlineSigners = append(onlineSigners, key) + + return false + }) + + onlineSignersBytes, err := json.Marshal(onlineSigners) + if err != nil { + utils.Logger.With("Error", err).Error("Cant marshal online signers list") + return consts.ErrInternalError + } + + pubsub.Publish(consts.ChannelFrostSigner, consts.OpcodeFrostSignerOnlines, onlineSignersBytes) + + return nil +} + // SyncSigners starts calculating of Frost signers by sending signers list to the Broker. -func (s *service) SyncSigners(ctx context.Context) error { +func (s *service) SyncSigners(ctx context.Context, onlineSigners []string) error { addresses, err := s.pos.GetSchnorrSigners(ctx) if err != nil { utils.Logger.With("Error", err).Error("Cant get signers list") return err } - minSignerCount := (len(addresses) / 2) + 1 + addresses = FilterOnlineSigners(addresses, onlineSigners) + + minSignerCount := (len(addresses) / 100) * 65 s.currentSigners = addresses var handshakeMessageCh <-chan *protocol.Message diff --git a/internal/service/pos/pos_mock.go b/internal/service/pos/pos_mock.go index 2cf30251..c29b9836 100644 --- a/internal/service/pos/pos_mock.go +++ b/internal/service/pos/pos_mock.go @@ -41,3 +41,15 @@ func (m *MockService) GetSchnorrSigners(_ context.Context) ([]common.Address, er args := m.Called() return args.Get(0).([]common.Address), args.Error(1) } + +func NewMock() *MockService { + pos := &MockService{} + + pos.On("GetSchnorrSigners", mock.Anything).Return([]common.Address{ + common.HexToAddress("0x1"), + common.HexToAddress("0x2"), + common.HexToAddress("0x3"), + }, nil) + + return pos +} diff --git a/internal/service/pos/pos_test.go b/internal/service/pos/pos_test.go index 2918c13c..4071b610 100644 --- a/internal/service/pos/pos_test.go +++ b/internal/service/pos/pos_test.go @@ -2,46 +2,45 @@ package pos import ( "context" + "math/big" "testing" - "github.com/TimeleapLabs/unchained/internal/crypto" - "github.com/TimeleapLabs/unchained/internal/crypto/ethereum" - "github.com/TimeleapLabs/unchained/internal/utils" "github.com/stretchr/testify/suite" ) type PosTestSuite struct { suite.Suite - service Service + service *MockService } func (s *PosTestSuite) SetupTest() { - utils.SetupLogger("info") - crypto.InitMachineIdentity( - crypto.WithBlsIdentity(), - crypto.WithEvmSigner(), - ) - - ethRPC := ethereum.NewMock() - s.service = New(ethRPC) + s.service = NewMock() } func (s *PosTestSuite) TestGetTotalVotingPower() { + s.service.On("GetTotalVotingPower").Return(0, nil) + _, err := s.service.GetTotalVotingPower() s.NoError(err) } func (s *PosTestSuite) TestGetVotingPower() { - _, err := s.service.GetVotingPower([20]byte{}, nil) + s.service.On("GetVotingPower", [20]byte{}, big.NewInt(0)).Return(0, nil) + + _, err := s.service.GetVotingPower([20]byte{}, big.NewInt(0)) s.NoError(err) } func (s *PosTestSuite) TestGetVotingPowerFromContract() { - _, err := s.service.GetVotingPowerFromContract([20]byte{}, nil) + s.service.On("GetVotingPowerFromContract", [20]byte{}, big.NewInt(0)).Return(0, nil) + + _, err := s.service.GetVotingPowerFromContract([20]byte{}, big.NewInt(0)) s.NoError(err) } func (s *PosTestSuite) TestGetVotingPowerOfPublicKey() { + s.service.On("GetVotingPowerOfPublicKey", [96]byte{}).Return(0, nil) + _, err := s.service.GetVotingPowerOfPublicKey(context.TODO(), [96]byte{}) s.NoError(err) } diff --git a/internal/transport/client/client.go b/internal/transport/client/client.go index 91bd6289..7a8676e4 100644 --- a/internal/transport/client/client.go +++ b/internal/transport/client/client.go @@ -48,9 +48,8 @@ func NewRPC(handler handler.Handler) { case consts.OpCodeFrostSignerHandshake: handler.ConfirmFrostHandshake(ctx, payload[1:]) - case consts.OpcodeFrostSignerIsReady: - handler.StoreOnlineFrostParty(ctx, payload[1:]) - + case consts.OpcodeFrostSignerOnlines: + handler.InitFrostIdentity(ctx, payload[1:]) default: utils.Logger. With("Code", payload[0]). diff --git a/internal/transport/client/handler/challenge.go b/internal/transport/client/handler/challenge.go index c222ca3f..48ae2014 100644 --- a/internal/transport/client/handler/challenge.go +++ b/internal/transport/client/handler/challenge.go @@ -6,7 +6,7 @@ import ( "github.com/TimeleapLabs/unchained/internal/utils" ) -func (h *postgresConsumer) Challenge(message []byte) []byte { +func (h *consumer) Challenge(message []byte) []byte { challenge := new(model.ChallengePacket).FromBytes(message) signature, err := crypto.Identity.Bls.Sign(challenge.Random[:]) @@ -20,21 +20,7 @@ func (h *postgresConsumer) Challenge(message []byte) []byte { return challenge.Sia().Bytes() } -func (h *schnorrConsumer) Challenge(message []byte) []byte { - challenge := new(model.ChallengePacket).FromBytes(message) - - signature, err := crypto.Identity.Bls.Sign(challenge.Random[:]) - if err != nil { - utils.Logger.Error(err.Error()) - return nil - } - - challenge.Signature = [48]byte(signature) - - return challenge.Sia().Bytes() -} - -func (w worker) Challenge(message []byte) []byte { +func (w *worker) Challenge(message []byte) []byte { challenge := new(model.ChallengePacket).FromBytes(message) signature, err := crypto.Identity.Bls.Sign(challenge.Random[:]) diff --git a/internal/transport/client/handler/consumer.go b/internal/transport/client/handler/consumer.go deleted file mode 100644 index 31880760..00000000 --- a/internal/transport/client/handler/consumer.go +++ /dev/null @@ -1,43 +0,0 @@ -package handler - -import ( - "github.com/TimeleapLabs/unchained/internal/config" - "github.com/TimeleapLabs/unchained/internal/consts" - "github.com/TimeleapLabs/unchained/internal/service/correctness" - "github.com/TimeleapLabs/unchained/internal/service/evmlog" - "github.com/TimeleapLabs/unchained/internal/service/uniswap" - "github.com/TimeleapLabs/unchained/internal/transport/client/conn" - "github.com/TimeleapLabs/unchained/internal/transport/client/store" -) - -type postgresConsumer struct { - correctness correctness.Service - uniswap uniswap.Service - evmlog evmlog.Service -} - -type schnorrConsumer struct { - signerRepository store.SignerRepository -} - -func NewSchnorrConsumerHandler( - signerRepository store.SignerRepository, -) Handler { - return &schnorrConsumer{ - signerRepository: signerRepository, - } -} - -func NewPostgresConsumerHandler( - correctness correctness.Service, - uniswap uniswap.Service, - evmlog evmlog.Service, -) Handler { - conn.Send(consts.OpCodeRegisterConsumer, []byte(config.App.Network.SubscribedChannel)) - - return &postgresConsumer{ - correctness: correctness, - uniswap: uniswap, - evmlog: evmlog, - } -} diff --git a/internal/transport/client/handler/correctness.go b/internal/transport/client/handler/correctness.go index 525a1056..b7953170 100644 --- a/internal/transport/client/handler/correctness.go +++ b/internal/transport/client/handler/correctness.go @@ -6,7 +6,7 @@ import ( "github.com/TimeleapLabs/unchained/internal/model" ) -func (h *postgresConsumer) CorrectnessReport(ctx context.Context, message []byte) { +func (h *consumer) CorrectnessReport(ctx context.Context, message []byte) { packet := new(model.BroadcastCorrectnessPacket).FromBytes(message) correctnessHash, err := packet.Info.Bls() @@ -27,6 +27,4 @@ func (h *postgresConsumer) CorrectnessReport(ctx context.Context, message []byte } } -func (h *schnorrConsumer) CorrectnessReport(_ context.Context, _ []byte) {} - -func (w worker) CorrectnessReport(_ context.Context, _ []byte) {} +func (w *worker) CorrectnessReport(_ context.Context, _ []byte) {} diff --git a/internal/transport/client/handler/event.go b/internal/transport/client/handler/event.go index 16be34a4..2231f7f7 100644 --- a/internal/transport/client/handler/event.go +++ b/internal/transport/client/handler/event.go @@ -6,7 +6,7 @@ import ( "github.com/TimeleapLabs/unchained/internal/model" ) -func (h *postgresConsumer) EventLog(ctx context.Context, message []byte) { +func (h *consumer) EventLog(ctx context.Context, message []byte) { packet := new(model.BroadcastEventPacket).FromBytes(message) eventLogHash, err := packet.Info.Bls() @@ -28,6 +28,4 @@ func (h *postgresConsumer) EventLog(ctx context.Context, message []byte) { } } -func (h *schnorrConsumer) EventLog(_ context.Context, _ []byte) {} - -func (w worker) EventLog(_ context.Context, _ []byte) {} +func (w *worker) EventLog(_ context.Context, _ []byte) {} diff --git a/internal/transport/client/handler/frost.go b/internal/transport/client/handler/frost.go index 0c915de8..7c8e352e 100644 --- a/internal/transport/client/handler/frost.go +++ b/internal/transport/client/handler/frost.go @@ -2,22 +2,31 @@ package handler import ( "context" + "encoding/json" + "github.com/TimeleapLabs/unchained/internal/utils" ) -func (h *postgresConsumer) ConfirmFrostHandshake(_ context.Context, _ []byte) {} -func (h *schnorrConsumer) ConfirmFrostHandshake(_ context.Context, _ []byte) {} +func (h *consumer) ConfirmFrostHandshake(_ context.Context, _ []byte) {} -func (w worker) ConfirmFrostHandshake(ctx context.Context, message []byte) { +func (w *worker) ConfirmFrostHandshake(ctx context.Context, message []byte) { err := w.frostService.ConfirmHandshake(ctx, message) if err != nil { return } } -func (h *postgresConsumer) StoreOnlineFrostParty(_ context.Context, _ []byte) {} +func (h *consumer) InitFrostIdentity(ctx context.Context, message []byte) {} +func (w *worker) InitFrostIdentity(ctx context.Context, message []byte) { + utils.Logger.Info("Start init frost identity") + onlineSigners := []string{} -func (h *schnorrConsumer) StoreOnlineFrostParty(_ context.Context, evmAddressBytes []byte) { - h.signerRepository.SetSignerIsAlive(string(evmAddressBytes)) -} + err := json.Unmarshal(message, &onlineSigners) + if err != nil { + return + } -func (w worker) StoreOnlineFrostParty(_ context.Context, _ []byte) {} + err = w.frostService.SyncSigners(ctx, onlineSigners) + if err != nil { + return + } +} diff --git a/internal/transport/client/handler/handler.go b/internal/transport/client/handler/handler.go index 570275a7..57c5e303 100644 --- a/internal/transport/client/handler/handler.go +++ b/internal/transport/client/handler/handler.go @@ -2,6 +2,13 @@ package handler import ( "context" + "github.com/TimeleapLabs/unchained/internal/config" + "github.com/TimeleapLabs/unchained/internal/consts" + "github.com/TimeleapLabs/unchained/internal/service/correctness" + "github.com/TimeleapLabs/unchained/internal/service/evmlog" + "github.com/TimeleapLabs/unchained/internal/service/frost" + "github.com/TimeleapLabs/unchained/internal/service/uniswap" + "github.com/TimeleapLabs/unchained/internal/transport/client/conn" ) type Handler interface { @@ -11,5 +18,37 @@ type Handler interface { PriceReport(ctx context.Context, message []byte) ConfirmFrostHandshake(ctx context.Context, message []byte) - StoreOnlineFrostParty(ctx context.Context, message []byte) + InitFrostIdentity(ctx context.Context, message []byte) +} + +type worker struct { + frostService frost.Service +} + +type consumer struct { + correctness correctness.Service + uniswap uniswap.Service + evmlog evmlog.Service +} + +func NewWorkerHandler(frostService frost.Service) Handler { + conn.Send(consts.OpCodeRegisterConsumer, []byte(config.App.Network.SubscribedChannel)) + + return &worker{ + frostService: frostService, + } +} + +func NewConsumerHandler( + correctness correctness.Service, + uniswap uniswap.Service, + evmlog evmlog.Service, +) Handler { + conn.Send(consts.OpCodeRegisterConsumer, []byte(config.App.Network.SubscribedChannel)) + + return &consumer{ + correctness: correctness, + uniswap: uniswap, + evmlog: evmlog, + } } diff --git a/internal/transport/client/handler/price.go b/internal/transport/client/handler/price.go index a5eea832..81c8c010 100644 --- a/internal/transport/client/handler/price.go +++ b/internal/transport/client/handler/price.go @@ -6,7 +6,7 @@ import ( "github.com/TimeleapLabs/unchained/internal/model" ) -func (h *postgresConsumer) PriceReport(ctx context.Context, message []byte) { +func (h *consumer) PriceReport(ctx context.Context, message []byte) { packet := new(model.BroadcastPricePacket).FromBytes(message) priceInfoHash, err := packet.Info.Bls() @@ -28,6 +28,4 @@ func (h *postgresConsumer) PriceReport(ctx context.Context, message []byte) { } } -func (h *schnorrConsumer) PriceReport(_ context.Context, _ []byte) {} - -func (w worker) PriceReport(_ context.Context, _ []byte) {} +func (w *worker) PriceReport(_ context.Context, _ []byte) {} diff --git a/internal/transport/client/handler/worker.go b/internal/transport/client/handler/worker.go deleted file mode 100644 index 83dca90a..00000000 --- a/internal/transport/client/handler/worker.go +++ /dev/null @@ -1,13 +0,0 @@ -package handler - -import "github.com/TimeleapLabs/unchained/internal/service/frost" - -type worker struct { - frostService frost.Service -} - -func NewWorkerHandler(frostService frost.Service) Handler { - return &worker{ - frostService: frostService, - } -} diff --git a/internal/transport/client/store/native.go b/internal/transport/client/store/native.go deleted file mode 100644 index da422489..00000000 --- a/internal/transport/client/store/native.go +++ /dev/null @@ -1,25 +0,0 @@ -package store - -import ( - "time" - - "github.com/puzpuzpuz/xsync/v3" -) - -type SignerRepository interface { - SetSignerIsAlive(evmAddress string) -} - -type NativeStore struct { - signers *xsync.MapOf[string, time.Time] -} - -func (n NativeStore) SetSignerIsAlive(evmAddress string) { - n.signers.Store(evmAddress, time.Now()) -} - -func New() SignerRepository { - return &NativeStore{ - signers: xsync.NewMapOf[string, time.Time](), - } -} diff --git a/internal/transport/server/websocket/handler/hello.go b/internal/transport/server/websocket/handler/hello.go index 9e003323..8dddb895 100644 --- a/internal/transport/server/websocket/handler/hello.go +++ b/internal/transport/server/websocket/handler/hello.go @@ -18,6 +18,7 @@ func (h Handler) Hello(conn *websocket.Conn, payload []byte) ([]byte, error) { preConn, preConnExist := h.clientRepository.GetByPublicKey(signer.PublicKey) if preConnExist { + h.clientRepository.Remove(preConn) Close(preConn) } diff --git a/internal/transport/server/websocket/handler/helper.go b/internal/transport/server/websocket/handler/helper.go index e6db66a5..b62ccaf0 100644 --- a/internal/transport/server/websocket/handler/helper.go +++ b/internal/transport/server/websocket/handler/helper.go @@ -29,7 +29,7 @@ func BroadcastListener(ctx context.Context, conn *websocket.Conn, ch chan []byte select { case <-ctx.Done(): utils.Logger.Info("Closing connection") - close(ch) + //close(ch) return case message := <-ch: err := conn.WriteMessage(websocket.BinaryMessage, message) diff --git a/internal/transport/server/websocket/store/store.go b/internal/transport/server/websocket/store/store.go index b7febd30..2a71ded7 100644 --- a/internal/transport/server/websocket/store/store.go +++ b/internal/transport/server/websocket/store/store.go @@ -2,12 +2,14 @@ package store import ( "github.com/TimeleapLabs/unchained/internal/model" + "time" "github.com/gorilla/websocket" "github.com/puzpuzpuz/xsync/v3" ) var Challenges = xsync.NewMapOf[*websocket.Conn, model.ChallengePacket]() +var OnlineFrostParties = xsync.NewMapOf[string, time.Time]() type ClientRepository interface { Set(conn *websocket.Conn, signer model.Signer) diff --git a/internal/transport/server/websocket/websocket.go b/internal/transport/server/websocket/websocket.go index f62cedba..f345c149 100644 --- a/internal/transport/server/websocket/websocket.go +++ b/internal/transport/server/websocket/websocket.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "net/http" + "time" "github.com/taurusgroup/multi-party-sig/pkg/protocol" @@ -40,8 +41,7 @@ func WithWebsocket( } func multiplexer( - signerRepository store.ClientRepository, - serverHandler *handler.Handler, + signerRepository store.ClientRepository, serverHandler *handler.Handler, ) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) @@ -138,6 +138,9 @@ func multiplexer( case consts.OpcodeFrostSignerIsReady: pubsub.Publish(consts.ChannelFrostSigner, consts.OpcodeFrostSignerIsReady, payload[1:]) + case consts.OpCodeFrostSignerHeartBeat: + store.OnlineFrostParties.Store(conn.RemoteAddr().String(), time.Now()) + default: handler.SendError(conn, messageType, consts.OpCodeError, consts.ErrNotSupportedInstruction) } From f4d718ed8d8466e77dc92d7291f24a721211cac1 Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Fri, 14 Jun 2024 01:20:29 +0330 Subject: [PATCH 28/29] =?UTF-8?q?=E2=9C=A8=20feat(frost):=20add=20full=20t?= =?UTF-8?q?est=20for=20frost=20and=20some=20debuging=20>>>=20=E2=8F=B0=204?= =?UTF-8?q?h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/crypto/identity.go | 20 +----- internal/crypto/multisig/identity.go | 7 +- internal/crypto/multisig/identity_test.go | 81 ++++++++++------------ internal/crypto/multisig/signer.go | 30 ++++++-- internal/service/frost/frost.go | 43 ++++++++---- internal/service/frost/frost_test.go | 80 +++++++++++++++++++++ internal/service/frost/helper.go | 20 +++--- internal/service/frost/sync.go | 18 ++--- internal/service/pos/pos_mock.go | 13 ++-- internal/transport/client/handler/frost.go | 13 +++- 10 files changed, 216 insertions(+), 109 deletions(-) create mode 100644 internal/service/frost/frost_test.go diff --git a/internal/crypto/identity.go b/internal/crypto/identity.go index 4ecb6410..e74b7b17 100644 --- a/internal/crypto/identity.go +++ b/internal/crypto/identity.go @@ -3,8 +3,6 @@ package crypto import ( "encoding/hex" - "github.com/TimeleapLabs/unchained/internal/crypto/multisig" - "github.com/TimeleapLabs/unchained/internal/config" "github.com/TimeleapLabs/unchained/internal/crypto/bls" "github.com/TimeleapLabs/unchained/internal/crypto/ethereum" @@ -20,9 +18,8 @@ type Signer interface { // MachineIdentity holds machine identity and provide and manage keys. type MachineIdentity struct { - Bls Signer - Eth Signer - Frost *multisig.DistributedSigner + Bls Signer + Eth Signer } // Identity is a global variable that holds machine identity. @@ -73,19 +70,6 @@ func WithEvmSigner() func(machineIdentity *MachineIdentity) error { } } -// WithTssSigner initialize and will add Tss identity to machine identity. -// func WithTssSigner(signers []string, minThreshold int) func(machineIdentity *MachineIdentity) error { -// return func(machineIdentity *MachineIdentity) error { -// machineIdentity.Tss = tss.NewIdentity( -// signers, -// minThreshold, -// ) -// //machineIdentity.Tss.WriteConfigs() -// -// return nil -// } -//} - // WithBlsIdentity initialize and will add Bls identity to machine identity. func WithBlsIdentity() func(machineIdentity *MachineIdentity) error { return func(machineIdentity *MachineIdentity) error { diff --git a/internal/crypto/multisig/identity.go b/internal/crypto/multisig/identity.go index 1f48a3c0..2396a57f 100644 --- a/internal/crypto/multisig/identity.go +++ b/internal/crypto/multisig/identity.go @@ -15,6 +15,7 @@ type DistributedSigner struct { ID party.ID sessionID string Signers []party.ID + numOfAcks int ackHandler *protocol.MultiHandler Config *frost.TaprootConfig } @@ -33,7 +34,7 @@ func (d *DistributedSigner) ConfirmFromBytes(msgBytes []byte) (bool, error) { // Confirm function will set other parties confirms. func (d *DistributedSigner) Confirm(msg *protocol.Message) (bool, error) { - if !msg.IsFor(d.ID) { + if !msg.IsFor(d.ID) && !msg.Broadcast { return false, consts.ErrInvalidSignature } @@ -42,6 +43,9 @@ func (d *DistributedSigner) Confirm(msg *protocol.Message) (bool, error) { result, err := d.ackHandler.Result() if err != nil { if err.Error() == "protocol: not finished" { + //d.numOfAcks++ + //fmt.Println(d.ID, "Acks:", d.numOfAcks) + return false, nil } @@ -69,6 +73,7 @@ func NewIdentity(sessionID, id string, signers []string, minSigningCount int) (* } return &DistributedSigner{ + ID: party.ID(id), sessionID: sessionID, Signers: signersIDs, minSigningCount: minSigningCount, diff --git a/internal/crypto/multisig/identity_test.go b/internal/crypto/multisig/identity_test.go index c197fc32..842363d6 100644 --- a/internal/crypto/multisig/identity_test.go +++ b/internal/crypto/multisig/identity_test.go @@ -18,6 +18,7 @@ const ( var ( sessionID = "sessionID" + testData = "hello world!" ) type MultiSigIdentityTestSuite struct { @@ -45,26 +46,15 @@ func (s *MultiSigIdentityTestSuite) SetupTest() { wg.Add(1) go func(channel <-chan *protocol.Message) { for msg := range channel { - if msg.Broadcast { - for _, p := range s.parties { + for _, p := range s.parties { + if msg.Broadcast || msg.IsFor(p.ID) { isReady, err := p.Confirm(msg) assert.NoError(s.T(), err) + if isReady { - s.T().Log("Confirmed!") wg.Done() } } - } else { - for _, p := range s.parties { - if msg.IsFor(p.ID) { - isReady, err := p.Confirm(msg) - assert.NoError(s.T(), err) - if isReady { - s.T().Log("Confirmed!") - wg.Done() - } - } - } } } }(channel) @@ -74,38 +64,37 @@ func (s *MultiSigIdentityTestSuite) SetupTest() { } func (s *MultiSigIdentityTestSuite) TestSign() { - // signers := []*MessageSigner{} - - // for _, party := range s.parties { - // signer, msgCh, err := party.NewSigner(testData) - // assert.NoError(s.T(), err) - // - // signers = append(signers, signer) - // - // go func() { - // for msg := range msgCh { - // if msg.Broadcast { - // for _, v := range s.parties { - // err = v.Confirm(msg) - // assert.NoError(s.T(), err) - // if err == nil { - // s.T().Log("Confirmed!") - // } - // } - // } else { - // for _, v := range s.parties { - // if msg.IsFor(v.ID) { - // err = v.Confirm(msg) - // assert.NoError(s.T(), err) - // if err == nil { - // s.T().Log("Confirmed!") - // } - // } - // } - // } - // } - // }() - //} + signers := []*MessageSigner{} + channels := []<-chan *protocol.Message{} + + for _, party := range s.parties { + signer, msgCh, err := party.NewSigner([]byte(testData)) + assert.NoError(s.T(), err) + + signers = append(signers, signer) + channels = append(channels, msgCh) + } + + wg := sync.WaitGroup{} + wg.Add(1) + for _, channel := range channels { + go func(channel <-chan *protocol.Message) { + for msg := range channel { + for _, p := range signers { + if msg.Broadcast || msg.IsFor(p.ID) { + isReady, err := p.Confirm(msg) + assert.NoError(s.T(), err) + + if isReady { + wg.Done() + } + } + } + } + }(channel) + } + + wg.Wait() } func TestMultiSigIdentitySuite(t *testing.T) { diff --git a/internal/crypto/multisig/signer.go b/internal/crypto/multisig/signer.go index 3650ae4b..e31f0261 100644 --- a/internal/crypto/multisig/signer.go +++ b/internal/crypto/multisig/signer.go @@ -3,27 +3,48 @@ package multisig import ( "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/taurusgroup/multi-party-sig/pkg/party" "github.com/taurusgroup/multi-party-sig/pkg/protocol" "github.com/taurusgroup/multi-party-sig/protocols/frost" ) // MessageSigner represents state of signing of a message. type MessageSigner struct { + ID party.ID ackHandler *protocol.MultiHandler } -// Confirm function will set other parties confirms. -func (s *MessageSigner) Confirm(msgByte []byte) error { +// ConfirmFromBytes function will set other parties confirms from byte array. +func (s *MessageSigner) ConfirmFromBytes(msgByte []byte) (bool, error) { msg := &protocol.Message{} err := msg.UnmarshalBinary(msgByte) if err != nil { utils.Logger.With("err", err).Error("cant unmarshal message") - return consts.ErrCantDecode + return false, consts.ErrCantDecode } + return s.Confirm(msg) +} + +// Confirm function will set other parties confirms. +func (s *MessageSigner) Confirm(msg *protocol.Message) (bool, error) { s.ackHandler.Accept(msg) - return nil + _, err := s.ackHandler.Result() + if err != nil { + if err.Error() == "protocol: not finished" { + //d.numOfAcks++ + //fmt.Println(d.ID, "Acks:", d.numOfAcks) + + return false, nil + } + + return false, err + } + + //signature := result.(taproot.Signature) + + return true, nil } func (d *DistributedSigner) NewSigner(data []byte) (*MessageSigner, <-chan *protocol.Message, error) { @@ -40,6 +61,7 @@ func (d *DistributedSigner) NewSigner(data []byte) (*MessageSigner, <-chan *prot } return &MessageSigner{ + ID: d.ID, ackHandler: handler, }, handler.Listen(), nil } diff --git a/internal/service/frost/frost.go b/internal/service/frost/frost.go index 5134206f..a3c7080c 100644 --- a/internal/service/frost/frost.go +++ b/internal/service/frost/frost.go @@ -2,40 +2,59 @@ package frost import ( "context" + "errors" + "github.com/TimeleapLabs/unchained/internal/consts" + "github.com/TimeleapLabs/unchained/internal/crypto/multisig" + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/taurusgroup/multi-party-sig/pkg/protocol" "github.com/ethereum/go-ethereum/common" - "github.com/TimeleapLabs/unchained/internal/consts" - "github.com/TimeleapLabs/unchained/internal/crypto" "github.com/TimeleapLabs/unchained/internal/service/pos" - "github.com/TimeleapLabs/unchained/internal/transport/client/conn" - "github.com/TimeleapLabs/unchained/internal/utils" ) type Service interface { SendOnlineSigners(ctx context.Context) error - SyncSigners(ctx context.Context, onlineSigners []string) error - ConfirmHandshake(ctx context.Context, message []byte) error + SyncSigners(ctx context.Context, onlineSigners []string) (<-chan *protocol.Message, error) + CoordinateHandshake(ch <-chan *protocol.Message) + ConfirmHandshake(ctx context.Context, message []byte) (bool, error) + ConfirmHandshakeRaw(ctx context.Context, message *protocol.Message) (bool, error) + SignData(ctx context.Context, data []byte) ([]byte, error) } type service struct { pos pos.Service + frost *multisig.DistributedSigner + currentSigners []common.Address } -func (s *service) ConfirmHandshake(_ context.Context, message []byte) error { - isReady, err := crypto.Identity.Frost.ConfirmFromBytes(message) +func (s *service) SignData(ctx context.Context, data []byte) ([]byte, error) { + signer, msgCh, err := s.frost.NewSigner(data) if err != nil { + + } +} + +func (s *service) ConfirmHandshakeRaw(_ context.Context, message *protocol.Message) (bool, error) { + isReady, err := s.frost.Confirm(message) + if err != nil && !errors.Is(err, consts.ErrInvalidSignature) { utils.Logger.With("Error", err).Error("Can't confirm handshake message") - return err + return false, err } - if isReady { - conn.SendMessage(consts.OpcodeFrostSignerIsReady, crypto.Identity.ExportEvmSigner().EvmAddress) + return isReady, nil +} + +func (s *service) ConfirmHandshake(_ context.Context, message []byte) (bool, error) { + isReady, err := s.frost.ConfirmFromBytes(message) + if err != nil && errors.Is(err, consts.ErrInvalidSignature) { + utils.Logger.With("Error", err).Error("Can't confirm handshake message") + return false, err } - return nil + return isReady, nil } func New(pos pos.Service) Service { diff --git a/internal/service/frost/frost_test.go b/internal/service/frost/frost_test.go new file mode 100644 index 00000000..adee5636 --- /dev/null +++ b/internal/service/frost/frost_test.go @@ -0,0 +1,80 @@ +package frost + +import ( + "context" + "github.com/TimeleapLabs/unchained/internal/config" + "github.com/TimeleapLabs/unchained/internal/service/pos" + "github.com/TimeleapLabs/unchained/internal/utils" + "github.com/stretchr/testify/suite" + "github.com/taurusgroup/multi-party-sig/pkg/protocol" + "sync" + "testing" +) + +var ( + OnlinePeers = []string{ + "0x0000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000003", "0x0000000000000000000000000000000000000004", "0x0000000000000000000000000000000000000005", "0x0000000000000000000000000000000000000006", "0x0000000000000000000000000000000000000007", "0x0000000000000000000000000000000000000008", "0x0000000000000000000000000000000000000009", "0x0000000000000000000000000000000000000010", + } + AllPeers = []string{ + "0x0000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000003", "0x0000000000000000000000000000000000000004", "0x0000000000000000000000000000000000000005", "0x0000000000000000000000000000000000000006", "0x0000000000000000000000000000000000000007", "0x0000000000000000000000000000000000000008", "0x0000000000000000000000000000000000000009", "0x0000000000000000000000000000000000000010", "0x0000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000012", "0x0000000000000000000000000000000000000013", + } +) + +type FrostServiceTestSuite struct { + suite.Suite + + services []Service +} + +func (s *FrostServiceTestSuite) SetupTest() { + utils.SetupLogger("info") + + mockPos := pos.NewMock(AllPeers) + + for i := 0; i < len(OnlinePeers); i++ { + s.services = append(s.services, New(mockPos)) + } + +} + +func (s *FrostServiceTestSuite) TestSyncSigners() { + channels := []<-chan *protocol.Message{} + for i := 0; i < len(OnlinePeers); i++ { + + config.App.Plugins.Frost = &config.Frost{Session: "session-test"} + config.App.Secret.EvmAddress = OnlinePeers[i] + config.App.Secret.PublicKey = "a7f10f30e905b5c7a060f6f761ef8004e09b8faae72a09d7ddbc0c3b75cd98c80bbd79660abaca8242a3ce95e01fdbb51960bf8e67489aa4882b56fd2ed0691c0e9754d0856baeac0424bd38194f595e054eb17068434546dec24d548fb3ec82" + + handshakeChannel, err := s.services[i].SyncSigners(context.TODO(), OnlinePeers) + s.NoError(err) + + channels = append(channels, handshakeChannel) + } + + wg := sync.WaitGroup{} + for i, channel := range channels { + wg.Add(1) + go func(channel <-chan *protocol.Message) { + for msg := range channel { + for j, _ := range s.services { + isReady, err := s.services[j].ConfirmHandshakeRaw(context.TODO(), msg) + s.NoError(err) + + if isReady { + wg.Done() + } + } + } + }(channel) + } + + wg.Wait() +} + +func (s *FrostServiceTestSuite) TestSigning() { + +} + +func TestFrostServiceTestSuite(t *testing.T) { + suite.Run(t, new(FrostServiceTestSuite)) +} diff --git a/internal/service/frost/helper.go b/internal/service/frost/helper.go index 2970df8f..100e0735 100644 --- a/internal/service/frost/helper.go +++ b/internal/service/frost/helper.go @@ -5,19 +5,17 @@ import ( ) func FilterOnlineSigners(signers []common.Address, onlines []string) []common.Address { - for i := 0; i < len(signers); i++ { - isExist := false - for _, online := range onlines { - if online == signers[i].String() { - isExist = true - break - } - } + lookup := make(map[string]bool) + for _, item := range onlines { + lookup[item] = true + } - if !isExist { - signers = append(signers[:i], signers[i+1:]...) + var filtered []common.Address + for _, item := range signers { + if _, exists := lookup[item.String()]; exists { + filtered = append(filtered, item) } } - return signers + return filtered } diff --git a/internal/service/frost/sync.go b/internal/service/frost/sync.go index 102cc7eb..499f5763 100644 --- a/internal/service/frost/sync.go +++ b/internal/service/frost/sync.go @@ -9,6 +9,7 @@ import ( "github.com/TimeleapLabs/unchained/internal/transport/client/conn" "github.com/TimeleapLabs/unchained/internal/transport/server/pubsub" "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/store" + "math" "time" "github.com/TimeleapLabs/unchained/internal/consts" @@ -17,6 +18,7 @@ import ( "github.com/taurusgroup/multi-party-sig/pkg/protocol" ) +// SendOnlineSigners sends online signers list to the Workers. func (s *service) SendOnlineSigners(ctx context.Context) error { onlineSigners := []string{} store.OnlineFrostParties.Range(func(key string, value time.Time) bool { @@ -37,29 +39,27 @@ func (s *service) SendOnlineSigners(ctx context.Context) error { } // SyncSigners starts calculating of Frost signers by sending signers list to the Broker. -func (s *service) SyncSigners(ctx context.Context, onlineSigners []string) error { +func (s *service) SyncSigners(ctx context.Context, onlineSigners []string) (<-chan *protocol.Message, error) { addresses, err := s.pos.GetSchnorrSigners(ctx) if err != nil { utils.Logger.With("Error", err).Error("Cant get signers list") - return err + return nil, err } addresses = FilterOnlineSigners(addresses, onlineSigners) - minSignerCount := (len(addresses) / 100) * 65 + minSignerCount := math.Round(0.65 * float64(len(addresses))) s.currentSigners = addresses - var handshakeMessageCh <-chan *protocol.Message - crypto.Identity.Frost, handshakeMessageCh = multisig.NewIdentity( + + s.frost, handshakeMessageCh = multisig.NewIdentity( config.App.Plugins.Frost.Session, crypto.Identity.ExportEvmSigner().EvmAddress, addressArrayToStringArray(addresses), - minSignerCount, + int(minSignerCount), ) - go s.CoordinateHandshake(handshakeMessageCh) - - return nil + return handshakeMessageCh, nil } func (s *service) CoordinateHandshake(ch <-chan *protocol.Message) { diff --git a/internal/service/pos/pos_mock.go b/internal/service/pos/pos_mock.go index c29b9836..6a97bffc 100644 --- a/internal/service/pos/pos_mock.go +++ b/internal/service/pos/pos_mock.go @@ -42,14 +42,15 @@ func (m *MockService) GetSchnorrSigners(_ context.Context) ([]common.Address, er return args.Get(0).([]common.Address), args.Error(1) } -func NewMock() *MockService { +func NewMock(parties []string) *MockService { pos := &MockService{} - pos.On("GetSchnorrSigners", mock.Anything).Return([]common.Address{ - common.HexToAddress("0x1"), - common.HexToAddress("0x2"), - common.HexToAddress("0x3"), - }, nil) + partiesAddress := []common.Address{} + for _, party := range parties { + partiesAddress = append(partiesAddress, common.HexToAddress(party)) + } + + pos.On("GetSchnorrSigners", mock.Anything).Return(partiesAddress, nil) return pos } diff --git a/internal/transport/client/handler/frost.go b/internal/transport/client/handler/frost.go index 7c8e352e..d272a891 100644 --- a/internal/transport/client/handler/frost.go +++ b/internal/transport/client/handler/frost.go @@ -3,16 +3,23 @@ package handler import ( "context" "encoding/json" + "github.com/TimeleapLabs/unchained/internal/consts" + "github.com/TimeleapLabs/unchained/internal/crypto" + "github.com/TimeleapLabs/unchained/internal/transport/client/conn" "github.com/TimeleapLabs/unchained/internal/utils" ) func (h *consumer) ConfirmFrostHandshake(_ context.Context, _ []byte) {} func (w *worker) ConfirmFrostHandshake(ctx context.Context, message []byte) { - err := w.frostService.ConfirmHandshake(ctx, message) + isReady, err := w.frostService.ConfirmHandshake(ctx, message) if err != nil { return } + + if isReady { + conn.SendMessage(consts.OpcodeFrostSignerIsReady, crypto.Identity.ExportEvmSigner().EvmAddress) + } } func (h *consumer) InitFrostIdentity(ctx context.Context, message []byte) {} @@ -25,8 +32,10 @@ func (w *worker) InitFrostIdentity(ctx context.Context, message []byte) { return } - err = w.frostService.SyncSigners(ctx, onlineSigners) + handshakeChannel, err := w.frostService.SyncSigners(ctx, onlineSigners) if err != nil { return } + + w.frostService.CoordinateHandshake(handshakeChannel) } From 543a26705e56b5b7b210dda7716d163ea3a6eaf4 Mon Sep 17 00:00:00 2001 From: Parya Rastegar Date: Tue, 18 Jun 2024 02:53:34 +0330 Subject: [PATCH 29/29] =?UTF-8?q?=E2=9C=A8=20feat(frost):=20add=20service?= =?UTF-8?q?=20test=20>>>=20=E2=8F=B0=203h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/app/broker.go | 4 +- internal/app/consumer.go | 5 +- internal/consts/opcodes.go | 4 + internal/crypto/multisig/identity.go | 5 +- internal/crypto/multisig/identity_test.go | 4 +- internal/crypto/multisig/signer.go | 25 ++--- internal/service/frost/frost.go | 58 +++++++++++- internal/service/frost/frost_test.go | 94 ++++++++++++++++--- internal/service/frost/helper_test.go | 3 +- internal/service/frost/sync.go | 7 +- internal/service/pos/pos_test.go | 2 +- internal/transport/client/client.go | 4 + internal/transport/client/handler/frost.go | 8 +- internal/transport/client/handler/handler.go | 2 + .../server/websocket/handler/helper.go | 2 +- .../transport/server/websocket/store/store.go | 3 +- .../transport/server/websocket/websocket.go | 3 + internal/utils/ttlmap.go | 41 ++++++++ 18 files changed, 229 insertions(+), 45 deletions(-) create mode 100644 internal/utils/ttlmap.go diff --git a/internal/app/broker.go b/internal/app/broker.go index 61cff02a..dc807ac1 100644 --- a/internal/app/broker.go +++ b/internal/app/broker.go @@ -29,10 +29,10 @@ func Broker() { ethRPC := ethereum.New() pos := pos.New(ethRPC) - //redisIns := redis.New() + // redisIns := redis.New() nativeSignerRepo := store.New() - //redisSignerRepo := store.NewRedisStore(redisIns, nativeSignerRepo) + // redisSignerRepo := store.NewRedisStore(redisIns, nativeSignerRepo) frostService := frost.New(pos) diff --git a/internal/app/consumer.go b/internal/app/consumer.go index 106d149a..72b0ef92 100644 --- a/internal/app/consumer.go +++ b/internal/app/consumer.go @@ -54,11 +54,10 @@ func Consumer() { gql.WithGraphQL(db), ) - //signerRepo := store.New() + // signerRepo := store.New() - //client.NewRPC( + // client.NewRPC( // handler.NewSchnorrConsumerHandler(signerRepo), //) // - } diff --git a/internal/consts/opcodes.go b/internal/consts/opcodes.go index a6c2864e..7f032905 100644 --- a/internal/consts/opcodes.go +++ b/internal/consts/opcodes.go @@ -28,4 +28,8 @@ const ( OpcodeFrostSignerIsReady OpCode = 13 OpCodeFrostSignerHeartBeat OpCode = 14 OpcodeFrostSignerOnlines OpCode = 15 + + OpCodeFrostRequestSign OpCode = 16 + OpCodeFrostConfirmMessageSign OpCode = 17 + OpCodeFrostMessageIsReady OpCode = 18 ) diff --git a/internal/crypto/multisig/identity.go b/internal/crypto/multisig/identity.go index 2396a57f..720797bb 100644 --- a/internal/crypto/multisig/identity.go +++ b/internal/crypto/multisig/identity.go @@ -15,7 +15,6 @@ type DistributedSigner struct { ID party.ID sessionID string Signers []party.ID - numOfAcks int ackHandler *protocol.MultiHandler Config *frost.TaprootConfig } @@ -43,8 +42,8 @@ func (d *DistributedSigner) Confirm(msg *protocol.Message) (bool, error) { result, err := d.ackHandler.Result() if err != nil { if err.Error() == "protocol: not finished" { - //d.numOfAcks++ - //fmt.Println(d.ID, "Acks:", d.numOfAcks) + // d.numOfAcks++ + // fmt.Println(d.ID, "Acks:", d.numOfAcks) return false, nil } diff --git a/internal/crypto/multisig/identity_test.go b/internal/crypto/multisig/identity_test.go index 842363d6..5d7458cf 100644 --- a/internal/crypto/multisig/identity_test.go +++ b/internal/crypto/multisig/identity_test.go @@ -82,10 +82,10 @@ func (s *MultiSigIdentityTestSuite) TestSign() { for msg := range channel { for _, p := range signers { if msg.Broadcast || msg.IsFor(p.ID) { - isReady, err := p.Confirm(msg) + signature, err := p.Confirm(msg) assert.NoError(s.T(), err) - if isReady { + if signature != nil { wg.Done() } } diff --git a/internal/crypto/multisig/signer.go b/internal/crypto/multisig/signer.go index e31f0261..e6f83f99 100644 --- a/internal/crypto/multisig/signer.go +++ b/internal/crypto/multisig/signer.go @@ -5,6 +5,7 @@ import ( "github.com/TimeleapLabs/unchained/internal/utils" "github.com/taurusgroup/multi-party-sig/pkg/party" "github.com/taurusgroup/multi-party-sig/pkg/protocol" + "github.com/taurusgroup/multi-party-sig/pkg/taproot" "github.com/taurusgroup/multi-party-sig/protocols/frost" ) @@ -15,36 +16,36 @@ type MessageSigner struct { } // ConfirmFromBytes function will set other parties confirms from byte array. -func (s *MessageSigner) ConfirmFromBytes(msgByte []byte) (bool, error) { +func (s *MessageSigner) ConfirmFromBytes(msgByte []byte) ([]byte, error) { msg := &protocol.Message{} err := msg.UnmarshalBinary(msgByte) if err != nil { utils.Logger.With("err", err).Error("cant unmarshal message") - return false, consts.ErrCantDecode + return nil, consts.ErrCantDecode } return s.Confirm(msg) } // Confirm function will set other parties confirms. -func (s *MessageSigner) Confirm(msg *protocol.Message) (bool, error) { +func (s *MessageSigner) Confirm(msg *protocol.Message) ([]byte, error) { s.ackHandler.Accept(msg) - _, err := s.ackHandler.Result() + result, err := s.ackHandler.Result() if err != nil { if err.Error() == "protocol: not finished" { - //d.numOfAcks++ - //fmt.Println(d.ID, "Acks:", d.numOfAcks) - - return false, nil + return nil, nil } - return false, err + return nil, err } - //signature := result.(taproot.Signature) - - return true, nil + signature, ok := result.(taproot.Signature) + if !ok { + utils.Logger.Error("Can't get signature") + return nil, consts.ErrInternalError + } + return signature, nil } func (d *DistributedSigner) NewSigner(data []byte) (*MessageSigner, <-chan *protocol.Message, error) { diff --git a/internal/service/frost/frost.go b/internal/service/frost/frost.go index a3c7080c..cf142ac9 100644 --- a/internal/service/frost/frost.go +++ b/internal/service/frost/frost.go @@ -2,9 +2,12 @@ package frost import ( "context" + "crypto/sha1" // #nosec "errors" + "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/crypto/multisig" + "github.com/TimeleapLabs/unchained/internal/transport/client/conn" "github.com/TimeleapLabs/unchained/internal/utils" "github.com/taurusgroup/multi-party-sig/pkg/protocol" @@ -19,7 +22,11 @@ type Service interface { CoordinateHandshake(ch <-chan *protocol.Message) ConfirmHandshake(ctx context.Context, message []byte) (bool, error) ConfirmHandshakeRaw(ctx context.Context, message *protocol.Message) (bool, error) - SignData(ctx context.Context, data []byte) ([]byte, error) + + RequestToSign(data []byte) + SignData(ctx context.Context, data []byte) ([]byte, <-chan *protocol.Message, error) + CoordinateSignData(hashOfMessage []byte, msgCh <-chan *protocol.Message) + ConfirmSignedData(data []byte) ([]byte, error) } type service struct { @@ -27,14 +34,56 @@ type service struct { frost *multisig.DistributedSigner - currentSigners []common.Address + currentSigners []common.Address + signingMessages *utils.TTLMap +} + +func (s *service) RequestToSign(data []byte) { + conn.Send(consts.OpCodeFrostRequestSign, data) } -func (s *service) SignData(ctx context.Context, data []byte) ([]byte, error) { +func (s *service) SignData(ctx context.Context, data []byte) ([]byte, <-chan *protocol.Message, error) { signer, msgCh, err := s.frost.NewSigner(data) if err != nil { + return nil, nil, err + } + + hasher := sha1.New() // #nosec + hasher.Write(data) + hashOfMessage := hasher.Sum(nil) + s.signingMessages.Set(ctx, string(hashOfMessage), signer) + + return hashOfMessage, msgCh, nil +} +func (s *service) CoordinateSignData(hashOfMessage []byte, msgCh <-chan *protocol.Message) { + for msg := range msgCh { + msgBytes, err := msg.MarshalBinary() + if err != nil { + utils.Logger.With("Error", err).Error("Can't marshal message") + return + } + + conn.Send(consts.OpCodeFrostConfirmMessageSign, append(hashOfMessage, msgBytes...)) + } +} + +func (s *service) ConfirmSignedData(data []byte) ([]byte, error) { + hashOfMessage := data[:20] + signatureBytes := data[20:] + signer, isExist := s.signingMessages.Get(string(hashOfMessage)) + if !isExist { + utils.Logger.With("Error", "").Error("Can't get signer") + return nil, consts.ErrSignerIsNotReady } + + signature, err := signer.(*multisig.MessageSigner).ConfirmFromBytes(signatureBytes) + if err != nil { + utils.Logger.With("Error", err).Error("Can't confirm signed message") + return nil, err + } + + return signature, nil } func (s *service) ConfirmHandshakeRaw(_ context.Context, message *protocol.Message) (bool, error) { @@ -59,6 +108,7 @@ func (s *service) ConfirmHandshake(_ context.Context, message []byte) (bool, err func New(pos pos.Service) Service { return &service{ - pos: pos, + pos: pos, + signingMessages: utils.NewDataStore(), } } diff --git a/internal/service/frost/frost_test.go b/internal/service/frost/frost_test.go index adee5636..a0ead922 100644 --- a/internal/service/frost/frost_test.go +++ b/internal/service/frost/frost_test.go @@ -2,22 +2,34 @@ package frost import ( "context" + "sync" + "testing" + "github.com/TimeleapLabs/unchained/internal/config" "github.com/TimeleapLabs/unchained/internal/service/pos" "github.com/TimeleapLabs/unchained/internal/utils" "github.com/stretchr/testify/suite" "github.com/taurusgroup/multi-party-sig/pkg/protocol" - "sync" - "testing" ) var ( OnlinePeers = []string{ - "0x0000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000003", "0x0000000000000000000000000000000000000004", "0x0000000000000000000000000000000000000005", "0x0000000000000000000000000000000000000006", "0x0000000000000000000000000000000000000007", "0x0000000000000000000000000000000000000008", "0x0000000000000000000000000000000000000009", "0x0000000000000000000000000000000000000010", + "0x0000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003", "0x0000000000000000000000000000000000000004", + "0x0000000000000000000000000000000000000005", "0x0000000000000000000000000000000000000006", + "0x0000000000000000000000000000000000000007", "0x0000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000009", "0x0000000000000000000000000000000000000010", } AllPeers = []string{ - "0x0000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000002", "0x0000000000000000000000000000000000000003", "0x0000000000000000000000000000000000000004", "0x0000000000000000000000000000000000000005", "0x0000000000000000000000000000000000000006", "0x0000000000000000000000000000000000000007", "0x0000000000000000000000000000000000000008", "0x0000000000000000000000000000000000000009", "0x0000000000000000000000000000000000000010", "0x0000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000012", "0x0000000000000000000000000000000000000013", + "0x0000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000003", "0x0000000000000000000000000000000000000004", + "0x0000000000000000000000000000000000000005", "0x0000000000000000000000000000000000000006", + "0x0000000000000000000000000000000000000007", "0x0000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000009", "0x0000000000000000000000000000000000000010", + "0x0000000000000000000000000000000000000011", "0x0000000000000000000000000000000000000012", + "0x0000000000000000000000000000000000000013", } + TestData = []byte("test-data") ) type FrostServiceTestSuite struct { @@ -35,15 +47,12 @@ func (s *FrostServiceTestSuite) SetupTest() { s.services = append(s.services, New(mockPos)) } -} - -func (s *FrostServiceTestSuite) TestSyncSigners() { channels := []<-chan *protocol.Message{} for i := 0; i < len(OnlinePeers); i++ { - config.App.Plugins.Frost = &config.Frost{Session: "session-test"} config.App.Secret.EvmAddress = OnlinePeers[i] - config.App.Secret.PublicKey = "a7f10f30e905b5c7a060f6f761ef8004e09b8faae72a09d7ddbc0c3b75cd98c80bbd79660abaca8242a3ce95e01fdbb51960bf8e67489aa4882b56fd2ed0691c0e9754d0856baeac0424bd38194f595e054eb17068434546dec24d548fb3ec82" + config.App.Secret.PublicKey = + "a7f10f30e905b5c7a060f6f761ef8004e09b8faae72a09d7ddbc0c3b75cd98c80bbd79660abaca8242a3ce95e01fdbb51960bf8e67489aa4882b56fd2ed0691c0e9754d0856baeac0424bd38194f595e054eb17068434546dec24d548fb3ec82" handshakeChannel, err := s.services[i].SyncSigners(context.TODO(), OnlinePeers) s.NoError(err) @@ -52,11 +61,11 @@ func (s *FrostServiceTestSuite) TestSyncSigners() { } wg := sync.WaitGroup{} - for i, channel := range channels { + for _, channel := range channels { wg.Add(1) go func(channel <-chan *protocol.Message) { for msg := range channel { - for j, _ := range s.services { + for j := range s.services { isReady, err := s.services[j].ConfirmHandshakeRaw(context.TODO(), msg) s.NoError(err) @@ -72,7 +81,70 @@ func (s *FrostServiceTestSuite) TestSyncSigners() { } func (s *FrostServiceTestSuite) TestSigning() { + channels := []<-chan *protocol.Message{} + for i := 0; i < len(OnlinePeers); i++ { + config.App.Plugins.Frost = &config.Frost{Session: "session-test"} + config.App.Secret.EvmAddress = OnlinePeers[i] + config.App.Secret.PublicKey = + "a7f10f30e905b5c7a060f6f761ef8004e09b8faae72a09d7ddbc0c3b75cd98c80bbd79660abaca8242a3ce95e01fdbb51960bf8e67489aa4882b56fd2ed0691c0e9754d0856baeac0424bd38194f595e054eb17068434546dec24d548fb3ec82" + + handshakeChannel, err := s.services[i].SyncSigners(context.TODO(), OnlinePeers) + s.NoError(err) + + channels = append(channels, handshakeChannel) + } + + wg := sync.WaitGroup{} + for _, channel := range channels { + wg.Add(1) + go func(channel <-chan *protocol.Message) { + for msg := range channel { + for j := range s.services { + isReady, err := s.services[j].ConfirmHandshakeRaw(context.TODO(), msg) + s.NoError(err) + if isReady { + wg.Done() + } + } + } + }(channel) + } + + wg.Wait() + + signChannels := []<-chan *protocol.Message{} + hashOfMessage := []byte{} + for _, signer := range s.services { + var err error + var msgCh <-chan *protocol.Message + hashOfMessage, msgCh, err = signer.SignData(context.TODO(), TestData) + s.NoError(err) + + channels = append(channels, msgCh) + } + + wg = sync.WaitGroup{} + for _, channel := range signChannels { + wg.Add(1) + go func(hashOfMessage []byte, msgCh <-chan *protocol.Message) { + for msg := range msgCh { + msgBytes, err := msg.MarshalBinary() + s.NoError(err) + + for j := range s.services { + signature, err := s.services[j].ConfirmSignedData(append(hashOfMessage, msgBytes...)) + s.NoError(err) + + if signature != nil { + wg.Done() + } + } + } + }(hashOfMessage, channel) + } + + wg.Wait() } func TestFrostServiceTestSuite(t *testing.T) { diff --git a/internal/service/frost/helper_test.go b/internal/service/frost/helper_test.go index ff75804f..4df99a9a 100644 --- a/internal/service/frost/helper_test.go +++ b/internal/service/frost/helper_test.go @@ -1,9 +1,10 @@ package frost import ( - "github.com/ethereum/go-ethereum/common" "reflect" "testing" + + "github.com/ethereum/go-ethereum/common" ) func TestFilterOnlineSigners(t *testing.T) { diff --git a/internal/service/frost/sync.go b/internal/service/frost/sync.go index 499f5763..856f8413 100644 --- a/internal/service/frost/sync.go +++ b/internal/service/frost/sync.go @@ -3,14 +3,15 @@ package frost import ( "context" "encoding/json" + "math" + "time" + "github.com/TimeleapLabs/unchained/internal/config" "github.com/TimeleapLabs/unchained/internal/crypto" "github.com/TimeleapLabs/unchained/internal/crypto/multisig" "github.com/TimeleapLabs/unchained/internal/transport/client/conn" "github.com/TimeleapLabs/unchained/internal/transport/server/pubsub" "github.com/TimeleapLabs/unchained/internal/transport/server/websocket/store" - "math" - "time" "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/utils" @@ -19,7 +20,7 @@ import ( ) // SendOnlineSigners sends online signers list to the Workers. -func (s *service) SendOnlineSigners(ctx context.Context) error { +func (s *service) SendOnlineSigners(_ context.Context) error { onlineSigners := []string{} store.OnlineFrostParties.Range(func(key string, value time.Time) bool { onlineSigners = append(onlineSigners, key) diff --git a/internal/service/pos/pos_test.go b/internal/service/pos/pos_test.go index 4071b610..7a0f1a1b 100644 --- a/internal/service/pos/pos_test.go +++ b/internal/service/pos/pos_test.go @@ -14,7 +14,7 @@ type PosTestSuite struct { } func (s *PosTestSuite) SetupTest() { - s.service = NewMock() + s.service = NewMock([]string{"0x1", "0x2", "0x3"}) } func (s *PosTestSuite) TestGetTotalVotingPower() { diff --git a/internal/transport/client/client.go b/internal/transport/client/client.go index 7a8676e4..2d8d3423 100644 --- a/internal/transport/client/client.go +++ b/internal/transport/client/client.go @@ -50,6 +50,10 @@ func NewRPC(handler handler.Handler) { case consts.OpcodeFrostSignerOnlines: handler.InitFrostIdentity(ctx, payload[1:]) + + case consts.OpCodeFrostRequestSign: + handler.RequestToSign(ctx, payload[1:]) + default: utils.Logger. With("Code", payload[0]). diff --git a/internal/transport/client/handler/frost.go b/internal/transport/client/handler/frost.go index d272a891..ecd06a28 100644 --- a/internal/transport/client/handler/frost.go +++ b/internal/transport/client/handler/frost.go @@ -3,6 +3,7 @@ package handler import ( "context" "encoding/json" + "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/crypto" "github.com/TimeleapLabs/unchained/internal/transport/client/conn" @@ -22,7 +23,7 @@ func (w *worker) ConfirmFrostHandshake(ctx context.Context, message []byte) { } } -func (h *consumer) InitFrostIdentity(ctx context.Context, message []byte) {} +func (h *consumer) InitFrostIdentity(_ context.Context, _ []byte) {} func (w *worker) InitFrostIdentity(ctx context.Context, message []byte) { utils.Logger.Info("Start init frost identity") onlineSigners := []string{} @@ -39,3 +40,8 @@ func (w *worker) InitFrostIdentity(ctx context.Context, message []byte) { w.frostService.CoordinateHandshake(handshakeChannel) } + +func (h *consumer) RequestToSign(_ context.Context, _ []byte) {} +func (w *worker) RequestToSign(_ context.Context, message []byte) { + w.frostService.RequestToSign(message) +} diff --git a/internal/transport/client/handler/handler.go b/internal/transport/client/handler/handler.go index 57c5e303..288af303 100644 --- a/internal/transport/client/handler/handler.go +++ b/internal/transport/client/handler/handler.go @@ -2,6 +2,7 @@ package handler import ( "context" + "github.com/TimeleapLabs/unchained/internal/config" "github.com/TimeleapLabs/unchained/internal/consts" "github.com/TimeleapLabs/unchained/internal/service/correctness" @@ -19,6 +20,7 @@ type Handler interface { ConfirmFrostHandshake(ctx context.Context, message []byte) InitFrostIdentity(ctx context.Context, message []byte) + RequestToSign(ctx context.Context, message []byte) } type worker struct { diff --git a/internal/transport/server/websocket/handler/helper.go b/internal/transport/server/websocket/handler/helper.go index b62ccaf0..f00358e7 100644 --- a/internal/transport/server/websocket/handler/helper.go +++ b/internal/transport/server/websocket/handler/helper.go @@ -29,7 +29,7 @@ func BroadcastListener(ctx context.Context, conn *websocket.Conn, ch chan []byte select { case <-ctx.Done(): utils.Logger.Info("Closing connection") - //close(ch) + // close(ch) return case message := <-ch: err := conn.WriteMessage(websocket.BinaryMessage, message) diff --git a/internal/transport/server/websocket/store/store.go b/internal/transport/server/websocket/store/store.go index 2a71ded7..d7aa167c 100644 --- a/internal/transport/server/websocket/store/store.go +++ b/internal/transport/server/websocket/store/store.go @@ -1,9 +1,10 @@ package store import ( - "github.com/TimeleapLabs/unchained/internal/model" "time" + "github.com/TimeleapLabs/unchained/internal/model" + "github.com/gorilla/websocket" "github.com/puzpuzpuz/xsync/v3" ) diff --git a/internal/transport/server/websocket/websocket.go b/internal/transport/server/websocket/websocket.go index f345c149..2f61966e 100644 --- a/internal/transport/server/websocket/websocket.go +++ b/internal/transport/server/websocket/websocket.go @@ -141,6 +141,9 @@ func multiplexer( case consts.OpCodeFrostSignerHeartBeat: store.OnlineFrostParties.Store(conn.RemoteAddr().String(), time.Now()) + case consts.OpCodeFrostRequestSign: + pubsub.Publish(consts.ChannelFrostSigner, consts.OpCodeFrostRequestSign, payload[1:]) + default: handler.SendError(conn, messageType, consts.OpCodeError, consts.ErrNotSupportedInstruction) } diff --git a/internal/utils/ttlmap.go b/internal/utils/ttlmap.go new file mode 100644 index 00000000..0cdc550a --- /dev/null +++ b/internal/utils/ttlmap.go @@ -0,0 +1,41 @@ +package utils + +import ( + "context" + "sync" +) + +// TTLMap is a thread-safe map to store data with context. +type TTLMap struct { + data map[string]interface{} + mutex sync.Mutex +} + +// NewDataStore initializes a new DataStore. +func NewDataStore() *TTLMap { + return &TTLMap{ + data: make(map[string]interface{}), + } +} + +// Set adds a key-value pair to the DataStore with a context. +func (ds *TTLMap) Set(ctx context.Context, key string, value interface{}) { + ds.mutex.Lock() + ds.data[key] = value + ds.mutex.Unlock() + + go func() { + <-ctx.Done() + ds.mutex.Lock() + delete(ds.data, key) + ds.mutex.Unlock() + }() +} + +// Get retrieves a value by key from the DataStore. +func (ds *TTLMap) Get(key string) (interface{}, bool) { + ds.mutex.Lock() + defer ds.mutex.Unlock() + value, exists := ds.data[key] + return value, exists +}