diff --git a/go.mod b/go.mod index d64b798..4b81028 100644 --- a/go.mod +++ b/go.mod @@ -24,10 +24,11 @@ require ( github.com/spf13/cast v1.9.2 github.com/spf13/cobra v1.9.1 github.com/spf13/viper v1.20.1 + github.com/stellar/go-stellar-sdk v0.2.0 github.com/stretchr/testify v1.11.1 go.uber.org/mock v0.6.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.44.0 + golang.org/x/crypto v0.46.0 google.golang.org/grpc v1.77.0 google.golang.org/protobuf v1.36.11 gorm.io/driver/postgres v1.6.0 @@ -102,6 +103,8 @@ require ( github.com/fluent/fluent-logger-golang v1.4.0 // indirect github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect + github.com/go-chi/chi v4.1.2+incompatible // indirect + github.com/go-errors/errors v1.5.1 // indirect github.com/go-kit/kit v0.13.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect @@ -110,7 +113,7 @@ require ( github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect - github.com/go-viper/mapstructure/v2 v2.3.0 // indirect + github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gofrs/uuid v4.4.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -122,6 +125,7 @@ require ( github.com/google/btree v1.1.3 // indirect github.com/google/flatbuffers v1.12.1 // indirect github.com/google/go-cmp v0.7.0 // indirect + github.com/gorilla/schema v1.4.1 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect @@ -148,6 +152,7 @@ require ( github.com/leodido/go-urn v1.2.1 // indirect github.com/linxGnu/grocksdb v1.8.14 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/manucorporat/sse v0.0.0-20160126180136-ee05b128a739 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect @@ -176,11 +181,14 @@ require ( github.com/rs/zerolog v1.33.0 // indirect github.com/sagikazarmark/locafero v0.7.0 // indirect github.com/sasha-s/go-deadlock v0.3.5 // indirect + github.com/segmentio/go-loggly v0.5.1-0.20171222203950-eb91657e62b2 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.12.0 // indirect github.com/spf13/pflag v1.0.6 // indirect + github.com/stellar/go-xdr v0.0.0-20231122183749-b53fb00bcac2 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect @@ -204,13 +212,13 @@ require ( go.opentelemetry.io/otel v1.39.0 // indirect go.opentelemetry.io/otel/metric v1.39.0 // indirect go.opentelemetry.io/otel/trace v1.39.0 // indirect - go.uber.org/multierr v1.10.0 // indirect + go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sync v0.18.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sync v0.19.0 // indirect golang.org/x/sys v0.39.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.9.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 // indirect diff --git a/go.sum b/go.sum index 95c4f1c..5885f2b 100644 --- a/go.sum +++ b/go.sum @@ -76,12 +76,16 @@ github.com/VictoriaMetrics/fastcache v1.13.0/go.mod h1:hHXhl4DA2fTL2HTZDJFXWgW0L github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/ajg/form v0.0.0-20160822230020-523a5da1a92f h1:zvClvFQwU++UpIUBGC8YmDlfhUrweEy1R1Fj1gu5iIM= +github.com/ajg/form v0.0.0-20160822230020-523a5da1a92f/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= +github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= @@ -133,8 +137,8 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f github.com/catppuccin/go v0.3.0 h1:d+0/YicIq+hSTo5oPuRi5kOpqkVA5tAsU6dNhvRu+aY= github.com/catppuccin/go v0.3.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= -github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= -github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -277,6 +281,8 @@ github.com/evalphobia/logrus_fluent v0.5.4 h1:G4BSBTm7+L+oanWfFtA/A5Y3pvL2OMxvic github.com/evalphobia/logrus_fluent v0.5.4/go.mod h1:hasyj+CXm3BDP1YhFk/rnTcjlegyqvkokV9A25cQsaA= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY= @@ -291,11 +297,15 @@ 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.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/gavv/monotime v0.0.0-20161010190848-47d58efa6955 h1:gmtGRvSexPU4B1T/yYo0sLOKzER1YT+b4kPxPpm0Ty4= +github.com/gavv/monotime v0.0.0-20161010190848-47d58efa6955/go.mod h1:vmp8DIyckQMXOPl0AQVHt+7n5h7Gb7hS6CUydiV8QeA= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= -github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= +github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= +github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -326,8 +336,8 @@ github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-viper/mapstructure/v2 v2.3.0 h1:27XbWsHIqhbdR5TIC911OfYvgSaW93HM+dX7970Q7jk= -github.com/go-viper/mapstructure/v2 v2.3.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= +github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -403,6 +413,8 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= @@ -424,10 +436,12 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= -github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= +github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= +github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -483,6 +497,8 @@ github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/icon-project/goloop v1.4.4 h1:DgVL/t0tMmtVIKM66gWhK5hV6rXJf6Qy1HPdDKr1ipI= github.com/icon-project/goloop v1.4.4/go.mod h1:afo1sZEgOjT5eMvRx6OzdGqKkbDrpZX+qi2lJOVXXKo= +github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -497,6 +513,8 @@ github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jarcoal/httpmock v0.0.0-20161210151336-4442edb3db31 h1:Aw95BEvxJ3K6o9GGv5ppCd1P8hkeIeEJ30FO+OhOJpM= +github.com/jarcoal/httpmock v0.0.0-20161210151336-4442edb3db31/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -556,6 +574,8 @@ github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69 github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/manucorporat/sse v0.0.0-20160126180136-ee05b128a739 h1:ykXz+pRRTibcSjG1yRhpdSHInF8yZY/mfn+Rz2Nd1rE= +github.com/manucorporat/sse v0.0.0-20160126180136-ee05b128a739/go.mod h1:zUx1mhth20V3VKgL5jbd1BSQcW4Fy6Qs4PZvQwRFwzM= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -592,6 +612,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/moul/http2curl v0.0.0-20161031194548-4e24498b31db h1:eZgFHVkk9uOTaOQLC6tgjkzdp7Ays8eEVecBcfHZlJQ= +github.com/moul/http2curl v0.0.0-20161031194548-4e24498b31db/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= @@ -615,14 +637,15 @@ github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DV github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q= -github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= @@ -708,6 +731,10 @@ github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsF github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= github.com/sasha-s/go-deadlock v0.3.5 h1:tNCOEEDG6tBqrNDOX35j/7hL5FcFViG6awUGROb2NsU= github.com/sasha-s/go-deadlock v0.3.5/go.mod h1:bugP6EGbdGYObIlx7pUZtWqlvo8k9H6vCBBsiChJQ5U= +github.com/segmentio/go-loggly v0.5.1-0.20171222203950-eb91657e62b2 h1:S4OC0+OBKz6mJnzuHioeEat74PuQ4Sgvbf8eus695sc= +github.com/segmentio/go-loggly v0.5.1-0.20171222203950-eb91657e62b2/go.mod h1:8zLRYR5npGjaOXgPSKat5+oOh+UHd8OdbS18iqX9F6Y= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= @@ -729,6 +756,10 @@ github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4= github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= +github.com/stellar/go-stellar-sdk v0.2.0 h1:7+C4SKAtxDRZ3H1Istr3Ctn6xVshoPF1MNsWw+iuGgU= +github.com/stellar/go-stellar-sdk v0.2.0/go.mod h1:4osSHRDfb/D7zE2iNjmPdg2Gmbx0M/JLhTM4YcwPW5s= +github.com/stellar/go-xdr v0.0.0-20231122183749-b53fb00bcac2 h1:OzCVd0SV5qE3ZcDeSFCmOWLZfEWZ3Oe8KtmSOYKEVWE= +github.com/stellar/go-xdr v0.0.0-20231122183749-b53fb00bcac2/go.mod h1:yoxyU/M8nl9LKeWIoBrbDPQ7Cy+4jxRcWcOayZ4BMps= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -772,6 +803,8 @@ github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.40.0 h1:CRq/00MfruPGFLTQKY8b+8SfdK60TxNztjRMnH0t1Yc= +github.com/valyala/fasthttp v1.40.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= @@ -779,10 +812,24 @@ github.com/vmihailenco/msgpack/v4 v4.3.13 h1:A2wsiTbvp63ilDaWmsk2wjx6xZdxQOvpiNl github.com/vmihailenco/msgpack/v4 v4.3.13/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/xdrpp/goxdr v0.1.1 h1:E1B2c6E8eYhOVyd7yEpOyopzTPirUeF6mVOfXfGyJyc= +github.com/xdrpp/goxdr v0.1.1/go.mod h1:dXo1scL/l6s7iME1gxHWo2XCppbHEKZS7m/KyYWkNzA= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= +github.com/yalp/jsonpath v0.0.0-20150812003900-31a79c7593bb h1:06WAhQa+mYv7BiOk13B/ywyTlkoE/S7uu6TBKU6FHnE= +github.com/yalp/jsonpath v0.0.0-20150812003900-31a79c7593bb/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yudai/gojsondiff v0.0.0-20170107030110-7b1b7adf999d h1:yJIizrfO599ot2kQ6Af1enICnwBD3XoxgX3MrMwot2M= +github.com/yudai/gojsondiff v0.0.0-20170107030110-7b1b7adf999d/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20150405163532-d1c525dea8ce h1:888GrqRxabUce7lj4OaoShPxodm3kXOMpSa85wdYzfY= +github.com/yudai/golcs v0.0.0-20150405163532-d1c525dea8ce/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -817,8 +864,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -829,8 +876,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= -golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -900,8 +947,8 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -920,8 +967,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -987,8 +1034,8 @@ golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -996,8 +1043,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1153,6 +1200,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gavv/httpexpect.v1 v1.0.0-20170111145843-40724cf1e4a0 h1:r5ptJ1tBxVAeqw4CrYWhXIMr0SybY3CDHuIbCg5CFVw= +gopkg.in/gavv/httpexpect.v1 v1.0.0-20170111145843-40724cf1e4a0/go.mod h1:WtiW9ZA1LdaWqtQRo1VbIL/v4XZ8NDta+O/kSpGgVek= gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v9 v9.31.0 h1:bmXmP2RSNtFES+bn4uYuHT7iJFJv7Vj+an+ZQdDaD1M= diff --git a/internal/relayertest/mocks/chain_soroban_client.go b/internal/relayertest/mocks/chain_soroban_client.go new file mode 100644 index 0000000..8375a76 --- /dev/null +++ b/internal/relayertest/mocks/chain_soroban_client.go @@ -0,0 +1,160 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: relayer/chains/soroban/client.go +// +// Generated by this command: +// +// mockgen -source=relayer/chains/soroban/client.go -mock_names Client=MockSorobanClient -package mocks -destination internal/relayertest/mocks/chain_soroban_client.go +// + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + big "math/big" + reflect "reflect" + time "time" + + soroban "github.com/bandprotocol/falcon/relayer/chains/soroban" + horizon "github.com/stellar/go-stellar-sdk/protocols/horizon" + gomock "go.uber.org/mock/gomock" +) + +// MockSorobanClient is a mock of Client interface. +type MockSorobanClient struct { + ctrl *gomock.Controller + recorder *MockSorobanClientMockRecorder + isgomock struct{} +} + +// MockSorobanClientMockRecorder is the mock recorder for MockSorobanClient. +type MockSorobanClientMockRecorder struct { + mock *MockSorobanClient +} + +// NewMockSorobanClient creates a new mock instance. +func NewMockSorobanClient(ctrl *gomock.Controller) *MockSorobanClient { + mock := &MockSorobanClient{ctrl: ctrl} + mock.recorder = &MockSorobanClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockSorobanClient) EXPECT() *MockSorobanClientMockRecorder { + return m.recorder +} + +// BroadcastTx mocks base method. +func (m *MockSorobanClient) BroadcastTx(txBlob string) (soroban.TxResult, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BroadcastTx", txBlob) + ret0, _ := ret[0].(soroban.TxResult) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BroadcastTx indicates an expected call of BroadcastTx. +func (mr *MockSorobanClientMockRecorder) BroadcastTx(txBlob any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BroadcastTx", reflect.TypeOf((*MockSorobanClient)(nil).BroadcastTx), txBlob) +} + +// CheckAndConnect mocks base method. +func (m *MockSorobanClient) CheckAndConnect(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CheckAndConnect", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// CheckAndConnect indicates an expected call of CheckAndConnect. +func (mr *MockSorobanClientMockRecorder) CheckAndConnect(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckAndConnect", reflect.TypeOf((*MockSorobanClient)(nil).CheckAndConnect), ctx) +} + +// Connect mocks base method. +func (m *MockSorobanClient) Connect(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Connect", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// Connect indicates an expected call of Connect. +func (mr *MockSorobanClientMockRecorder) Connect(ctx any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connect", reflect.TypeOf((*MockSorobanClient)(nil).Connect), ctx) +} + +// GetAccountSequenceNumber mocks base method. +func (m *MockSorobanClient) GetAccountSequenceNumber(account string) (int64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAccountSequenceNumber", account) + ret0, _ := ret[0].(int64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAccountSequenceNumber indicates an expected call of GetAccountSequenceNumber. +func (mr *MockSorobanClientMockRecorder) GetAccountSequenceNumber(account any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccountSequenceNumber", reflect.TypeOf((*MockSorobanClient)(nil).GetAccountSequenceNumber), account) +} + +// GetBalance mocks base method. +func (m *MockSorobanClient) GetBalance(account string) (*big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBalance", account) + ret0, _ := ret[0].(*big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBalance indicates an expected call of GetBalance. +func (mr *MockSorobanClientMockRecorder) GetBalance(account any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBalance", reflect.TypeOf((*MockSorobanClient)(nil).GetBalance), account) +} + +// GetLedgerCloseTime mocks base method. +func (m *MockSorobanClient) GetLedgerCloseTime(ledgerIndex uint64) (*time.Time, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetLedgerCloseTime", ledgerIndex) + ret0, _ := ret[0].(*time.Time) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetLedgerCloseTime indicates an expected call of GetLedgerCloseTime. +func (mr *MockSorobanClientMockRecorder) GetLedgerCloseTime(ledgerIndex any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLedgerCloseTime", reflect.TypeOf((*MockSorobanClient)(nil).GetLedgerCloseTime), ledgerIndex) +} + +// GetTransactionStatus mocks base method. +func (m *MockSorobanClient) GetTransactionStatus(txHash string) (horizon.Transaction, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTransactionStatus", txHash) + ret0, _ := ret[0].(horizon.Transaction) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetTransactionStatus indicates an expected call of GetTransactionStatus. +func (mr *MockSorobanClientMockRecorder) GetTransactionStatus(txHash any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTransactionStatus", reflect.TypeOf((*MockSorobanClient)(nil).GetTransactionStatus), txHash) +} + +// StartLivelinessCheck mocks base method. +func (m *MockSorobanClient) StartLivelinessCheck(ctx context.Context, interval time.Duration) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "StartLivelinessCheck", ctx, interval) +} + +// StartLivelinessCheck indicates an expected call of StartLivelinessCheck. +func (mr *MockSorobanClientMockRecorder) StartLivelinessCheck(ctx, interval any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartLivelinessCheck", reflect.TypeOf((*MockSorobanClient)(nil).StartLivelinessCheck), ctx, interval) +} diff --git a/internal/relayertest/mocks/signer_grpc.go b/internal/relayertest/mocks/signer_grpc.go index 47f2358..e6fda31 100644 --- a/internal/relayertest/mocks/signer_grpc.go +++ b/internal/relayertest/mocks/signer_grpc.go @@ -102,6 +102,26 @@ func (mr *MockFkmsServiceClientMockRecorder) SignIcon(ctx, in any, opts ...any) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignIcon", reflect.TypeOf((*MockFkmsServiceClient)(nil).SignIcon), varargs...) } +// SignSoroban mocks base method. +func (m *MockFkmsServiceClient) SignSoroban(ctx context.Context, in *fkmsv1.SignSorobanRequest, opts ...grpc.CallOption) (*fkmsv1.SignSorobanResponse, error) { + m.ctrl.T.Helper() + varargs := []any{ctx, in} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "SignSoroban", varargs...) + ret0, _ := ret[0].(*fkmsv1.SignSorobanResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SignSoroban indicates an expected call of SignSoroban. +func (mr *MockFkmsServiceClientMockRecorder) SignSoroban(ctx, in any, opts ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx, in}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignSoroban", reflect.TypeOf((*MockFkmsServiceClient)(nil).SignSoroban), varargs...) +} + // SignXrpl mocks base method. func (m *MockFkmsServiceClient) SignXrpl(ctx context.Context, in *fkmsv1.SignXrplRequest, opts ...grpc.CallOption) (*fkmsv1.SignXrplResponse, error) { m.ctrl.T.Helper() @@ -191,6 +211,21 @@ func (mr *MockFkmsServiceServerMockRecorder) SignIcon(arg0, arg1 any) *gomock.Ca return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignIcon", reflect.TypeOf((*MockFkmsServiceServer)(nil).SignIcon), arg0, arg1) } +// SignSoroban mocks base method. +func (m *MockFkmsServiceServer) SignSoroban(arg0 context.Context, arg1 *fkmsv1.SignSorobanRequest) (*fkmsv1.SignSorobanResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SignSoroban", arg0, arg1) + ret0, _ := ret[0].(*fkmsv1.SignSorobanResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SignSoroban indicates an expected call of SignSoroban. +func (mr *MockFkmsServiceServerMockRecorder) SignSoroban(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignSoroban", reflect.TypeOf((*MockFkmsServiceServer)(nil).SignSoroban), arg0, arg1) +} + // SignXrpl mocks base method. func (m *MockFkmsServiceServer) SignXrpl(arg0 context.Context, arg1 *fkmsv1.SignXrplRequest) (*fkmsv1.SignXrplResponse, error) { m.ctrl.T.Helper() diff --git a/proto/fkms/v1/signer.pb.go b/proto/fkms/v1/signer.pb.go index cf724a5..2c7cb0a 100644 --- a/proto/fkms/v1/signer.pb.go +++ b/proto/fkms/v1/signer.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.6 -// protoc v5.29.3 +// protoc-gen-go v1.35.2 +// protoc v6.33.1 // source: proto/fkms/v1/signer.proto package fkmsv1 @@ -11,7 +11,6 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" - unsafe "unsafe" ) const ( @@ -24,9 +23,10 @@ const ( type ChainType int32 const ( - ChainType_EVM ChainType = 0 - ChainType_XRPL ChainType = 1 - ChainType_ICON ChainType = 2 + ChainType_EVM ChainType = 0 + ChainType_XRPL ChainType = 1 + ChainType_ICON ChainType = 2 + ChainType_SOROBAN ChainType = 3 ) // Enum value maps for ChainType. @@ -35,11 +35,13 @@ var ( 0: "EVM", 1: "XRPL", 2: "ICON", + 3: "SOROBAN", } ChainType_value = map[string]int32{ - "EVM": 0, - "XRPL": 1, - "ICON": 2, + "EVM": 0, + "XRPL": 1, + "ICON": 2, + "SOROBAN": 3, } ) @@ -71,11 +73,12 @@ func (ChainType) EnumDescriptor() ([]byte, []int) { } type SignEvmRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - Message []byte `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + Message []byte `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` } func (x *SignEvmRequest) Reset() { @@ -123,10 +126,11 @@ func (x *SignEvmRequest) GetMessage() []byte { } type SignEvmResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"` } func (x *SignEvmResponse) Reset() { @@ -167,11 +171,12 @@ func (x *SignEvmResponse) GetSignature() []byte { } type SignXrplRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - SignerPayload *XrplSignerPayload `protobuf:"bytes,1,opt,name=signer_payload,json=signerPayload,proto3" json:"signer_payload,omitempty"` - Tss *Tss `protobuf:"bytes,2,opt,name=tss,proto3" json:"tss,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SignerPayload *XrplSignerPayload `protobuf:"bytes,1,opt,name=signer_payload,json=signerPayload,proto3" json:"signer_payload,omitempty"` + Tss *Tss `protobuf:"bytes,2,opt,name=tss,proto3" json:"tss,omitempty"` } func (x *SignXrplRequest) Reset() { @@ -219,10 +224,11 @@ func (x *SignXrplRequest) GetTss() *Tss { } type SignXrplResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - TxBlob []byte `protobuf:"bytes,1,opt,name=tx_blob,json=txBlob,proto3" json:"tx_blob,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TxBlob []byte `protobuf:"bytes,1,opt,name=tx_blob,json=txBlob,proto3" json:"tx_blob,omitempty"` } func (x *SignXrplResponse) Reset() { @@ -263,11 +269,12 @@ func (x *SignXrplResponse) GetTxBlob() []byte { } type SignIconRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - SignerPayload *IconSignerPayload `protobuf:"bytes,1,opt,name=signer_payload,json=signerPayload,proto3" json:"signer_payload,omitempty"` - Tss *Tss `protobuf:"bytes,2,opt,name=tss,proto3" json:"tss,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SignerPayload *IconSignerPayload `protobuf:"bytes,1,opt,name=signer_payload,json=signerPayload,proto3" json:"signer_payload,omitempty"` + Tss *Tss `protobuf:"bytes,2,opt,name=tss,proto3" json:"tss,omitempty"` } func (x *SignIconRequest) Reset() { @@ -315,10 +322,11 @@ func (x *SignIconRequest) GetTss() *Tss { } type SignIconResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - TxParams []byte `protobuf:"bytes,1,opt,name=tx_params,json=txParams,proto3" json:"tx_params,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TxParams []byte `protobuf:"bytes,1,opt,name=tx_params,json=txParams,proto3" json:"tx_params,omitempty"` } func (x *SignIconResponse) Reset() { @@ -358,15 +366,113 @@ func (x *SignIconResponse) GetTxParams() []byte { return nil } -type GetSignerAddressesRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` +type SignSorobanRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + SignerPayload *SorobanSignerPayload `protobuf:"bytes,1,opt,name=signer_payload,json=signerPayload,proto3" json:"signer_payload,omitempty"` + Tss *Tss `protobuf:"bytes,2,opt,name=tss,proto3" json:"tss,omitempty"` +} + +func (x *SignSorobanRequest) Reset() { + *x = SignSorobanRequest{} + mi := &file_proto_fkms_v1_signer_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SignSorobanRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignSorobanRequest) ProtoMessage() {} + +func (x *SignSorobanRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_fkms_v1_signer_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignSorobanRequest.ProtoReflect.Descriptor instead. +func (*SignSorobanRequest) Descriptor() ([]byte, []int) { + return file_proto_fkms_v1_signer_proto_rawDescGZIP(), []int{6} +} + +func (x *SignSorobanRequest) GetSignerPayload() *SorobanSignerPayload { + if x != nil { + return x.SignerPayload + } + return nil +} + +func (x *SignSorobanRequest) GetTss() *Tss { + if x != nil { + return x.Tss + } + return nil +} + +type SignSorobanResponse struct { + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TxBlob string `protobuf:"bytes,1,opt,name=tx_blob,json=txBlob,proto3" json:"tx_blob,omitempty"` +} + +func (x *SignSorobanResponse) Reset() { + *x = SignSorobanResponse{} + mi := &file_proto_fkms_v1_signer_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SignSorobanResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignSorobanResponse) ProtoMessage() {} + +func (x *SignSorobanResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_fkms_v1_signer_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignSorobanResponse.ProtoReflect.Descriptor instead. +func (*SignSorobanResponse) Descriptor() ([]byte, []int) { + return file_proto_fkms_v1_signer_proto_rawDescGZIP(), []int{7} +} + +func (x *SignSorobanResponse) GetTxBlob() string { + if x != nil { + return x.TxBlob + } + return "" +} + +type GetSignerAddressesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } func (x *GetSignerAddressesRequest) Reset() { *x = GetSignerAddressesRequest{} - mi := &file_proto_fkms_v1_signer_proto_msgTypes[6] + mi := &file_proto_fkms_v1_signer_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -378,7 +484,7 @@ func (x *GetSignerAddressesRequest) String() string { func (*GetSignerAddressesRequest) ProtoMessage() {} func (x *GetSignerAddressesRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_fkms_v1_signer_proto_msgTypes[6] + mi := &file_proto_fkms_v1_signer_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -391,19 +497,20 @@ func (x *GetSignerAddressesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSignerAddressesRequest.ProtoReflect.Descriptor instead. func (*GetSignerAddressesRequest) Descriptor() ([]byte, []int) { - return file_proto_fkms_v1_signer_proto_rawDescGZIP(), []int{6} + return file_proto_fkms_v1_signer_proto_rawDescGZIP(), []int{8} } type GetSignerAddressesResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Signers []*Signers `protobuf:"bytes,1,rep,name=signers,proto3" json:"signers,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Signers []*Signers `protobuf:"bytes,1,rep,name=signers,proto3" json:"signers,omitempty"` } func (x *GetSignerAddressesResponse) Reset() { *x = GetSignerAddressesResponse{} - mi := &file_proto_fkms_v1_signer_proto_msgTypes[7] + mi := &file_proto_fkms_v1_signer_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -415,7 +522,7 @@ func (x *GetSignerAddressesResponse) String() string { func (*GetSignerAddressesResponse) ProtoMessage() {} func (x *GetSignerAddressesResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_fkms_v1_signer_proto_msgTypes[7] + mi := &file_proto_fkms_v1_signer_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -428,7 +535,7 @@ func (x *GetSignerAddressesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSignerAddressesResponse.ProtoReflect.Descriptor instead. func (*GetSignerAddressesResponse) Descriptor() ([]byte, []int) { - return file_proto_fkms_v1_signer_proto_rawDescGZIP(), []int{7} + return file_proto_fkms_v1_signer_proto_rawDescGZIP(), []int{9} } func (x *GetSignerAddressesResponse) GetSigners() []*Signers { @@ -439,18 +546,19 @@ func (x *GetSignerAddressesResponse) GetSigners() []*Signers { } type XrplSignerPayload struct { - state protoimpl.MessageState `protogen:"open.v1"` - Account string `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` - OracleId uint64 `protobuf:"varint,2,opt,name=oracle_id,json=oracleId,proto3" json:"oracle_id,omitempty"` - Fee string `protobuf:"bytes,3,opt,name=fee,proto3" json:"fee,omitempty"` - Sequence uint64 `protobuf:"varint,4,opt,name=sequence,proto3" json:"sequence,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Account string `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` + OracleId uint64 `protobuf:"varint,2,opt,name=oracle_id,json=oracleId,proto3" json:"oracle_id,omitempty"` + Fee string `protobuf:"bytes,3,opt,name=fee,proto3" json:"fee,omitempty"` + Sequence uint64 `protobuf:"varint,4,opt,name=sequence,proto3" json:"sequence,omitempty"` } func (x *XrplSignerPayload) Reset() { *x = XrplSignerPayload{} - mi := &file_proto_fkms_v1_signer_proto_msgTypes[8] + mi := &file_proto_fkms_v1_signer_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -462,7 +570,7 @@ func (x *XrplSignerPayload) String() string { func (*XrplSignerPayload) ProtoMessage() {} func (x *XrplSignerPayload) ProtoReflect() protoreflect.Message { - mi := &file_proto_fkms_v1_signer_proto_msgTypes[8] + mi := &file_proto_fkms_v1_signer_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -475,7 +583,7 @@ func (x *XrplSignerPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use XrplSignerPayload.ProtoReflect.Descriptor instead. func (*XrplSignerPayload) Descriptor() ([]byte, []int) { - return file_proto_fkms_v1_signer_proto_rawDescGZIP(), []int{8} + return file_proto_fkms_v1_signer_proto_rawDescGZIP(), []int{10} } func (x *XrplSignerPayload) GetAccount() string { @@ -507,18 +615,19 @@ func (x *XrplSignerPayload) GetSequence() uint64 { } type IconSignerPayload struct { - state protoimpl.MessageState `protogen:"open.v1"` - Relayer string `protobuf:"bytes,1,opt,name=relayer,proto3" json:"relayer,omitempty"` - ContractAddress string `protobuf:"bytes,2,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` - StepLimit uint64 `protobuf:"varint,3,opt,name=step_limit,json=stepLimit,proto3" json:"step_limit,omitempty"` - NetworkId string `protobuf:"bytes,4,opt,name=network_id,json=networkId,proto3" json:"network_id,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Relayer string `protobuf:"bytes,1,opt,name=relayer,proto3" json:"relayer,omitempty"` + ContractAddress string `protobuf:"bytes,2,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` + StepLimit uint64 `protobuf:"varint,3,opt,name=step_limit,json=stepLimit,proto3" json:"step_limit,omitempty"` + NetworkId string `protobuf:"bytes,4,opt,name=network_id,json=networkId,proto3" json:"network_id,omitempty"` } func (x *IconSignerPayload) Reset() { *x = IconSignerPayload{} - mi := &file_proto_fkms_v1_signer_proto_msgTypes[9] + mi := &file_proto_fkms_v1_signer_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -530,7 +639,7 @@ func (x *IconSignerPayload) String() string { func (*IconSignerPayload) ProtoMessage() {} func (x *IconSignerPayload) ProtoReflect() protoreflect.Message { - mi := &file_proto_fkms_v1_signer_proto_msgTypes[9] + mi := &file_proto_fkms_v1_signer_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -543,7 +652,7 @@ func (x *IconSignerPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use IconSignerPayload.ProtoReflect.Descriptor instead. func (*IconSignerPayload) Descriptor() ([]byte, []int) { - return file_proto_fkms_v1_signer_proto_rawDescGZIP(), []int{9} + return file_proto_fkms_v1_signer_proto_rawDescGZIP(), []int{11} } func (x *IconSignerPayload) GetRelayer() string { @@ -574,18 +683,104 @@ func (x *IconSignerPayload) GetNetworkId() string { return "" } -type Tss struct { - state protoimpl.MessageState `protogen:"open.v1"` - Message []byte `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` - RandomAddr []byte `protobuf:"bytes,2,opt,name=random_addr,json=randomAddr,proto3" json:"random_addr,omitempty"` - SignatureS []byte `protobuf:"bytes,3,opt,name=signature_s,json=signatureS,proto3" json:"signature_s,omitempty"` +type SorobanSignerPayload struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + SourceAccount string `protobuf:"bytes,1,opt,name=source_account,json=sourceAccount,proto3" json:"source_account,omitempty"` + ContractAddress string `protobuf:"bytes,2,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` + Fee string `protobuf:"bytes,3,opt,name=fee,proto3" json:"fee,omitempty"` + Sequence int64 `protobuf:"varint,4,opt,name=sequence,proto3" json:"sequence,omitempty"` + NetworkPassphrase string `protobuf:"bytes,5,opt,name=network_passphrase,json=networkPassphrase,proto3" json:"network_passphrase,omitempty"` + RpcUrls []string `protobuf:"bytes,6,rep,name=rpc_urls,json=rpcUrls,proto3" json:"rpc_urls,omitempty"` +} + +func (x *SorobanSignerPayload) Reset() { + *x = SorobanSignerPayload{} + mi := &file_proto_fkms_v1_signer_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SorobanSignerPayload) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SorobanSignerPayload) ProtoMessage() {} + +func (x *SorobanSignerPayload) ProtoReflect() protoreflect.Message { + mi := &file_proto_fkms_v1_signer_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SorobanSignerPayload.ProtoReflect.Descriptor instead. +func (*SorobanSignerPayload) Descriptor() ([]byte, []int) { + return file_proto_fkms_v1_signer_proto_rawDescGZIP(), []int{12} +} + +func (x *SorobanSignerPayload) GetSourceAccount() string { + if x != nil { + return x.SourceAccount + } + return "" +} + +func (x *SorobanSignerPayload) GetContractAddress() string { + if x != nil { + return x.ContractAddress + } + return "" +} + +func (x *SorobanSignerPayload) GetFee() string { + if x != nil { + return x.Fee + } + return "" +} + +func (x *SorobanSignerPayload) GetSequence() int64 { + if x != nil { + return x.Sequence + } + return 0 +} + +func (x *SorobanSignerPayload) GetNetworkPassphrase() string { + if x != nil { + return x.NetworkPassphrase + } + return "" +} + +func (x *SorobanSignerPayload) GetRpcUrls() []string { + if x != nil { + return x.RpcUrls + } + return nil +} + +type Tss struct { + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message []byte `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + RandomAddr []byte `protobuf:"bytes,2,opt,name=random_addr,json=randomAddr,proto3" json:"random_addr,omitempty"` + SignatureS []byte `protobuf:"bytes,3,opt,name=signature_s,json=signatureS,proto3" json:"signature_s,omitempty"` } func (x *Tss) Reset() { *x = Tss{} - mi := &file_proto_fkms_v1_signer_proto_msgTypes[10] + mi := &file_proto_fkms_v1_signer_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -597,7 +792,7 @@ func (x *Tss) String() string { func (*Tss) ProtoMessage() {} func (x *Tss) ProtoReflect() protoreflect.Message { - mi := &file_proto_fkms_v1_signer_proto_msgTypes[10] + mi := &file_proto_fkms_v1_signer_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -610,7 +805,7 @@ func (x *Tss) ProtoReflect() protoreflect.Message { // Deprecated: Use Tss.ProtoReflect.Descriptor instead. func (*Tss) Descriptor() ([]byte, []int) { - return file_proto_fkms_v1_signer_proto_rawDescGZIP(), []int{10} + return file_proto_fkms_v1_signer_proto_rawDescGZIP(), []int{13} } func (x *Tss) GetMessage() []byte { @@ -635,16 +830,17 @@ func (x *Tss) GetSignatureS() []byte { } type Signers struct { - state protoimpl.MessageState `protogen:"open.v1"` - ChainType ChainType `protobuf:"varint,1,opt,name=chain_type,json=chainType,proto3,enum=fkms.v1.ChainType" json:"chain_type,omitempty"` - Addresses []string `protobuf:"bytes,2,rep,name=addresses,proto3" json:"addresses,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ChainType ChainType `protobuf:"varint,1,opt,name=chain_type,json=chainType,proto3,enum=fkms.v1.ChainType" json:"chain_type,omitempty"` + Addresses []string `protobuf:"bytes,2,rep,name=addresses,proto3" json:"addresses,omitempty"` } func (x *Signers) Reset() { *x = Signers{} - mi := &file_proto_fkms_v1_signer_proto_msgTypes[11] + mi := &file_proto_fkms_v1_signer_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -656,7 +852,7 @@ func (x *Signers) String() string { func (*Signers) ProtoMessage() {} func (x *Signers) ProtoReflect() protoreflect.Message { - mi := &file_proto_fkms_v1_signer_proto_msgTypes[11] + mi := &file_proto_fkms_v1_signer_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -669,7 +865,7 @@ func (x *Signers) ProtoReflect() protoreflect.Message { // Deprecated: Use Signers.ProtoReflect.Descriptor instead. func (*Signers) Descriptor() ([]byte, []int) { - return file_proto_fkms_v1_signer_proto_rawDescGZIP(), []int{11} + return file_proto_fkms_v1_signer_proto_rawDescGZIP(), []int{14} } func (x *Signers) GetChainType() ChainType { @@ -688,73 +884,145 @@ func (x *Signers) GetAddresses() []string { var File_proto_fkms_v1_signer_proto protoreflect.FileDescriptor -const file_proto_fkms_v1_signer_proto_rawDesc = "" + - "\n" + - "\x1aproto/fkms/v1/signer.proto\x12\afkms.v1\"D\n" + - "\x0eSignEvmRequest\x12\x18\n" + - "\aaddress\x18\x01 \x01(\tR\aaddress\x12\x18\n" + - "\amessage\x18\x02 \x01(\fR\amessage\"/\n" + - "\x0fSignEvmResponse\x12\x1c\n" + - "\tsignature\x18\x01 \x01(\fR\tsignature\"t\n" + - "\x0fSignXrplRequest\x12A\n" + - "\x0esigner_payload\x18\x01 \x01(\v2\x1a.fkms.v1.XrplSignerPayloadR\rsignerPayload\x12\x1e\n" + - "\x03tss\x18\x02 \x01(\v2\f.fkms.v1.TssR\x03tss\"+\n" + - "\x10SignXrplResponse\x12\x17\n" + - "\atx_blob\x18\x01 \x01(\fR\x06txBlob\"t\n" + - "\x0fSignIconRequest\x12A\n" + - "\x0esigner_payload\x18\x01 \x01(\v2\x1a.fkms.v1.IconSignerPayloadR\rsignerPayload\x12\x1e\n" + - "\x03tss\x18\x02 \x01(\v2\f.fkms.v1.TssR\x03tss\"/\n" + - "\x10SignIconResponse\x12\x1b\n" + - "\ttx_params\x18\x01 \x01(\fR\btxParams\"\x1b\n" + - "\x19GetSignerAddressesRequest\"H\n" + - "\x1aGetSignerAddressesResponse\x12*\n" + - "\asigners\x18\x01 \x03(\v2\x10.fkms.v1.SignersR\asigners\"x\n" + - "\x11XrplSignerPayload\x12\x18\n" + - "\aaccount\x18\x01 \x01(\tR\aaccount\x12\x1b\n" + - "\toracle_id\x18\x02 \x01(\x04R\boracleId\x12\x10\n" + - "\x03fee\x18\x03 \x01(\tR\x03fee\x12\x1a\n" + - "\bsequence\x18\x04 \x01(\x04R\bsequence\"\x96\x01\n" + - "\x11IconSignerPayload\x12\x18\n" + - "\arelayer\x18\x01 \x01(\tR\arelayer\x12)\n" + - "\x10contract_address\x18\x02 \x01(\tR\x0fcontractAddress\x12\x1d\n" + - "\n" + - "step_limit\x18\x03 \x01(\x04R\tstepLimit\x12\x1d\n" + - "\n" + - "network_id\x18\x04 \x01(\tR\tnetworkId\"a\n" + - "\x03Tss\x12\x18\n" + - "\amessage\x18\x01 \x01(\fR\amessage\x12\x1f\n" + - "\vrandom_addr\x18\x02 \x01(\fR\n" + - "randomAddr\x12\x1f\n" + - "\vsignature_s\x18\x03 \x01(\fR\n" + - "signatureS\"Z\n" + - "\aSigners\x121\n" + - "\n" + - "chain_type\x18\x01 \x01(\x0e2\x12.fkms.v1.ChainTypeR\tchainType\x12\x1c\n" + - "\taddresses\x18\x02 \x03(\tR\taddresses*(\n" + - "\tChainType\x12\a\n" + - "\x03EVM\x10\x00\x12\b\n" + - "\x04XRPL\x10\x01\x12\b\n" + - "\x04ICON\x10\x022\xac\x02\n" + - "\vFkmsService\x12<\n" + - "\aSignEvm\x12\x17.fkms.v1.SignEvmRequest\x1a\x18.fkms.v1.SignEvmResponse\x12?\n" + - "\bSignXrpl\x12\x18.fkms.v1.SignXrplRequest\x1a\x19.fkms.v1.SignXrplResponse\x12?\n" + - "\bSignIcon\x12\x18.fkms.v1.SignIconRequest\x1a\x19.fkms.v1.SignIconResponse\x12]\n" + - "\x12GetSignerAddresses\x12\".fkms.v1.GetSignerAddressesRequest\x1a#.fkms.v1.GetSignerAddressesResponseB5Z3github.com/bandprotocol/falcon/proto/fkms/v1;fkmsv1b\x06proto3" +var file_proto_fkms_v1_signer_proto_rawDesc = []byte{ + 0x0a, 0x1a, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x66, 0x6b, 0x6d, 0x73, 0x2f, 0x76, 0x31, 0x2f, + 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x66, 0x6b, + 0x6d, 0x73, 0x2e, 0x76, 0x31, 0x22, 0x44, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, 0x45, 0x76, 0x6d, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2f, 0x0a, 0x0f, 0x53, + 0x69, 0x67, 0x6e, 0x45, 0x76, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, + 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x74, 0x0a, 0x0f, + 0x53, 0x69, 0x67, 0x6e, 0x58, 0x72, 0x70, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x41, 0x0a, 0x0e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x66, 0x6b, 0x6d, 0x73, 0x2e, 0x76, + 0x31, 0x2e, 0x58, 0x72, 0x70, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, + 0x61, 0x64, 0x12, 0x1e, 0x0a, 0x03, 0x74, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0c, 0x2e, 0x66, 0x6b, 0x6d, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x73, 0x73, 0x52, 0x03, 0x74, + 0x73, 0x73, 0x22, 0x2b, 0x0a, 0x10, 0x53, 0x69, 0x67, 0x6e, 0x58, 0x72, 0x70, 0x6c, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x62, 0x6c, 0x6f, + 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x78, 0x42, 0x6c, 0x6f, 0x62, 0x22, + 0x74, 0x0a, 0x0f, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x63, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x41, 0x0a, 0x0e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x79, + 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x66, 0x6b, 0x6d, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x63, 0x6f, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, + 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1e, 0x0a, 0x03, 0x74, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x66, 0x6b, 0x6d, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x73, 0x73, + 0x52, 0x03, 0x74, 0x73, 0x73, 0x22, 0x2f, 0x0a, 0x10, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x63, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x78, 0x5f, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x74, 0x78, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x7a, 0x0a, 0x12, 0x53, 0x69, 0x67, 0x6e, 0x53, 0x6f, + 0x72, 0x6f, 0x62, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x0e, + 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x66, 0x6b, 0x6d, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, + 0x6f, 0x72, 0x6f, 0x62, 0x61, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, + 0x61, 0x64, 0x12, 0x1e, 0x0a, 0x03, 0x74, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0c, 0x2e, 0x66, 0x6b, 0x6d, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x73, 0x73, 0x52, 0x03, 0x74, + 0x73, 0x73, 0x22, 0x2e, 0x0a, 0x13, 0x53, 0x69, 0x67, 0x6e, 0x53, 0x6f, 0x72, 0x6f, 0x62, 0x61, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, + 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x78, 0x42, 0x6c, + 0x6f, 0x62, 0x22, 0x1b, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, + 0x48, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, + 0x07, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x66, 0x6b, 0x6d, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x73, + 0x52, 0x07, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x73, 0x22, 0x78, 0x0a, 0x11, 0x58, 0x72, 0x70, + 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x18, + 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x72, 0x61, 0x63, + 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6f, 0x72, 0x61, + 0x63, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x66, 0x65, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x63, 0x65, 0x22, 0x96, 0x01, 0x0a, 0x11, 0x49, 0x63, 0x6f, 0x6e, 0x53, 0x69, 0x67, 0x6e, + 0x65, 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6c, + 0x61, 0x79, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x61, + 0x79, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1d, + 0x0a, 0x0a, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x09, 0x73, 0x74, 0x65, 0x70, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, + 0x0a, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x22, 0xe0, 0x01, 0x0a, + 0x14, 0x53, 0x6f, 0x72, 0x6f, 0x62, 0x61, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x10, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x66, 0x65, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, + 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x73, 0x65, 0x71, + 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x2d, 0x0a, 0x12, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x5f, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x11, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, + 0x72, 0x61, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x70, 0x63, 0x5f, 0x75, 0x72, 0x6c, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x70, 0x63, 0x55, 0x72, 0x6c, 0x73, 0x22, + 0x61, 0x0a, 0x03, 0x54, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x41, 0x64, 0x64, + 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x53, 0x22, 0x5a, 0x0a, 0x07, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x31, 0x0a, + 0x0a, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x12, 0x2e, 0x66, 0x6b, 0x6d, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, + 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x2a, 0x35, + 0x0a, 0x09, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x45, + 0x56, 0x4d, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x58, 0x52, 0x50, 0x4c, 0x10, 0x01, 0x12, 0x08, + 0x0a, 0x04, 0x49, 0x43, 0x4f, 0x4e, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x4f, 0x52, 0x4f, + 0x42, 0x41, 0x4e, 0x10, 0x03, 0x32, 0xf6, 0x02, 0x0a, 0x0b, 0x46, 0x6b, 0x6d, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3c, 0x0a, 0x07, 0x53, 0x69, 0x67, 0x6e, 0x45, 0x76, 0x6d, + 0x12, 0x17, 0x2e, 0x66, 0x6b, 0x6d, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x45, + 0x76, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x66, 0x6b, 0x6d, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x45, 0x76, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x08, 0x53, 0x69, 0x67, 0x6e, 0x58, 0x72, 0x70, 0x6c, 0x12, + 0x18, 0x2e, 0x66, 0x6b, 0x6d, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x58, 0x72, + 0x70, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x66, 0x6b, 0x6d, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x58, 0x72, 0x70, 0x6c, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x08, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x63, 0x6f, 0x6e, + 0x12, 0x18, 0x2e, 0x66, 0x6b, 0x6d, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x49, + 0x63, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x66, 0x6b, 0x6d, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x63, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x53, 0x6f, 0x72, + 0x6f, 0x62, 0x61, 0x6e, 0x12, 0x1b, 0x2e, 0x66, 0x6b, 0x6d, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, + 0x69, 0x67, 0x6e, 0x53, 0x6f, 0x72, 0x6f, 0x62, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1c, 0x2e, 0x66, 0x6b, 0x6d, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, + 0x53, 0x6f, 0x72, 0x6f, 0x62, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x5d, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x22, 0x2e, 0x66, 0x6b, 0x6d, 0x73, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x66, 0x6b, 0x6d, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x35, + 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x6e, + 0x64, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x66, 0x61, 0x6c, 0x63, 0x6f, 0x6e, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x66, 0x6b, 0x6d, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x66, + 0x6b, 0x6d, 0x73, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} var ( file_proto_fkms_v1_signer_proto_rawDescOnce sync.Once - file_proto_fkms_v1_signer_proto_rawDescData []byte + file_proto_fkms_v1_signer_proto_rawDescData = file_proto_fkms_v1_signer_proto_rawDesc ) func file_proto_fkms_v1_signer_proto_rawDescGZIP() []byte { file_proto_fkms_v1_signer_proto_rawDescOnce.Do(func() { - file_proto_fkms_v1_signer_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proto_fkms_v1_signer_proto_rawDesc), len(file_proto_fkms_v1_signer_proto_rawDesc))) + file_proto_fkms_v1_signer_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_fkms_v1_signer_proto_rawDescData) }) return file_proto_fkms_v1_signer_proto_rawDescData } var file_proto_fkms_v1_signer_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_proto_fkms_v1_signer_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_proto_fkms_v1_signer_proto_msgTypes = make([]protoimpl.MessageInfo, 15) var file_proto_fkms_v1_signer_proto_goTypes = []any{ (ChainType)(0), // 0: fkms.v1.ChainType (*SignEvmRequest)(nil), // 1: fkms.v1.SignEvmRequest @@ -763,33 +1031,40 @@ var file_proto_fkms_v1_signer_proto_goTypes = []any{ (*SignXrplResponse)(nil), // 4: fkms.v1.SignXrplResponse (*SignIconRequest)(nil), // 5: fkms.v1.SignIconRequest (*SignIconResponse)(nil), // 6: fkms.v1.SignIconResponse - (*GetSignerAddressesRequest)(nil), // 7: fkms.v1.GetSignerAddressesRequest - (*GetSignerAddressesResponse)(nil), // 8: fkms.v1.GetSignerAddressesResponse - (*XrplSignerPayload)(nil), // 9: fkms.v1.XrplSignerPayload - (*IconSignerPayload)(nil), // 10: fkms.v1.IconSignerPayload - (*Tss)(nil), // 11: fkms.v1.Tss - (*Signers)(nil), // 12: fkms.v1.Signers + (*SignSorobanRequest)(nil), // 7: fkms.v1.SignSorobanRequest + (*SignSorobanResponse)(nil), // 8: fkms.v1.SignSorobanResponse + (*GetSignerAddressesRequest)(nil), // 9: fkms.v1.GetSignerAddressesRequest + (*GetSignerAddressesResponse)(nil), // 10: fkms.v1.GetSignerAddressesResponse + (*XrplSignerPayload)(nil), // 11: fkms.v1.XrplSignerPayload + (*IconSignerPayload)(nil), // 12: fkms.v1.IconSignerPayload + (*SorobanSignerPayload)(nil), // 13: fkms.v1.SorobanSignerPayload + (*Tss)(nil), // 14: fkms.v1.Tss + (*Signers)(nil), // 15: fkms.v1.Signers } var file_proto_fkms_v1_signer_proto_depIdxs = []int32{ - 9, // 0: fkms.v1.SignXrplRequest.signer_payload:type_name -> fkms.v1.XrplSignerPayload - 11, // 1: fkms.v1.SignXrplRequest.tss:type_name -> fkms.v1.Tss - 10, // 2: fkms.v1.SignIconRequest.signer_payload:type_name -> fkms.v1.IconSignerPayload - 11, // 3: fkms.v1.SignIconRequest.tss:type_name -> fkms.v1.Tss - 12, // 4: fkms.v1.GetSignerAddressesResponse.signers:type_name -> fkms.v1.Signers - 0, // 5: fkms.v1.Signers.chain_type:type_name -> fkms.v1.ChainType - 1, // 6: fkms.v1.FkmsService.SignEvm:input_type -> fkms.v1.SignEvmRequest - 3, // 7: fkms.v1.FkmsService.SignXrpl:input_type -> fkms.v1.SignXrplRequest - 5, // 8: fkms.v1.FkmsService.SignIcon:input_type -> fkms.v1.SignIconRequest - 7, // 9: fkms.v1.FkmsService.GetSignerAddresses:input_type -> fkms.v1.GetSignerAddressesRequest - 2, // 10: fkms.v1.FkmsService.SignEvm:output_type -> fkms.v1.SignEvmResponse - 4, // 11: fkms.v1.FkmsService.SignXrpl:output_type -> fkms.v1.SignXrplResponse - 6, // 12: fkms.v1.FkmsService.SignIcon:output_type -> fkms.v1.SignIconResponse - 8, // 13: fkms.v1.FkmsService.GetSignerAddresses:output_type -> fkms.v1.GetSignerAddressesResponse - 10, // [10:14] is the sub-list for method output_type - 6, // [6:10] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 11, // 0: fkms.v1.SignXrplRequest.signer_payload:type_name -> fkms.v1.XrplSignerPayload + 14, // 1: fkms.v1.SignXrplRequest.tss:type_name -> fkms.v1.Tss + 12, // 2: fkms.v1.SignIconRequest.signer_payload:type_name -> fkms.v1.IconSignerPayload + 14, // 3: fkms.v1.SignIconRequest.tss:type_name -> fkms.v1.Tss + 13, // 4: fkms.v1.SignSorobanRequest.signer_payload:type_name -> fkms.v1.SorobanSignerPayload + 14, // 5: fkms.v1.SignSorobanRequest.tss:type_name -> fkms.v1.Tss + 15, // 6: fkms.v1.GetSignerAddressesResponse.signers:type_name -> fkms.v1.Signers + 0, // 7: fkms.v1.Signers.chain_type:type_name -> fkms.v1.ChainType + 1, // 8: fkms.v1.FkmsService.SignEvm:input_type -> fkms.v1.SignEvmRequest + 3, // 9: fkms.v1.FkmsService.SignXrpl:input_type -> fkms.v1.SignXrplRequest + 5, // 10: fkms.v1.FkmsService.SignIcon:input_type -> fkms.v1.SignIconRequest + 7, // 11: fkms.v1.FkmsService.SignSoroban:input_type -> fkms.v1.SignSorobanRequest + 9, // 12: fkms.v1.FkmsService.GetSignerAddresses:input_type -> fkms.v1.GetSignerAddressesRequest + 2, // 13: fkms.v1.FkmsService.SignEvm:output_type -> fkms.v1.SignEvmResponse + 4, // 14: fkms.v1.FkmsService.SignXrpl:output_type -> fkms.v1.SignXrplResponse + 6, // 15: fkms.v1.FkmsService.SignIcon:output_type -> fkms.v1.SignIconResponse + 8, // 16: fkms.v1.FkmsService.SignSoroban:output_type -> fkms.v1.SignSorobanResponse + 10, // 17: fkms.v1.FkmsService.GetSignerAddresses:output_type -> fkms.v1.GetSignerAddressesResponse + 13, // [13:18] is the sub-list for method output_type + 8, // [8:13] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name } func init() { file_proto_fkms_v1_signer_proto_init() } @@ -801,9 +1076,9 @@ func file_proto_fkms_v1_signer_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_fkms_v1_signer_proto_rawDesc), len(file_proto_fkms_v1_signer_proto_rawDesc)), + RawDescriptor: file_proto_fkms_v1_signer_proto_rawDesc, NumEnums: 1, - NumMessages: 12, + NumMessages: 15, NumExtensions: 0, NumServices: 1, }, @@ -813,6 +1088,7 @@ func file_proto_fkms_v1_signer_proto_init() { MessageInfos: file_proto_fkms_v1_signer_proto_msgTypes, }.Build() File_proto_fkms_v1_signer_proto = out.File + file_proto_fkms_v1_signer_proto_rawDesc = nil file_proto_fkms_v1_signer_proto_goTypes = nil file_proto_fkms_v1_signer_proto_depIdxs = nil } diff --git a/proto/fkms/v1/signer.proto b/proto/fkms/v1/signer.proto index 7c6ba39..c2808ae 100644 --- a/proto/fkms/v1/signer.proto +++ b/proto/fkms/v1/signer.proto @@ -8,6 +8,7 @@ service FkmsService { rpc SignEvm(SignEvmRequest) returns (SignEvmResponse); rpc SignXrpl(SignXrplRequest) returns (SignXrplResponse); rpc SignIcon(SignIconRequest) returns (SignIconResponse); + rpc SignSoroban(SignSorobanRequest) returns (SignSorobanResponse); rpc GetSignerAddresses(GetSignerAddressesRequest) returns (GetSignerAddressesResponse); } @@ -38,6 +39,15 @@ message SignIconResponse { bytes tx_params = 1; } +message SignSorobanRequest { + SorobanSignerPayload signer_payload = 1; + Tss tss = 2; +} + +message SignSorobanResponse { + string tx_blob = 1; +} + message GetSignerAddressesRequest {} message GetSignerAddressesResponse { @@ -58,6 +68,15 @@ message IconSignerPayload { string network_id = 4; } +message SorobanSignerPayload { + string source_account = 1; + string contract_address = 2; + string fee = 3; + int64 sequence = 4; + string network_passphrase = 5; + repeated string rpc_urls = 6; +} + message Tss { bytes message = 1; bytes random_addr = 2; @@ -73,4 +92,5 @@ enum ChainType { EVM = 0; XRPL = 1; ICON = 2; + SOROBAN = 3; } diff --git a/proto/fkms/v1/signer_grpc.pb.go b/proto/fkms/v1/signer_grpc.pb.go index f0887a3..c07f2af 100644 --- a/proto/fkms/v1/signer_grpc.pb.go +++ b/proto/fkms/v1/signer_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.5.1 -// - protoc v5.29.3 +// - protoc v6.33.1 // source: proto/fkms/v1/signer.proto package fkmsv1 @@ -22,6 +22,7 @@ const ( FkmsService_SignEvm_FullMethodName = "/fkms.v1.FkmsService/SignEvm" FkmsService_SignXrpl_FullMethodName = "/fkms.v1.FkmsService/SignXrpl" FkmsService_SignIcon_FullMethodName = "/fkms.v1.FkmsService/SignIcon" + FkmsService_SignSoroban_FullMethodName = "/fkms.v1.FkmsService/SignSoroban" FkmsService_GetSignerAddresses_FullMethodName = "/fkms.v1.FkmsService/GetSignerAddresses" ) @@ -32,6 +33,7 @@ type FkmsServiceClient interface { SignEvm(ctx context.Context, in *SignEvmRequest, opts ...grpc.CallOption) (*SignEvmResponse, error) SignXrpl(ctx context.Context, in *SignXrplRequest, opts ...grpc.CallOption) (*SignXrplResponse, error) SignIcon(ctx context.Context, in *SignIconRequest, opts ...grpc.CallOption) (*SignIconResponse, error) + SignSoroban(ctx context.Context, in *SignSorobanRequest, opts ...grpc.CallOption) (*SignSorobanResponse, error) GetSignerAddresses(ctx context.Context, in *GetSignerAddressesRequest, opts ...grpc.CallOption) (*GetSignerAddressesResponse, error) } @@ -73,6 +75,16 @@ func (c *fkmsServiceClient) SignIcon(ctx context.Context, in *SignIconRequest, o return out, nil } +func (c *fkmsServiceClient) SignSoroban(ctx context.Context, in *SignSorobanRequest, opts ...grpc.CallOption) (*SignSorobanResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(SignSorobanResponse) + err := c.cc.Invoke(ctx, FkmsService_SignSoroban_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *fkmsServiceClient) GetSignerAddresses(ctx context.Context, in *GetSignerAddressesRequest, opts ...grpc.CallOption) (*GetSignerAddressesResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(GetSignerAddressesResponse) @@ -90,6 +102,7 @@ type FkmsServiceServer interface { SignEvm(context.Context, *SignEvmRequest) (*SignEvmResponse, error) SignXrpl(context.Context, *SignXrplRequest) (*SignXrplResponse, error) SignIcon(context.Context, *SignIconRequest) (*SignIconResponse, error) + SignSoroban(context.Context, *SignSorobanRequest) (*SignSorobanResponse, error) GetSignerAddresses(context.Context, *GetSignerAddressesRequest) (*GetSignerAddressesResponse, error) mustEmbedUnimplementedFkmsServiceServer() } @@ -110,6 +123,9 @@ func (UnimplementedFkmsServiceServer) SignXrpl(context.Context, *SignXrplRequest func (UnimplementedFkmsServiceServer) SignIcon(context.Context, *SignIconRequest) (*SignIconResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method SignIcon not implemented") } +func (UnimplementedFkmsServiceServer) SignSoroban(context.Context, *SignSorobanRequest) (*SignSorobanResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SignSoroban not implemented") +} func (UnimplementedFkmsServiceServer) GetSignerAddresses(context.Context, *GetSignerAddressesRequest) (*GetSignerAddressesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetSignerAddresses not implemented") } @@ -188,6 +204,24 @@ func _FkmsService_SignIcon_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } +func _FkmsService_SignSoroban_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SignSorobanRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(FkmsServiceServer).SignSoroban(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: FkmsService_SignSoroban_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(FkmsServiceServer).SignSoroban(ctx, req.(*SignSorobanRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _FkmsService_GetSignerAddresses_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetSignerAddressesRequest) if err := dec(in); err != nil { @@ -225,6 +259,10 @@ var FkmsService_ServiceDesc = grpc.ServiceDesc{ MethodName: "SignIcon", Handler: _FkmsService_SignIcon_Handler, }, + { + MethodName: "SignSoroban", + Handler: _FkmsService_SignSoroban_Handler, + }, { MethodName: "GetSignerAddresses", Handler: _FkmsService_GetSignerAddresses_Handler, diff --git a/relayer/chains/soroban/client.go b/relayer/chains/soroban/client.go new file mode 100644 index 0000000..48e03a8 --- /dev/null +++ b/relayer/chains/soroban/client.go @@ -0,0 +1,325 @@ +package soroban + +import ( + "context" + "errors" + "fmt" + "math/big" + "net/http" + "strings" + "sync" + "time" + + "github.com/shopspring/decimal" + "github.com/stellar/go-stellar-sdk/clients/horizonclient" + hProtocol "github.com/stellar/go-stellar-sdk/protocols/horizon" + + "github.com/bandprotocol/falcon/relayer/alert" + "github.com/bandprotocol/falcon/relayer/chains" + "github.com/bandprotocol/falcon/relayer/logger" +) + +// HorizonClients holds Horizon RPC clients and the selected endpoint. +type HorizonClients = chains.ClientPool[horizonclient.Client] + +// NewHorizonClients creates and returns a new SorobanClients instance with no endpoints. +func NewHorizonClients() HorizonClients { + return chains.NewClientPool[horizonclient.Client]() +} + +// ClientConnectionResult contains the result of connecting to a specific Horizon endpoint. +type ClientConnectionResult struct { + Endpoint string + Client *horizonclient.Client + LedgerSequence uint64 +} + +type Client interface { + Connect(ctx context.Context) error + CheckAndConnect(ctx context.Context) error + StartLivelinessCheck(ctx context.Context, interval time.Duration) + GetAccountSequenceNumber(account string) (int64, error) + GetBalance(account string) (*big.Int, error) + BroadcastTx(txBlob string) (TxResult, error) + GetLedgerCloseTime(ledgerIndex uint64) (*time.Time, error) + GetTransactionStatus(txHash string) (hProtocol.Transaction, error) +} + +type client struct { + ChainName string + HorizonEndpoints []string + QueryTimeout time.Duration + + Log logger.Logger + alert alert.Alert + + clients HorizonClients +} + +func NewClient(chainName string, cfg *SorobanChainProviderConfig, log logger.Logger, alert alert.Alert) Client { + return &client{ + ChainName: chainName, + HorizonEndpoints: cfg.HorizonEndpoints, + QueryTimeout: cfg.QueryTimeout, + Log: log.With("chain_name", chainName), + alert: alert, + clients: NewHorizonClients(), + } +} + +// Connect connects to all Horizon endpoints in parallel and selects the one with the highest ledger. +func (c *client) Connect(ctx context.Context) error { + var wg sync.WaitGroup + for _, endpoint := range c.HorizonEndpoints { + _, ok := c.clients.GetClient(endpoint) + if ok { + continue + } + + wg.Add(1) + go func(endpoint string) { + defer wg.Done() + hc := &horizonclient.Client{ + HorizonURL: strings.TrimRight(endpoint, "/"), + HTTP: &http.Client{Timeout: c.QueryTimeout}, + } + if _, err := hc.Root(); err != nil { + c.Log.Warn( + "Failed to connect to Soroban chain", + "endpoint", endpoint, + err, + ) + alert.HandleAlert( + c.alert, + alert.NewTopic(alert.ConnectSingleChainClientErrorMsg). + WithChainName(c.ChainName). + WithEndpoint(endpoint), + err.Error(), + ) + return + } + alert.HandleReset( + c.alert, + alert.NewTopic(alert.ConnectSingleChainClientErrorMsg). + WithChainName(c.ChainName). + WithEndpoint(endpoint), + ) + c.clients.SetClient(endpoint, hc) + }(endpoint) + } + + wg.Wait() + res, err := c.getClientWithMaxLedger(ctx) + if err != nil { + c.Log.Error("Failed to connect to Soroban chain", err) + return err + } + + // only log when new endpoint is used + if c.clients.GetSelectedEndpoint() != res.Endpoint { + c.Log.Info("Connected to Soroban chain", "endpoint", res.Endpoint) + } + + c.clients.SetSelectedEndpoint(res.Endpoint) + return nil +} + +// CheckAndConnect checks if the client is connected; if not, it connects. +func (c *client) CheckAndConnect(ctx context.Context) error { + if _, err := c.clients.GetSelectedClient(); err != nil { + return c.Connect(ctx) + } + return nil +} + +// StartLivelinessCheck starts the liveliness check for the Soroban chain. +func (c *client) StartLivelinessCheck(ctx context.Context, interval time.Duration) { + ticker := time.NewTicker(interval) + defer ticker.Stop() + + for { + select { + case <-ctx.Done(): + c.Log.Info("Stopping liveliness check") + return + case <-ticker.C: + err := c.Connect(ctx) + if err != nil { + c.Log.Error("Liveliness check: unable to reconnect to any endpoints", err) + } + } + } +} + +// getClientWithMaxLedger returns the connected client with the highest ingested ledger sequence. +func (c *client) getClientWithMaxLedger(ctx context.Context) (ClientConnectionResult, error) { + ch := make(chan ClientConnectionResult, len(c.HorizonEndpoints)) + + for _, endpoint := range c.HorizonEndpoints { + go func(endpoint string) { + hc, ok := c.clients.GetClient(endpoint) + if !ok { + ch <- ClientConnectionResult{endpoint, nil, 0} + return + } + + root, err := hc.Root() + if err != nil { + c.Log.Warn( + "Failed to get latest ledger", + "endpoint", endpoint, + err, + ) + ch <- ClientConnectionResult{endpoint, nil, 0} + alert.HandleAlert( + c.alert, + alert.NewTopic(alert.ConnectSingleChainClientErrorMsg). + WithChainName(c.ChainName). + WithEndpoint(endpoint), + err.Error(), + ) + return + } + + ledgerSeq := uint64(root.IngestSequence) + c.Log.Debug( + "Get latest ledger of the given client", + "endpoint", endpoint, + "ledger_sequence", ledgerSeq, + ) + alert.HandleReset( + c.alert, + alert.NewTopic(alert.ConnectSingleChainClientErrorMsg). + WithChainName(c.ChainName). + WithEndpoint(endpoint), + ) + + ch <- ClientConnectionResult{endpoint, hc, ledgerSeq} + }(endpoint) + } + + var result ClientConnectionResult + for i := 0; i < len(c.HorizonEndpoints); i++ { + r := <-ch + if r.Client != nil { + if r.LedgerSequence > result.LedgerSequence || + (r.Endpoint == c.clients.GetSelectedEndpoint() && r.LedgerSequence == result.LedgerSequence) { + result = r + } + } + } + + if result.Client == nil { + alert.HandleAlert( + c.alert, + alert.NewTopic(alert.ConnectAllChainClientErrorMsg).WithChainName(c.ChainName), + fmt.Sprintf("failed to connect to Soroban chain on all endpoints: %s", c.HorizonEndpoints), + ) + return ClientConnectionResult{}, fmt.Errorf("[SorobanClient] failed to connect to Soroban chain") + } + + alert.HandleReset(c.alert, alert.NewTopic(alert.ConnectAllChainClientErrorMsg).WithChainName(c.ChainName)) + return result, nil +} + +func (c *client) GetAccountSequenceNumber(account string) (int64, error) { + hc, err := c.clients.GetSelectedClient() + if err != nil { + c.Log.Error("Failed to get client", "endpoint", c.clients.GetSelectedEndpoint(), err) + return 0, fmt.Errorf("[SorobanClient] failed to get client: %w", err) + } + + acc, err := hc.AccountDetail(horizonclient.AccountRequest{AccountID: account}) + if err != nil { + return 0, fmt.Errorf("failed to fetch account: %w", err) + } + + seq, err := acc.GetSequenceNumber() + if err != nil { + return 0, fmt.Errorf("failed to get sequence number: %w", err) + } + + if seq < 0 { + return 0, fmt.Errorf("negative sequence number: %d", seq) + } + + return seq, nil +} + +func (c *client) GetBalance(account string) (*big.Int, error) { + hc, err := c.clients.GetSelectedClient() + if err != nil { + c.Log.Error("Failed to get client", "endpoint", c.clients.GetSelectedEndpoint(), err) + return nil, fmt.Errorf("[SorobanClient] failed to get client: %w", err) + } + + acc, err := hc.AccountDetail(horizonclient.AccountRequest{AccountID: account}) + if err != nil { + return nil, fmt.Errorf("failed to fetch account: %w", err) + } + + native, err := acc.GetNativeBalance() + if err != nil { + return nil, fmt.Errorf("failed to get native balance: %w", err) + } + + // Convert "10.1234567" to stroops (x 10^7) using exact decimal arithmetic. + d, err := decimal.NewFromString(native) + if err != nil { + return nil, fmt.Errorf("failed to parse balance %q: %w", native, err) + } + stroops := d.Mul(decimal.NewFromInt(1e7)).BigInt() + return stroops, nil +} + +func (c *client) BroadcastTx(txBlob string) (TxResult, error) { + hc, err := c.clients.GetSelectedClient() + if err != nil { + c.Log.Error("Failed to get client", "endpoint", c.clients.GetSelectedEndpoint(), err) + return TxResult{}, fmt.Errorf("[SorobanClient] failed to get client: %w", err) + } + + resp, err := hc.SubmitTransactionXDR(txBlob) + if err != nil { + var herr *horizonclient.Error + if errors.As(err, &herr) { + rc, _ := herr.ResultCodes() + c.Log.Error("horizon submission failed", + "status", herr.Problem.Status, + "result_codes", rc, + "result_xdr", herr.Problem.Extras["result_xdr"], + ) + return TxResult{}, fmt.Errorf("failed to submit transaction: status=%d codes=%+v xdr=%s", + herr.Problem.Status, rc, herr.Problem.Extras["result_xdr"]) + } + return TxResult{}, fmt.Errorf("failed to submit transaction: %w", err) + } + + return TxResult{TxHash: resp.Hash}, nil +} + +func (c *client) GetLedgerCloseTime(ledgerIndex uint64) (*time.Time, error) { + hc, err := c.clients.GetSelectedClient() + if err != nil { + c.Log.Error("Failed to get client", "endpoint", c.clients.GetSelectedEndpoint(), err) + return nil, fmt.Errorf("[SorobanClient] failed to get client: %w", err) + } + + ledger, err := hc.LedgerDetail(uint32(ledgerIndex)) + if err != nil { + return nil, fmt.Errorf("failed to fetch ledger %d: %w", ledgerIndex, err) + } + + t := ledger.ClosedAt + return &t, nil +} + +func (c *client) GetTransactionStatus(txHash string) (hProtocol.Transaction, error) { + hc, err := c.clients.GetSelectedClient() + if err != nil { + c.Log.Error("Failed to get client", "endpoint", c.clients.GetSelectedEndpoint(), err) + return hProtocol.Transaction{}, fmt.Errorf("[SorobanClient] failed to get client: %w", err) + } + + return hc.TransactionDetail(txHash) +} diff --git a/relayer/chains/soroban/config.go b/relayer/chains/soroban/config.go new file mode 100644 index 0000000..738f63d --- /dev/null +++ b/relayer/chains/soroban/config.go @@ -0,0 +1,40 @@ +package soroban + +import ( + "time" + + "github.com/bandprotocol/falcon/relayer/alert" + "github.com/bandprotocol/falcon/relayer/chains" + "github.com/bandprotocol/falcon/relayer/chains/types" + "github.com/bandprotocol/falcon/relayer/logger" + "github.com/bandprotocol/falcon/relayer/wallet" +) + +var _ chains.ChainProviderConfig = &SorobanChainProviderConfig{} + +// SorobanChainProviderConfig is the configuration for the Soroban chain provider. +type SorobanChainProviderConfig struct { + chains.BaseChainProviderConfig `mapstructure:",squash"` + + HorizonEndpoints []string `mapstructure:"horizon_endpoints" toml:"horizon_endpoints"` + Fee string `mapstructure:"fee" toml:"fee"` + NetworkPassphrase string `mapstructure:"network_passphrase" toml:"network_passphrase"` + WaitingTxDuration time.Duration `mapstructure:"waiting_tx_duration" toml:"waiting_tx_duration"` + CheckingTxInterval time.Duration `mapstructure:"checking_tx_interval" toml:"checking_tx_interval"` +} + +// NewChainProvider creates a new Soroban chain provider. +func (cpc *SorobanChainProviderConfig) NewChainProvider( + chainName string, + log logger.Logger, + wallet wallet.Wallet, + alert alert.Alert, +) (chains.ChainProvider, error) { + client := NewClient(chainName, cpc, log, alert) + + return NewSorobanChainProvider(chainName, client, cpc, log, wallet, alert), nil +} + +func (cpc *SorobanChainProviderConfig) GetChainType() types.ChainType { + return types.ChainTypeSoroban +} diff --git a/relayer/chains/soroban/provider.go b/relayer/chains/soroban/provider.go new file mode 100644 index 0000000..2b7e61d --- /dev/null +++ b/relayer/chains/soroban/provider.go @@ -0,0 +1,396 @@ +package soroban + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + "time" + + "github.com/shopspring/decimal" + + "github.com/bandprotocol/falcon/internal/relayermetrics" + "github.com/bandprotocol/falcon/relayer/alert" + bandtypes "github.com/bandprotocol/falcon/relayer/band/types" + "github.com/bandprotocol/falcon/relayer/chains" + "github.com/bandprotocol/falcon/relayer/chains/types" + "github.com/bandprotocol/falcon/relayer/db" + "github.com/bandprotocol/falcon/relayer/logger" + "github.com/bandprotocol/falcon/relayer/wallet" + "github.com/bandprotocol/falcon/relayer/wallet/soroban" +) + +const sorobanToWeiExp = 11 + +var _ chains.ChainProvider = (*SorobanChainProvider)(nil) + +// TxResult holds the outcome of a relayed transaction. +type TxResult struct { + Status types.TxStatus + TxHash string + LedgerIndex uint64 + Fee decimal.NullDecimal + FailureReason string +} + +// NewTxResult creates a TxResult with the given fields. +func NewTxResult( + status types.TxStatus, + txHash string, + ledgerIndex uint64, + fee decimal.NullDecimal, + failureReason string, +) TxResult { + return TxResult{ + Status: status, + TxHash: txHash, + LedgerIndex: ledgerIndex, + Fee: fee, + FailureReason: failureReason, + } +} + +// SorobanChainProvider handles interactions with Soroban. +type SorobanChainProvider struct { + Config *SorobanChainProviderConfig + ChainName string + + Client Client + Log logger.Logger + DB db.Database + Alert alert.Alert + + FreeSigners chan wallet.Signer + Wallet wallet.Wallet +} + +// NewSorobanChainProvider creates a new Soroban chain provider. +func NewSorobanChainProvider( + chainName string, + client Client, + cfg *SorobanChainProviderConfig, + log logger.Logger, + w wallet.Wallet, + a alert.Alert, +) *SorobanChainProvider { + return &SorobanChainProvider{ + Config: cfg, + ChainName: chainName, + Client: client, + Log: log.With("chain_name", chainName), + Alert: a, + FreeSigners: chains.LoadSigners(w), + Wallet: w, + } +} + +func (cp *SorobanChainProvider) Init(ctx context.Context) error { + if err := cp.Client.Connect(ctx); err != nil { + return err + } + go cp.Client.StartLivelinessCheck(ctx, cp.Config.LivelinessCheckingInterval) + return nil +} + +func (cp *SorobanChainProvider) SetDatabase(database db.Database) { + cp.DB = database +} + +func (cp *SorobanChainProvider) QueryTunnelInfo( + _ context.Context, + tunnelID uint64, + tunnelDestinationAddr string, +) (*types.Tunnel, error) { + // Soroban uses Skippable tunnels without sequence tracking similar to XRPL + tunnel := types.NewTunnel(tunnelID, tunnelDestinationAddr, true, nil, nil) + return tunnel, nil +} + +func (cp *SorobanChainProvider) RelayPacket(ctx context.Context, packet *bandtypes.Packet) error { + if err := cp.Client.CheckAndConnect(ctx); err != nil { + return fmt.Errorf("[SorobanProvider] failed to connect client: %w", err) + } + + // get a free signer + cp.Log.Debug("Waiting for a free signer...") + freeSigner := <-cp.FreeSigners + defer func() { cp.FreeSigners <- freeSigner }() + + log := cp.Log.With( + "tunnel_id", packet.TunnelID, + "sequence", packet.Sequence, + "signer_address", freeSigner.GetAddress(), + ) + + var lastErr error + for retryCount := 1; retryCount <= cp.Config.MaxRetry; retryCount++ { + log.Info("Relaying a message", "retry_count", retryCount) + + sequence, err := cp.Client.GetAccountSequenceNumber(freeSigner.GetAddress()) + if err != nil { + log.Error("Get account sequence number error", "retry_count", retryCount, err) + lastErr = err + time.Sleep(2 * time.Second) + continue + } + sequence++ + + signing, err := chains.SelectSigning(packet) + if err != nil { + log.Error("Select signing error", "retry_count", retryCount, err) + lastErr = err + continue + } + + signerPayload := soroban.NewSignerPayload( + freeSigner.GetAddress(), + packet.TargetAddress, + cp.Config.Fee, + sequence, + cp.Config.NetworkPassphrase, + cp.Config.Endpoints, + ) + + payloadBytes, err := json.Marshal(signerPayload) + if err != nil { + log.Error("Marshal signer payload error", "retry_count", retryCount, err) + lastErr = err + continue + } + + rAddress, signature := chains.ExtractEVMSignature(signing.EVMSignature) + tssPayload := wallet.NewTssPayload( + signing.Message, + rAddress, + signature, + ) + + result, err := freeSigner.Sign(payloadBytes, tssPayload) + if err != nil { + log.Error("Sign transaction error", "retry_count", retryCount, err) + lastErr = err + continue + } + txBlob := string(result) + + var balance *big.Int + if cp.DB != nil { + balance, err = cp.Client.GetBalance(freeSigner.GetAddress()) + if err != nil { + log.Error("Failed to get balance", "retry_count", retryCount, err) + alert.HandleAlert(cp.Alert, alert.NewTopic(alert.GetBalanceErrorMsg). + WithTunnelID(packet.TunnelID). + WithChainName(cp.ChainName), err.Error()) + } else { + alert.HandleReset(cp.Alert, alert.NewTopic(alert.GetBalanceErrorMsg). + WithTunnelID(packet.TunnelID). + WithChainName(cp.ChainName)) + } + } + + broadcastResult, err := cp.Client.BroadcastTx(txBlob) + if err != nil { + log.Error("Broadcast transaction error", "retry_count", retryCount, err) + lastErr = err + time.Sleep(2 * time.Second) + continue + } + + createdAt := time.Now() + + log.Info( + "Submitted a message; checking transaction status", + "tx_hash", broadcastResult.TxHash, + "retry_count", retryCount, + ) + + // save pending tx in db + if cp.DB != nil { + pending := NewTxResult(types.TX_STATUS_PENDING, broadcastResult.TxHash, 0, decimal.NullDecimal{}, "") + cp.handleSaveTransaction(pending, freeSigner.GetAddress(), packet, balance, log, retryCount) + } + + txResult := cp.WaitForConfirmedTx(broadcastResult.TxHash, log) + + cp.handleMetrics(packet.TunnelID, createdAt, txResult) + cp.handleSaveTransaction(txResult, freeSigner.GetAddress(), packet, balance, log, retryCount) + + if txResult.Status == types.TX_STATUS_SUCCESS { + log.Info( + "Packet is successfully relayed", + "tx_hash", txResult.TxHash, + "retry_count", retryCount, + ) + alert.HandleReset( + cp.Alert, + alert.NewTopic(alert.RelayTxErrorMsg).WithTunnelID(packet.TunnelID).WithChainName(cp.ChainName), + ) + return nil + } + + lastErr = fmt.Errorf("%s", txResult.FailureReason) + log.Error( + "Failed to relay packet", + "status", txResult.Status.String(), + "tx_hash", txResult.TxHash, + "retry_count", retryCount, + lastErr, + ) + + time.Sleep(2 * time.Second) + } + + alert.HandleAlert( + cp.Alert, + alert.NewTopic(alert.RelayTxErrorMsg).WithTunnelID(packet.TunnelID).WithChainName(cp.ChainName), + lastErr.Error(), + ) + return fmt.Errorf("[SorobanProvider] failed to relay packet after %d attempts", cp.Config.MaxRetry) +} + +// CheckConfirmedTx checks whether the submitted tx is confirmed on-chain. +// Returns PENDING if not yet found, SUCCESS if confirmed, FAILED if tx failed. +func (cp *SorobanChainProvider) CheckConfirmedTx(txHash string) (TxResult, error) { + tx, err := cp.Client.GetTransactionStatus(txHash) + if err != nil { + return NewTxResult(types.TX_STATUS_PENDING, txHash, 0, decimal.NullDecimal{}, err.Error()), err + } + + fee := decimal.NewNullDecimal(decimal.NewFromInt(tx.FeeCharged)) + + if tx.Successful { + return NewTxResult(types.TX_STATUS_SUCCESS, tx.Hash, uint64(tx.Ledger), fee, ""), nil + } + return NewTxResult(types.TX_STATUS_FAILED, tx.Hash, uint64(tx.Ledger), fee, "transaction failed on-chain"), nil +} + +// WaitForConfirmedTx polls CheckConfirmedTx until the transaction is confirmed or +// WaitingTxDuration elapses. It never returns an error — on timeout the result has +// Status == TX_STATUS_TIMEOUT and FailureReason set accordingly. +func (cp *SorobanChainProvider) WaitForConfirmedTx(txHash string, log logger.Logger) TxResult { + createdAt := time.Now() + var lastErr error + for time.Since(createdAt) <= cp.Config.WaitingTxDuration { + result, err := cp.CheckConfirmedTx(txHash) + if err != nil { + lastErr = err + log.Debug("Failed to check tx status", "tx_hash", txHash, err) + } + + switch result.Status { + case types.TX_STATUS_SUCCESS, types.TX_STATUS_FAILED: + return result + case types.TX_STATUS_PENDING: + log.Debug("Waiting for tx to be confirmed", "tx_hash", txHash) + time.Sleep(cp.Config.CheckingTxInterval) + } + } + + failureReason := fmt.Sprintf("timed out waiting %s for tx %s", cp.Config.WaitingTxDuration, txHash) + if lastErr != nil { + failureReason = fmt.Sprintf("%s: %v", failureReason, lastErr) + } + return NewTxResult(types.TX_STATUS_TIMEOUT, txHash, 0, decimal.NullDecimal{}, failureReason) +} + +// handleMetrics increments tx count and records processing time for confirmed txs. +func (cp *SorobanChainProvider) handleMetrics(tunnelID uint64, createdAt time.Time, txResult TxResult) { + relayermetrics.IncTxsCount(tunnelID, cp.ChainName, types.ChainTypeSoroban.String(), txResult.Status.String()) + + switch txResult.Status { + case types.TX_STATUS_SUCCESS, types.TX_STATUS_FAILED: + relayermetrics.ObserveTxProcessTime( + tunnelID, + cp.ChainName, + types.ChainTypeSoroban.String(), + txResult.Status.String(), + time.Since(createdAt).Milliseconds(), + ) + } +} + +func (cp *SorobanChainProvider) QueryBalance(ctx context.Context, address string) (*big.Int, error) { + return cp.Client.GetBalance(address) +} + +func (cp *SorobanChainProvider) GetChainName() string { return cp.ChainName } +func (cp *SorobanChainProvider) ChainType() types.ChainType { return types.ChainTypeSoroban } +func (cp *SorobanChainProvider) GetWallet() wallet.Wallet { return cp.Wallet } + +func (cp *SorobanChainProvider) handleSaveTransaction( + txResult TxResult, + signerAddress string, + packet *bandtypes.Packet, + oldBalance *big.Int, + log logger.Logger, + retryCount int, +) { + if cp.DB == nil || txResult.TxHash == "" { + return + } + + var signalPrices []db.SignalPrice + for _, p := range packet.SignalPrices { + signalPrices = append(signalPrices, *db.NewSignalPrice(p.SignalID, p.Price)) + } + + balanceDelta := decimal.NullDecimal{} + gasUsed := decimal.NullDecimal{} + fee := decimal.NullDecimal{} + if oldBalance != nil && (txResult.Status == types.TX_STATUS_SUCCESS || txResult.Status == types.TX_STATUS_FAILED) { + gasUsed = decimal.NewNullDecimal(decimal.NewFromInt(1)) + newBalance, err := cp.Client.GetBalance(signerAddress) + if txResult.Fee.Valid { + fee = decimal.NewNullDecimal(txResult.Fee.Decimal.Shift(sorobanToWeiExp)) + } + if err != nil { + log.Error("Failed to get balance", "retry_count", retryCount, err) + alert.HandleAlert(cp.Alert, alert.NewTopic(alert.GetBalanceErrorMsg). + WithTunnelID(packet.TunnelID). + WithChainName(cp.ChainName), err.Error()) + } else { + diff := new(big.Int).Sub(newBalance, oldBalance) + balanceDelta = decimal.NewNullDecimal(decimal.NewFromBigInt(diff, sorobanToWeiExp)) + } + } + + var closeTime *time.Time + if txResult.LedgerIndex != 0 { + ledgerCloseTime, err := cp.Client.GetLedgerCloseTime(txResult.LedgerIndex) + if err != nil { + log.Error( + "Failed to get ledger close time", + "retry_count", + retryCount, + "ledger_index", + txResult.LedgerIndex, + err, + ) + alert.HandleAlert(cp.Alert, alert.NewTopic(alert.GetLedgerCloseTimeErrorMsg). + WithTunnelID(packet.TunnelID). + WithChainName(cp.ChainName), err.Error()) + } else { + closeTime = ledgerCloseTime + alert.HandleReset(cp.Alert, alert.NewTopic(alert.GetLedgerCloseTimeErrorMsg). + WithTunnelID(packet.TunnelID). + WithChainName(cp.ChainName)) + } + } + + tx := db.NewTransaction( + txResult.TxHash, + packet.TunnelID, + packet.Sequence, + cp.ChainName, + types.ChainTypeSoroban, + signerAddress, + txResult.Status, + gasUsed, + fee, + balanceDelta, + signalPrices, + closeTime, + ) + + chains.HandleSaveTransaction(cp.DB, cp.Alert, tx, log) +} diff --git a/relayer/chains/soroban/provider_test.go b/relayer/chains/soroban/provider_test.go new file mode 100644 index 0000000..aa3127c --- /dev/null +++ b/relayer/chains/soroban/provider_test.go @@ -0,0 +1,192 @@ +package soroban_test + +import ( + "context" + "testing" + "time" + + cmbytes "github.com/cometbft/cometbft/libs/bytes" + "github.com/shopspring/decimal" + hProtocol "github.com/stellar/go-stellar-sdk/protocols/horizon" + "github.com/stretchr/testify/suite" + "go.uber.org/mock/gomock" + "go.uber.org/zap" + + "github.com/bandprotocol/falcon/internal/bandchain/tss" + "github.com/bandprotocol/falcon/internal/relayertest/mocks" + bandtypes "github.com/bandprotocol/falcon/relayer/band/types" + "github.com/bandprotocol/falcon/relayer/chains" + "github.com/bandprotocol/falcon/relayer/chains/soroban" + chaintypes "github.com/bandprotocol/falcon/relayer/chains/types" + "github.com/bandprotocol/falcon/relayer/logger" + walletsoroban "github.com/bandprotocol/falcon/relayer/wallet/soroban" +) + +var baseSorobanCfg = &soroban.SorobanChainProviderConfig{ + BaseChainProviderConfig: chains.BaseChainProviderConfig{ + Endpoints: []string{"http://localhost:8545"}, + ChainType: chaintypes.ChainTypeSoroban, + MaxRetry: 3, + QueryTimeout: 3 * time.Second, + ExecuteTimeout: 3 * time.Second, + LivelinessCheckingInterval: 15 * time.Minute, + }, + HorizonEndpoints: []string{"https://horizon-testnet.stellar.org"}, + Fee: "100", + NetworkPassphrase: "Test SDF Network ; September 2015", + WaitingTxDuration: time.Second * 3, + CheckingTxInterval: time.Second, +} + +func mockPacket() bandtypes.Packet { + relatedMsg := cmbytes.HexBytes("0xdeadbeef") + rAddr := cmbytes.HexBytes("0xfad9c8855b740a0b7ed4c221dbad0f33a83a49ca") + signature := cmbytes.HexBytes("0xabcd") + + evmSignature := bandtypes.NewEVMSignature(rAddr, signature) + signingInfo := bandtypes.NewSigning( + 1, + relatedMsg, + evmSignature, + tss.SIGNING_STATUS_SUCCESS, + ) + + return bandtypes.Packet{ + TunnelID: 1, + Sequence: 42, + TargetAddress: "GBV4CVR37D6TCX3I7FVSVUX2R6EIOH2AODVQLYY3474FUTG3YNDJ6P75", + SignalPrices: []bandtypes.SignalPrice{ + {SignalID: "signal1", Price: 100}, + {SignalID: "signal2", Price: 200}, + }, + CurrentGroupSigning: signingInfo, + IncomingGroupSigning: nil, + } +} + +type ProviderTestSuite struct { + suite.Suite + + ctrl *gomock.Controller + chainProvider *soroban.SorobanChainProvider + client *mocks.MockSorobanClient + log *zap.Logger + homePath string + chainName string +} + +func TestProviderTestSuite(t *testing.T) { + suite.Run(t, new(ProviderTestSuite)) +} + +func (s *ProviderTestSuite) SetupTest() { + var err error + tmpDir := s.T().TempDir() + s.homePath = tmpDir + + s.ctrl = gomock.NewController(s.T()) + s.client = mocks.NewMockSorobanClient(s.ctrl) + + s.log = zap.NewNop() + + s.chainName = "soroban-testnet" + + wallet, err := walletsoroban.NewWallet("", s.homePath, s.chainName) + s.Require().NoError(err) + + log := logger.NewZapLogWrapper(zap.NewNop().Sugar()) + s.chainProvider = soroban.NewSorobanChainProvider(s.chainName, s.client, baseSorobanCfg, log, wallet, nil) + + s.chainProvider.Client = s.client +} + +func (s *ProviderTestSuite) TestQueryTunnelInfo() { + tunnelID := uint64(1) + tunnelAddr := "GBV4CVR37D6TCX3I7FVSVUX2R6EIOH2AODVQLYY3474FUTG3YNDJ6P75" + + tunnel, err := s.chainProvider.QueryTunnelInfo(context.Background(), tunnelID, tunnelAddr) + s.Require().NoError(err) + s.Require().Equal(tunnelID, tunnel.ID) + s.Require().Equal(tunnelAddr, tunnel.TargetAddress) + s.Require().True(tunnel.IsActive) + s.Require().Nil(tunnel.LatestSequence) + s.Require().Nil(tunnel.Balance) +} + +func (s *ProviderTestSuite) TestCheckConfirmedTx() { + txHash := "abc123" + + testcases := []struct { + name string + preProcess func() + err error + out soroban.TxResult + }{ + { + name: "success", + preProcess: func() { + s.client.EXPECT().GetTransactionStatus(txHash).Return(hProtocol.Transaction{ + Hash: txHash, + Ledger: 100, + FeeCharged: 100, + Successful: true, + }, nil) + }, + out: soroban.NewTxResult( + chaintypes.TX_STATUS_SUCCESS, + txHash, + 100, + decimal.NewNullDecimal(decimal.NewFromInt(100)), + "", + ), + }, + { + name: "transaction failed", + preProcess: func() { + s.client.EXPECT().GetTransactionStatus(txHash).Return(hProtocol.Transaction{ + Hash: txHash, + Ledger: 100, + FeeCharged: 100, + Successful: false, + }, nil) + }, + out: soroban.NewTxResult( + chaintypes.TX_STATUS_FAILED, + txHash, + 100, + decimal.NewNullDecimal(decimal.NewFromInt(100)), + "transaction failed on-chain", + ), + }, + { + name: "client error", + preProcess: func() { + s.client.EXPECT().GetTransactionStatus(txHash).Return(hProtocol.Transaction{}, context.DeadlineExceeded) + }, + err: context.DeadlineExceeded, + out: soroban.NewTxResult( + chaintypes.TX_STATUS_PENDING, + txHash, + 0, + decimal.NullDecimal{}, + context.DeadlineExceeded.Error(), + ), + }, + } + + for _, tc := range testcases { + s.Run(tc.name, func() { + if tc.preProcess != nil { + tc.preProcess() + } + + res, err := s.chainProvider.CheckConfirmedTx(txHash) + if tc.err != nil { + s.Require().ErrorIs(err, tc.err) + } else { + s.Require().NoError(err) + } + s.Require().Equal(tc.out, res) + }) + } +} diff --git a/relayer/chains/types/chain_type.go b/relayer/chains/types/chain_type.go index e5165e5..f249e04 100644 --- a/relayer/chains/types/chain_type.go +++ b/relayer/chains/types/chain_type.go @@ -17,12 +17,14 @@ const ( ChainTypeEVM ChainTypeXRPL ChainTypeIcon + ChainTypeSoroban ) var chainTypeNameMap = map[ChainType]string{ - ChainTypeEVM: "evm", - ChainTypeXRPL: "xrpl", - ChainTypeIcon: "icon", + ChainTypeEVM: "evm", + ChainTypeXRPL: "xrpl", + ChainTypeIcon: "icon", + ChainTypeSoroban: "soroban", } var nameToChainTypeMap map[string]ChainType diff --git a/relayer/config/config.go b/relayer/config/config.go index e09bff8..29f1499 100644 --- a/relayer/config/config.go +++ b/relayer/config/config.go @@ -13,6 +13,7 @@ import ( "github.com/bandprotocol/falcon/relayer/chains" "github.com/bandprotocol/falcon/relayer/chains/evm" "github.com/bandprotocol/falcon/relayer/chains/icon" + "github.com/bandprotocol/falcon/relayer/chains/soroban" chainstypes "github.com/bandprotocol/falcon/relayer/chains/types" "github.com/bandprotocol/falcon/relayer/chains/xrpl" ) @@ -105,6 +106,20 @@ func ParseChainProviderConfig(w ChainProviderConfigWrapper) (chains.ChainProvide return nil, err } + cfg = &newCfg + case chainstypes.ChainTypeSoroban: + var newCfg soroban.SorobanChainProviderConfig + + decoderConfig.Result = &newCfg + decoder, err := mapstructure.NewDecoder(&decoderConfig) + if err != nil { + return nil, err + } + + if err := decoder.Decode(w); err != nil { + return nil, err + } + cfg = &newCfg default: return cfg, fmt.Errorf("unsupported chain type: %s", typeName) diff --git a/relayer/db/migrations/postgres/00005_add_soroban_chain_type.sql b/relayer/db/migrations/postgres/00005_add_soroban_chain_type.sql new file mode 100644 index 0000000..493fc1b --- /dev/null +++ b/relayer/db/migrations/postgres/00005_add_soroban_chain_type.sql @@ -0,0 +1,7 @@ +-- +goose Up +ALTER TYPE chain_type ADD VALUE IF NOT EXISTS 'soroban'; + +-- +goose Down +-- NOTE: PostgreSQL does not support removing values from an ENUM type. +-- To "undo" this, would typically have to drop and recreate the type, +-- which is dangerous if data already exists. diff --git a/relayer/db/migrations/sqlite/00001_create_transactions.sql b/relayer/db/migrations/sqlite/00001_create_transactions.sql index d04541f..de283a4 100644 --- a/relayer/db/migrations/sqlite/00001_create_transactions.sql +++ b/relayer/db/migrations/sqlite/00001_create_transactions.sql @@ -7,7 +7,7 @@ CREATE TABLE transactions ( tunnel_id INTEGER NOT NULL, sequence INTEGER NOT NULL, chain_name TEXT NOT NULL, - chain_type TEXT NOT NULL CHECK (chain_type IN ('evm')), + chain_type TEXT NOT NULL CHECK (chain_type IN ('evm', 'xrpl', 'icon', 'soroban')), status TEXT NOT NULL CHECK (status IN ('Pending','Success','Failed','Timeout')), sender TEXT, gas_used DECIMAL NULL, diff --git a/relayer/store/filesystem.go b/relayer/store/filesystem.go index 18211d7..e2633bd 100644 --- a/relayer/store/filesystem.go +++ b/relayer/store/filesystem.go @@ -13,6 +13,7 @@ import ( "github.com/bandprotocol/falcon/relayer/wallet" "github.com/bandprotocol/falcon/relayer/wallet/evm" "github.com/bandprotocol/falcon/relayer/wallet/icon" + "github.com/bandprotocol/falcon/relayer/wallet/soroban" "github.com/bandprotocol/falcon/relayer/wallet/xrpl" ) @@ -113,6 +114,8 @@ func (fs *FileSystem) NewWallet(chainType chainstypes.ChainType, chainName, pass return xrpl.NewWallet(passphrase, fs.HomePath, chainName) case chainstypes.ChainTypeIcon: return icon.NewWallet(passphrase, fs.HomePath, chainName) + case chainstypes.ChainTypeSoroban: + return soroban.NewWallet(passphrase, fs.HomePath, chainName) default: return nil, fmt.Errorf("unsupported chain type: %s", chainType) } diff --git a/relayer/wallet/soroban/remote_signer.go b/relayer/wallet/soroban/remote_signer.go new file mode 100644 index 0000000..5aaa856 --- /dev/null +++ b/relayer/wallet/soroban/remote_signer.go @@ -0,0 +1,56 @@ +package soroban + +import ( + "encoding/json" + + fkmsv1 "github.com/bandprotocol/falcon/proto/fkms/v1" + "github.com/bandprotocol/falcon/relayer/wallet" +) + +var _ wallet.Signer = (*RemoteSigner)(nil) + +// RemoteSigner is signer that uses KMS service to sign Soroban data. +type RemoteSigner struct { + wallet.BaseRemoteSigner +} + +// NewRemoteSigner creates a new RemoteSigner instance. +func NewRemoteSigner(name, address, url string, key string) (wallet.Signer, error) { + base, err := wallet.NewBaseRemoteSigner(name, address, url, key) + if err != nil { + return nil, err + } + + return &RemoteSigner{BaseRemoteSigner: *base}, nil +} + +// Sign requests the remote KMS to sign the data and returns the tx blob. +func (r *RemoteSigner) Sign(payload []byte, tssPayload wallet.TssPayload) ([]byte, error) { + var signerPayload SignerPayload + if err := json.Unmarshal(payload, &signerPayload); err != nil { + return nil, err + } + res, err := r.FkmsClient.SignSoroban( + r.ContextWithKey(), + &fkmsv1.SignSorobanRequest{ + SignerPayload: &fkmsv1.SorobanSignerPayload{ + SourceAccount: signerPayload.SourceAccount, + ContractAddress: signerPayload.ContractAddress, + Fee: signerPayload.Fee, + Sequence: signerPayload.Sequence, + NetworkPassphrase: signerPayload.NetworkPassphrase, + RpcUrls: signerPayload.RpcUrls, + }, + Tss: &fkmsv1.Tss{ + Message: tssPayload.TssMessage, + RandomAddr: tssPayload.RandomAddr, + SignatureS: tssPayload.Signature, + }, + }, + ) + if err != nil { + return nil, err + } + + return []byte(res.TxBlob), nil +} diff --git a/relayer/wallet/soroban/types.go b/relayer/wallet/soroban/types.go new file mode 100644 index 0000000..603c5c7 --- /dev/null +++ b/relayer/wallet/soroban/types.go @@ -0,0 +1,28 @@ +package soroban + +type SignerPayload struct { + SourceAccount string + ContractAddress string + Fee string + Sequence int64 + NetworkPassphrase string + RpcUrls []string +} + +func NewSignerPayload( + sourceAccount string, + contractAddress string, + fee string, + sequence int64, + networkPassphrase string, + rpcUrls []string, +) SignerPayload { + return SignerPayload{ + SourceAccount: sourceAccount, + ContractAddress: contractAddress, + Fee: fee, + Sequence: sequence, + NetworkPassphrase: networkPassphrase, + RpcUrls: rpcUrls, + } +} diff --git a/relayer/wallet/soroban/wallet.go b/relayer/wallet/soroban/wallet.go new file mode 100644 index 0000000..008788f --- /dev/null +++ b/relayer/wallet/soroban/wallet.go @@ -0,0 +1,8 @@ +package soroban + +import "github.com/bandprotocol/falcon/relayer/wallet" + +// NewWallet creates a new wallet for the given Soroban chain. +func NewWallet(passphrase, homePath, chainName string) (*wallet.BaseWallet, error) { + return wallet.NewBaseWallet(passphrase, homePath, chainName, wallet.NewRemoteOnlyAdapter(NewRemoteSigner)) +} diff --git a/scripts/mockgen.sh b/scripts/mockgen.sh index c82fb42..d0aa7dc 100755 --- a/scripts/mockgen.sh +++ b/scripts/mockgen.sh @@ -10,3 +10,4 @@ $mockgen_cmd -source=relayer/wallet/wallet.go -package mocks -destination intern $mockgen_cmd -source=relayer/store/store.go -package mocks -destination internal/relayertest/mocks/store.go $mockgen_cmd -source=proto/fkms/v1/signer_grpc.pb.go -package mocks -destination internal/relayertest/mocks/signer_grpc.go $mockgen_cmd -source=relayer/chains/xrpl/client.go -mock_names Client=MockXRPLClient -package mocks -destination internal/relayertest/mocks/chain_xrpl_client.go +$mockgen_cmd -source=relayer/chains/soroban/client.go -mock_names Client=MockSorobanClient -package mocks -destination internal/relayertest/mocks/chain_soroban_client.go