forked from cerc-io/laconicd
		
	Setup and integrate GQL server (#12)
Reviewed-on: deep-stack/laconic2d#12 Co-authored-by: Prathamesh Musale <prathamesh.musale0@gmail.com> Co-committed-by: Prathamesh Musale <prathamesh.musale0@gmail.com>
This commit is contained in:
		
							parent
							
								
									0af44b5f17
								
							
						
					
					
						commit
						fa5885b349
					
				@ -1,12 +1,14 @@
 | 
			
		||||
package cmd
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"io"
 | 
			
		||||
 | 
			
		||||
	dbm "github.com/cosmos/cosmos-db"
 | 
			
		||||
	"github.com/spf13/cobra"
 | 
			
		||||
	"github.com/spf13/viper"
 | 
			
		||||
	"golang.org/x/sync/errgroup"
 | 
			
		||||
 | 
			
		||||
	"cosmossdk.io/log"
 | 
			
		||||
	confixcmd "cosmossdk.io/tools/confix/cmd"
 | 
			
		||||
@ -26,6 +28,7 @@ import (
 | 
			
		||||
	genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
 | 
			
		||||
 | 
			
		||||
	"git.vdb.to/cerc-io/laconic2d/app"
 | 
			
		||||
	"git.vdb.to/cerc-io/laconic2d/gql"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func initRootCmd(rootCmd *cobra.Command, txConfig client.TxConfig, basicManager module.BasicManager) {
 | 
			
		||||
@ -40,7 +43,20 @@ func initRootCmd(rootCmd *cobra.Command, txConfig client.TxConfig, basicManager
 | 
			
		||||
		snapshot.Cmd(newApp),
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	server.AddCommands(rootCmd, app.DefaultNodeHome, newApp, appExport, func(startCmd *cobra.Command) {})
 | 
			
		||||
	server.AddCommands(rootCmd, app.DefaultNodeHome, newApp, appExport, func(startCmd *cobra.Command) {
 | 
			
		||||
		// Override start command to run the GQL server
 | 
			
		||||
		newStartCmd := server.StartCmdWithOptions(newApp, app.DefaultNodeHome, server.StartCmdOptions{
 | 
			
		||||
			PostSetup: func(svrCtx *server.Context, clientCtx client.Context, ctx context.Context, g *errgroup.Group) error {
 | 
			
		||||
				g.Go(func() error {
 | 
			
		||||
					return gql.Server(ctx, clientCtx, svrCtx.Logger.With("module", "gql-server"))
 | 
			
		||||
				})
 | 
			
		||||
 | 
			
		||||
				return nil
 | 
			
		||||
			},
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		startCmd.RunE = newStartCmd.RunE
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	// add keybase, auxiliary RPC, query, genesis, and tx child commands
 | 
			
		||||
	rootCmd.AddCommand(
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,7 @@ import (
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/x/auth/types"
 | 
			
		||||
 | 
			
		||||
	"git.vdb.to/cerc-io/laconic2d/app"
 | 
			
		||||
	"git.vdb.to/cerc-io/laconic2d/gql"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const EnvPrefix = "LACONIC"
 | 
			
		||||
@ -106,7 +107,7 @@ func NewRootCmd() *cobra.Command {
 | 
			
		||||
			// overwrite the block timeout
 | 
			
		||||
			cmtCfg := cmtcfg.DefaultConfig()
 | 
			
		||||
			cmtCfg.Consensus.TimeoutCommit = 3 * time.Second
 | 
			
		||||
			cmtCfg.LogLevel = "*:error,p2p:info,state:info,auction:info,bond:info,registry:info" // better default logging
 | 
			
		||||
			cmtCfg.LogLevel = "*:error,p2p:info,state:info,auction:info,bond:info,registry:info,gql-server:info" // better default logging
 | 
			
		||||
 | 
			
		||||
			return server.InterceptConfigsPreRunHandler(cmd, serverconfig.DefaultConfigTemplate, srvCfg, cmtCfg)
 | 
			
		||||
		},
 | 
			
		||||
@ -118,6 +119,9 @@ func NewRootCmd() *cobra.Command {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add flags for GQL server.
 | 
			
		||||
	rootCmd = gql.AddGQLFlags(rootCmd)
 | 
			
		||||
 | 
			
		||||
	return rootCmd
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										22
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								go.mod
									
									
									
									
									
								
							@ -23,6 +23,7 @@ require (
 | 
			
		||||
	cosmossdk.io/math v1.2.0
 | 
			
		||||
	cosmossdk.io/store v1.0.2
 | 
			
		||||
	cosmossdk.io/tools/confix v0.1.0
 | 
			
		||||
	github.com/99designs/gqlgen v0.17.22
 | 
			
		||||
	github.com/cometbft/cometbft v0.38.2
 | 
			
		||||
	github.com/cosmos/cosmos-db v1.0.0
 | 
			
		||||
	github.com/cosmos/cosmos-proto v1.0.0-beta.3
 | 
			
		||||
@ -31,14 +32,18 @@ require (
 | 
			
		||||
	github.com/cosmos/gogoproto v1.4.11
 | 
			
		||||
	github.com/deckarep/golang-set v1.8.0
 | 
			
		||||
	github.com/gibson042/canonicaljson-go v1.0.3
 | 
			
		||||
	github.com/go-chi/chi/v5 v5.0.8
 | 
			
		||||
	github.com/golang/protobuf v1.5.3
 | 
			
		||||
	github.com/grpc-ecosystem/grpc-gateway v1.16.0
 | 
			
		||||
	github.com/ipfs/go-cid v0.4.1
 | 
			
		||||
	github.com/ipld/go-ipld-prime v0.21.0
 | 
			
		||||
	github.com/rs/cors v1.8.3
 | 
			
		||||
	github.com/spf13/cobra v1.8.0
 | 
			
		||||
	github.com/spf13/viper v1.17.0
 | 
			
		||||
	github.com/stretchr/testify v1.8.4
 | 
			
		||||
	golang.org/x/exp v0.0.0-20231006140011-7918f672742d
 | 
			
		||||
	github.com/vektah/gqlparser/v2 v2.5.11
 | 
			
		||||
	golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
 | 
			
		||||
	golang.org/x/sync v0.6.0
 | 
			
		||||
	google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f
 | 
			
		||||
	google.golang.org/grpc v1.60.1
 | 
			
		||||
	google.golang.org/protobuf v1.32.0
 | 
			
		||||
@ -52,8 +57,11 @@ require (
 | 
			
		||||
	github.com/99designs/keyring v1.2.1 // indirect
 | 
			
		||||
	github.com/DataDog/datadog-go v3.2.0+incompatible // indirect
 | 
			
		||||
	github.com/DataDog/zstd v1.5.5 // indirect
 | 
			
		||||
	github.com/Microsoft/go-winio v0.6.1 // indirect
 | 
			
		||||
	github.com/agnivade/levenshtein v1.1.1 // indirect
 | 
			
		||||
	github.com/beorn7/perks v1.0.1 // indirect
 | 
			
		||||
	github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect
 | 
			
		||||
	github.com/bits-and-blooms/bitset v1.10.0 // indirect
 | 
			
		||||
	github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
 | 
			
		||||
	github.com/cenkalti/backoff/v4 v4.1.3 // indirect
 | 
			
		||||
	github.com/cespare/xxhash v1.1.0 // indirect
 | 
			
		||||
@ -94,7 +102,7 @@ require (
 | 
			
		||||
	github.com/gogo/protobuf v1.3.2 // indirect
 | 
			
		||||
	github.com/golang/glog v1.2.0 // indirect
 | 
			
		||||
	github.com/golang/mock v1.6.0 // indirect
 | 
			
		||||
	github.com/golang/snappy v0.0.4 // indirect
 | 
			
		||||
	github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
 | 
			
		||||
	github.com/google/btree v1.1.2 // indirect
 | 
			
		||||
	github.com/google/go-cmp v0.6.0 // indirect
 | 
			
		||||
	github.com/google/orderedcode v0.0.1 // indirect
 | 
			
		||||
@ -151,7 +159,6 @@ require (
 | 
			
		||||
	github.com/prometheus/procfs v0.12.0 // indirect
 | 
			
		||||
	github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
 | 
			
		||||
	github.com/rogpeppe/go-internal v1.11.0 // indirect
 | 
			
		||||
	github.com/rs/cors v1.8.3 // indirect
 | 
			
		||||
	github.com/rs/zerolog v1.31.0 // indirect
 | 
			
		||||
	github.com/sagikazarmark/locafero v0.3.0 // indirect
 | 
			
		||||
	github.com/sagikazarmark/slog-shim v0.1.0 // indirect
 | 
			
		||||
@ -169,11 +176,10 @@ require (
 | 
			
		||||
	github.com/zondax/ledger-go v0.14.3 // indirect
 | 
			
		||||
	go.etcd.io/bbolt v1.3.8 // indirect
 | 
			
		||||
	go.uber.org/multierr v1.10.0 // indirect
 | 
			
		||||
	golang.org/x/crypto v0.16.0 // indirect
 | 
			
		||||
	golang.org/x/net v0.19.0 // indirect
 | 
			
		||||
	golang.org/x/sync v0.4.0 // indirect
 | 
			
		||||
	golang.org/x/sys v0.15.0 // indirect
 | 
			
		||||
	golang.org/x/term v0.15.0 // indirect
 | 
			
		||||
	golang.org/x/crypto v0.18.0 // indirect
 | 
			
		||||
	golang.org/x/net v0.20.0 // indirect
 | 
			
		||||
	golang.org/x/sys v0.16.0 // indirect
 | 
			
		||||
	golang.org/x/term v0.16.0 // indirect
 | 
			
		||||
	golang.org/x/text v0.14.0 // indirect
 | 
			
		||||
	google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3 // indirect
 | 
			
		||||
	google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 // indirect
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										85
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										85
									
								
								go.sum
									
									
									
									
									
								
							@ -62,19 +62,22 @@ filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek=
 | 
			
		||||
filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
 | 
			
		||||
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs=
 | 
			
		||||
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4=
 | 
			
		||||
github.com/99designs/gqlgen v0.17.22 h1:TOcrF8t0T3I0za9JD3CB6ehq7dDEMjR9Onikf8Lc/04=
 | 
			
		||||
github.com/99designs/gqlgen v0.17.22/go.mod h1:BMhYIhe4bp7OlCo5I2PnowSK/Wimpv/YlxfNkqZGwLo=
 | 
			
		||||
github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo87o=
 | 
			
		||||
github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA=
 | 
			
		||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
 | 
			
		||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
 | 
			
		||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 | 
			
		||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
 | 
			
		||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 | 
			
		||||
github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4=
 | 
			
		||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
 | 
			
		||||
github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ=
 | 
			
		||||
github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
 | 
			
		||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
 | 
			
		||||
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
 | 
			
		||||
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
 | 
			
		||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
 | 
			
		||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
 | 
			
		||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
 | 
			
		||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
 | 
			
		||||
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
 | 
			
		||||
@ -86,14 +89,21 @@ github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/
 | 
			
		||||
github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I=
 | 
			
		||||
github.com/adlio/schema v1.3.3/go.mod h1:1EsRssiv9/Ce2CMzq5DoL7RiMshhuigQxrR4DMV9fHg=
 | 
			
		||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
 | 
			
		||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
 | 
			
		||||
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
 | 
			
		||||
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
 | 
			
		||||
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/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
 | 
			
		||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
 | 
			
		||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
 | 
			
		||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
 | 
			
		||||
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
 | 
			
		||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
 | 
			
		||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
 | 
			
		||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
 | 
			
		||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
 | 
			
		||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
 | 
			
		||||
@ -110,8 +120,8 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
 | 
			
		||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
 | 
			
		||||
github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s=
 | 
			
		||||
github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
 | 
			
		||||
github.com/bits-and-blooms/bitset v1.8.0 h1:FD+XqgOZDUxxZ8hzoBFuV9+cGWY9CslN6d5MS5JVb4c=
 | 
			
		||||
github.com/bits-and-blooms/bitset v1.8.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
 | 
			
		||||
github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88=
 | 
			
		||||
github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
 | 
			
		||||
github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U=
 | 
			
		||||
github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
 | 
			
		||||
github.com/btcsuite/btcd/btcutil v1.1.3 h1:xfbtw8lwpp0G6NwSHb+UE67ryTFHJAiNuipusjXSohQ=
 | 
			
		||||
@ -200,6 +210,7 @@ github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5n
 | 
			
		||||
github.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8=
 | 
			
		||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
 | 
			
		||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
 | 
			
		||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
 | 
			
		||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
 | 
			
		||||
github.com/creachadair/atomicfile v0.3.1 h1:yQORkHjSYySh/tv5th1dkKcn02NEW5JleB84sjt+W4Q=
 | 
			
		||||
github.com/creachadair/atomicfile v0.3.1/go.mod h1:mwfrkRxFKwpNAflYZzytbSwxvbK6fdGRRlp0KEQc0qU=
 | 
			
		||||
@ -230,6 +241,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
 | 
			
		||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
 | 
			
		||||
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y=
 | 
			
		||||
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
 | 
			
		||||
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=
 | 
			
		||||
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
 | 
			
		||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
 | 
			
		||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
 | 
			
		||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
 | 
			
		||||
@ -281,6 +294,8 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
 | 
			
		||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
 | 
			
		||||
github.com/gin-gonic/gin v1.7.0 h1:jGB9xAJQ12AIGNB4HguylppmDK1Am9ppF7XnGXXJuoU=
 | 
			
		||||
github.com/gin-gonic/gin v1.7.0/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
 | 
			
		||||
github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0=
 | 
			
		||||
github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
 | 
			
		||||
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-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
 | 
			
		||||
@ -368,8 +383,9 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg
 | 
			
		||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 | 
			
		||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 | 
			
		||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 | 
			
		||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
 | 
			
		||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 | 
			
		||||
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk=
 | 
			
		||||
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 | 
			
		||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 | 
			
		||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 | 
			
		||||
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
 | 
			
		||||
@ -462,6 +478,7 @@ github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09
 | 
			
		||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
 | 
			
		||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 | 
			
		||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 | 
			
		||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
 | 
			
		||||
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
 | 
			
		||||
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
 | 
			
		||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
 | 
			
		||||
@ -514,6 +531,7 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7
 | 
			
		||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 | 
			
		||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
 | 
			
		||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
 | 
			
		||||
github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM=
 | 
			
		||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
 | 
			
		||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
 | 
			
		||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 | 
			
		||||
@ -548,12 +566,14 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b
 | 
			
		||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
 | 
			
		||||
github.com/linxGnu/grocksdb v1.8.6 h1:O7I6SIGPrypf3f/gmrrLUBQDKfO8uOoYdWf4gLS06tc=
 | 
			
		||||
github.com/linxGnu/grocksdb v1.8.6/go.mod h1:xZCIb5Muw+nhbDK4Y5UJuOrin5MceOuiXkVUR7vp4WY=
 | 
			
		||||
github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc=
 | 
			
		||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
 | 
			
		||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 | 
			
		||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
 | 
			
		||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
 | 
			
		||||
github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA=
 | 
			
		||||
github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
 | 
			
		||||
github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk=
 | 
			
		||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
 | 
			
		||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
 | 
			
		||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
 | 
			
		||||
@ -749,6 +769,9 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0
 | 
			
		||||
github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0=
 | 
			
		||||
github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM=
 | 
			
		||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
 | 
			
		||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
 | 
			
		||||
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
 | 
			
		||||
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
 | 
			
		||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 | 
			
		||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 | 
			
		||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 | 
			
		||||
@ -825,15 +848,22 @@ github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95
 | 
			
		||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
 | 
			
		||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 | 
			
		||||
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 | 
			
		||||
github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY=
 | 
			
		||||
github.com/vektah/gqlparser/v2 v2.5.1/go.mod h1:mPgqFBu/woKTVYWyNk8cO3kh4S/f4aRFZrvOnp3hmCs=
 | 
			
		||||
github.com/vektah/gqlparser/v2 v2.5.11 h1:JJxLtXIoN7+3x6MBdtIP59TP1RANnY7pXOaDnADQSf8=
 | 
			
		||||
github.com/vektah/gqlparser/v2 v2.5.11/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc=
 | 
			
		||||
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ=
 | 
			
		||||
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
 | 
			
		||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 | 
			
		||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
 | 
			
		||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
 | 
			
		||||
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=
 | 
			
		||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 | 
			
		||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 | 
			
		||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 | 
			
		||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 | 
			
		||||
github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U=
 | 
			
		||||
github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=
 | 
			
		||||
github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw=
 | 
			
		||||
@ -876,9 +906,10 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
 | 
			
		||||
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.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 | 
			
		||||
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
 | 
			
		||||
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
 | 
			
		||||
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
 | 
			
		||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
 | 
			
		||||
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=
 | 
			
		||||
@ -890,8 +921,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
 | 
			
		||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
 | 
			
		||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
 | 
			
		||||
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
 | 
			
		||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
 | 
			
		||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
 | 
			
		||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
 | 
			
		||||
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
 | 
			
		||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 | 
			
		||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 | 
			
		||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 | 
			
		||||
@ -916,8 +947,10 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 | 
			
		||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 | 
			
		||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 | 
			
		||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 | 
			
		||||
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
 | 
			
		||||
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
 | 
			
		||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
 | 
			
		||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 | 
			
		||||
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
 | 
			
		||||
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
 | 
			
		||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
			
		||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
			
		||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
			
		||||
@ -962,10 +995,12 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v
 | 
			
		||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 | 
			
		||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 | 
			
		||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 | 
			
		||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 | 
			
		||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 | 
			
		||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 | 
			
		||||
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
 | 
			
		||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
 | 
			
		||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 | 
			
		||||
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
 | 
			
		||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
 | 
			
		||||
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=
 | 
			
		||||
@ -986,8 +1021,9 @@ 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-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
 | 
			
		||||
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
 | 
			
		||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
 | 
			
		||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 | 
			
		||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
			
		||||
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=
 | 
			
		||||
@ -1053,21 +1089,24 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
 | 
			
		||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
 | 
			
		||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 | 
			
		||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
 | 
			
		||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 | 
			
		||||
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.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
 | 
			
		||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
 | 
			
		||||
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
 | 
			
		||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
 | 
			
		||||
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=
 | 
			
		||||
@ -1077,6 +1116,7 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 | 
			
		||||
golang.org/x/text v0.3.5/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.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
 | 
			
		||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
 | 
			
		||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 | 
			
		||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
			
		||||
@ -1141,8 +1181,10 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
 | 
			
		||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 | 
			
		||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 | 
			
		||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 | 
			
		||||
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
 | 
			
		||||
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
 | 
			
		||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
 | 
			
		||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 | 
			
		||||
golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8=
 | 
			
		||||
golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
			
		||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
			
		||||
@ -1264,6 +1306,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
 | 
			
		||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 | 
			
		||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 | 
			
		||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 | 
			
		||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 | 
			
		||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 | 
			
		||||
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
 | 
			
		||||
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										353
									
								
								gql/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										353
									
								
								gql/README.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,353 @@
 | 
			
		||||
# cerc-io laconic gql
 | 
			
		||||
 | 
			
		||||
> Browser : http://localhost:9473 for gql
 | 
			
		||||
 | 
			
		||||
## Start server
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
laconic2d start --gql-playground --gql-server
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Basic node status:
 | 
			
		||||
 | 
			
		||||
```graphql
 | 
			
		||||
{
 | 
			
		||||
  getStatus {
 | 
			
		||||
    version
 | 
			
		||||
    node {
 | 
			
		||||
      id
 | 
			
		||||
      network
 | 
			
		||||
      moniker
 | 
			
		||||
    }
 | 
			
		||||
    sync {
 | 
			
		||||
      latest_block_height
 | 
			
		||||
      catching_up
 | 
			
		||||
    }
 | 
			
		||||
    num_peers
 | 
			
		||||
    peers {
 | 
			
		||||
      is_outbound
 | 
			
		||||
      remote_ip
 | 
			
		||||
    }
 | 
			
		||||
    disk_usage
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Full node status:
 | 
			
		||||
 | 
			
		||||
```graphql
 | 
			
		||||
{
 | 
			
		||||
  getStatus {
 | 
			
		||||
    version
 | 
			
		||||
    node {
 | 
			
		||||
      id
 | 
			
		||||
      network
 | 
			
		||||
      moniker
 | 
			
		||||
    }
 | 
			
		||||
    sync {
 | 
			
		||||
      latest_block_hash
 | 
			
		||||
      latest_block_time
 | 
			
		||||
      latest_block_height
 | 
			
		||||
      catching_up
 | 
			
		||||
    }
 | 
			
		||||
    validator {
 | 
			
		||||
      address
 | 
			
		||||
      voting_power
 | 
			
		||||
      proposer_priority
 | 
			
		||||
    }
 | 
			
		||||
    validators {
 | 
			
		||||
      address
 | 
			
		||||
      voting_power
 | 
			
		||||
      proposer_priority
 | 
			
		||||
    }
 | 
			
		||||
    num_peers
 | 
			
		||||
    peers {
 | 
			
		||||
      node {
 | 
			
		||||
        id
 | 
			
		||||
        network
 | 
			
		||||
        moniker
 | 
			
		||||
      }
 | 
			
		||||
      is_outbound
 | 
			
		||||
      remote_ip
 | 
			
		||||
    }
 | 
			
		||||
    disk_usage
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Get records by IDs.
 | 
			
		||||
 | 
			
		||||
```graphql
 | 
			
		||||
{
 | 
			
		||||
  getRecordsByIds(ids: ["bafyreigswvbm4dbpnbwkyegrcxd6kynqe4bivflo6esedgxnuofpzonwdy"]) {
 | 
			
		||||
    id
 | 
			
		||||
    names
 | 
			
		||||
    bondId
 | 
			
		||||
    createTime
 | 
			
		||||
    expiryTime
 | 
			
		||||
    owners
 | 
			
		||||
    attributes {
 | 
			
		||||
      key
 | 
			
		||||
      value {
 | 
			
		||||
        string
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Query records.
 | 
			
		||||
 | 
			
		||||
```graphql
 | 
			
		||||
{
 | 
			
		||||
  queryRecords(attributes: [{ key: "type", value: { string: "crn:bot" } }]) {
 | 
			
		||||
    id
 | 
			
		||||
    names
 | 
			
		||||
    bondId
 | 
			
		||||
    createTime
 | 
			
		||||
    expiryTime
 | 
			
		||||
    owners
 | 
			
		||||
    attributes {
 | 
			
		||||
      key
 | 
			
		||||
      value {
 | 
			
		||||
        string
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Get account details:
 | 
			
		||||
 | 
			
		||||
```graphql
 | 
			
		||||
{
 | 
			
		||||
  getAccounts(addresses: ["laconic17t5ywvqxntu0afc96tz0yxcx92ss0e2alhx2c2"]) {
 | 
			
		||||
    address
 | 
			
		||||
    pubKey
 | 
			
		||||
    number
 | 
			
		||||
    sequence
 | 
			
		||||
    balance {
 | 
			
		||||
      type
 | 
			
		||||
      quantity
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Query bonds:
 | 
			
		||||
 | 
			
		||||
```graphql
 | 
			
		||||
{
 | 
			
		||||
  queryBonds(
 | 
			
		||||
    attributes: [
 | 
			
		||||
      {
 | 
			
		||||
        key: "owner"
 | 
			
		||||
        value: { string: "laconic17t5ywvqxntu0afc96tz0yxcx92ss0e2alhx2c2" }
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  ) {
 | 
			
		||||
    id
 | 
			
		||||
    owner
 | 
			
		||||
    balance {
 | 
			
		||||
      type
 | 
			
		||||
      quantity
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Get bonds by IDs.
 | 
			
		||||
 | 
			
		||||
```graphql
 | 
			
		||||
{
 | 
			
		||||
  getBondsByIds(
 | 
			
		||||
    ids: [
 | 
			
		||||
      "1c2b677cb2a27c88cc6bf8acf675c94b69051125b40c4fd073153b10f046dd87"
 | 
			
		||||
      "c3f7a78c5042d2003880962ba31ff3b01fcf5942960e0bc3ca331f816346a440"
 | 
			
		||||
    ]
 | 
			
		||||
  ) {
 | 
			
		||||
    id
 | 
			
		||||
    owner
 | 
			
		||||
    balance {
 | 
			
		||||
      type
 | 
			
		||||
      quantity
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Query Bonds by Owner
 | 
			
		||||
 | 
			
		||||
```graphql
 | 
			
		||||
{
 | 
			
		||||
  queryBondsByOwner(
 | 
			
		||||
    ownerAddresses: ["laconic17t5ywvqxntu0afc96tz0yxcx92ss0e2alhx2c2"]
 | 
			
		||||
  ) {
 | 
			
		||||
    owner
 | 
			
		||||
    bonds {
 | 
			
		||||
      id
 | 
			
		||||
      owner
 | 
			
		||||
      balance {
 | 
			
		||||
        type
 | 
			
		||||
        quantity
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Query auctions by ids
 | 
			
		||||
 | 
			
		||||
```graphql
 | 
			
		||||
{
 | 
			
		||||
  getAuctionsByIds(
 | 
			
		||||
    ids: ["be98f2073c246194276554eefdb4c95b682a35a0f06fbe619a6da57c10c93e90"]
 | 
			
		||||
  ) {
 | 
			
		||||
    id
 | 
			
		||||
    ownerAddress
 | 
			
		||||
    createTime
 | 
			
		||||
    minimumBid {
 | 
			
		||||
      type
 | 
			
		||||
      quantity
 | 
			
		||||
    }
 | 
			
		||||
    commitFee {
 | 
			
		||||
      type
 | 
			
		||||
      quantity
 | 
			
		||||
    }
 | 
			
		||||
    commitsEndTime
 | 
			
		||||
    revealFee {
 | 
			
		||||
      type
 | 
			
		||||
      quantity
 | 
			
		||||
    }
 | 
			
		||||
    revealsEndTime
 | 
			
		||||
    winnerBid {
 | 
			
		||||
      type
 | 
			
		||||
      quantity
 | 
			
		||||
    }
 | 
			
		||||
    winnerPrice {
 | 
			
		||||
      type
 | 
			
		||||
      quantity
 | 
			
		||||
    }
 | 
			
		||||
    winnerAddress
 | 
			
		||||
    bids {
 | 
			
		||||
      bidderAddress
 | 
			
		||||
      commitHash
 | 
			
		||||
      commitTime
 | 
			
		||||
      commitFee {
 | 
			
		||||
        type
 | 
			
		||||
        quantity
 | 
			
		||||
      }
 | 
			
		||||
      revealFee {
 | 
			
		||||
        type
 | 
			
		||||
        quantity
 | 
			
		||||
      }
 | 
			
		||||
      revealTime
 | 
			
		||||
      bidAmount {
 | 
			
		||||
        type
 | 
			
		||||
        quantity
 | 
			
		||||
      }
 | 
			
		||||
      status
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
LookUp Authorities
 | 
			
		||||
 | 
			
		||||
```graphql
 | 
			
		||||
{
 | 
			
		||||
  lookupAuthorities(names: []) {
 | 
			
		||||
    ownerAddress
 | 
			
		||||
    ownerAddress
 | 
			
		||||
    height
 | 
			
		||||
    bondId
 | 
			
		||||
    status
 | 
			
		||||
    expiryTime
 | 
			
		||||
    auction {
 | 
			
		||||
      id
 | 
			
		||||
      ownerAddress
 | 
			
		||||
      createTime
 | 
			
		||||
      minimumBid {
 | 
			
		||||
        type
 | 
			
		||||
        quantity
 | 
			
		||||
      }
 | 
			
		||||
      commitFee {
 | 
			
		||||
        type
 | 
			
		||||
        quantity
 | 
			
		||||
      }
 | 
			
		||||
      commitsEndTime
 | 
			
		||||
      revealFee {
 | 
			
		||||
        type
 | 
			
		||||
        quantity
 | 
			
		||||
      }
 | 
			
		||||
      revealsEndTime
 | 
			
		||||
      winnerBid {
 | 
			
		||||
        type
 | 
			
		||||
        quantity
 | 
			
		||||
      }
 | 
			
		||||
      winnerPrice {
 | 
			
		||||
        type
 | 
			
		||||
        quantity
 | 
			
		||||
      }
 | 
			
		||||
      winnerAddress
 | 
			
		||||
      bids {
 | 
			
		||||
        bidderAddress
 | 
			
		||||
        commitHash
 | 
			
		||||
        commitTime
 | 
			
		||||
        commitFee {
 | 
			
		||||
          type
 | 
			
		||||
          quantity
 | 
			
		||||
        }
 | 
			
		||||
        revealFee {
 | 
			
		||||
          type
 | 
			
		||||
          quantity
 | 
			
		||||
        }
 | 
			
		||||
        revealTime
 | 
			
		||||
        bidAmount {
 | 
			
		||||
          type
 | 
			
		||||
          quantity
 | 
			
		||||
        }
 | 
			
		||||
        status
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
LookUp Names
 | 
			
		||||
 | 
			
		||||
```graphql
 | 
			
		||||
{
 | 
			
		||||
  lookupNames(names: ["crn://hello/test"]) {
 | 
			
		||||
    latest {
 | 
			
		||||
      id
 | 
			
		||||
      height
 | 
			
		||||
    }
 | 
			
		||||
    history {
 | 
			
		||||
      id
 | 
			
		||||
      height
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Resolve Names
 | 
			
		||||
 | 
			
		||||
```graphql
 | 
			
		||||
{
 | 
			
		||||
  resolveNames(names: ["asd"]) {
 | 
			
		||||
    id
 | 
			
		||||
    names
 | 
			
		||||
    bondId
 | 
			
		||||
    createTime
 | 
			
		||||
    expiryTime
 | 
			
		||||
    owners
 | 
			
		||||
    attributes {
 | 
			
		||||
      key
 | 
			
		||||
      value {
 | 
			
		||||
        string
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										258
									
								
								gql/cerc-io/laconic2d/schema.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										258
									
								
								gql/cerc-io/laconic2d/schema.graphql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,258 @@
 | 
			
		||||
# Reference to another record.
 | 
			
		||||
scalar Link
 | 
			
		||||
 | 
			
		||||
# Bonds contain funds that are used to pay rent on record registration and renewal.
 | 
			
		||||
type Bond {
 | 
			
		||||
  id: String! # Primary key, auto-generated by the server.
 | 
			
		||||
  owner: String! # Bond owner cosmos-sdk address.
 | 
			
		||||
  balance: [Coin!] # Current balance for each coin type.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# OwnerBonds contains the bonds related the owner
 | 
			
		||||
type OwnerBonds {
 | 
			
		||||
  owner: String!
 | 
			
		||||
  bonds: [Bond!]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Mutations require payment in coins (e.g. 100wire).
 | 
			
		||||
# Used by the wallet to get the account balance for display and mutations.
 | 
			
		||||
type Coin {
 | 
			
		||||
  type: String! # e.g. 'WIRE'
 | 
			
		||||
  quantity: String! # e.g. 1000000
 | 
			
		||||
}
 | 
			
		||||
# Represents an account on the blockchain.
 | 
			
		||||
# Mutations have to be signed by a particular account.
 | 
			
		||||
type Account {
 | 
			
		||||
  address: String! # Blockchain address.
 | 
			
		||||
  pubKey: String # Public key.
 | 
			
		||||
  number: String! # Account number.
 | 
			
		||||
  sequence: String! # Sequence number used to prevent replays.
 | 
			
		||||
  balance: [Coin!] # Current balance for each coin type.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Value describes a DAG-JSON compatible value.
 | 
			
		||||
union Value =
 | 
			
		||||
   BooleanValue
 | 
			
		||||
 | IntValue
 | 
			
		||||
 | FloatValue
 | 
			
		||||
 | StringValue
 | 
			
		||||
 | BytesValue
 | 
			
		||||
 | LinkValue
 | 
			
		||||
 | ArrayValue
 | 
			
		||||
 | MapValue
 | 
			
		||||
 | 
			
		||||
type BooleanValue {
 | 
			
		||||
  value: Boolean!
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type IntValue {
 | 
			
		||||
  value: Int!
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type FloatValue {
 | 
			
		||||
  value: Float!
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type StringValue {
 | 
			
		||||
  value: String!
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type BytesValue {
 | 
			
		||||
  value: String!
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ArrayValue {
 | 
			
		||||
  value: [Value]!
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type LinkValue {
 | 
			
		||||
  value: Link!
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type MapValue {
 | 
			
		||||
  value: [Attribute!]!
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Key/value pair.
 | 
			
		||||
type Attribute {
 | 
			
		||||
  key: String!
 | 
			
		||||
  value: Value
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Value of a given type used as input to queries.
 | 
			
		||||
# Note: GQL doesn't allow union input types.
 | 
			
		||||
input ValueInput {
 | 
			
		||||
  int: Int
 | 
			
		||||
  float: Float
 | 
			
		||||
  string: String
 | 
			
		||||
  boolean: Boolean
 | 
			
		||||
  link: Link
 | 
			
		||||
  array: [ValueInput]
 | 
			
		||||
  map: [KeyValueInput!]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Key/value pair for inputs.
 | 
			
		||||
input KeyValueInput {
 | 
			
		||||
  key: String!
 | 
			
		||||
  value: ValueInput
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Status information about a node (https://docs.tendermint.com/master/rpc/#/Info/status).
 | 
			
		||||
type NodeInfo {
 | 
			
		||||
  id: String! # Tendermint Node ID.
 | 
			
		||||
  network: String! # Name of the network/blockchain.
 | 
			
		||||
  moniker: String! # Name of the node.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Node sync status.
 | 
			
		||||
type SyncInfo {
 | 
			
		||||
  latest_block_hash: String!
 | 
			
		||||
  latest_block_height: String!
 | 
			
		||||
  latest_block_time: String!
 | 
			
		||||
  catching_up: Boolean!
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Validator set info (https://docs.tendermint.com/master/rpc/#/Info/validators).
 | 
			
		||||
type ValidatorInfo {
 | 
			
		||||
  address: String!
 | 
			
		||||
  voting_power: String!
 | 
			
		||||
  proposer_priority: String
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Network/peer info (https://docs.tendermint.com/master/rpc/#/Info/net_info).
 | 
			
		||||
type PeerInfo {
 | 
			
		||||
  node: NodeInfo!
 | 
			
		||||
  is_outbound: Boolean!
 | 
			
		||||
  remote_ip: String!
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Vulcanize laconic status.
 | 
			
		||||
type Status {
 | 
			
		||||
  version: String!
 | 
			
		||||
  node: NodeInfo!
 | 
			
		||||
  sync: SyncInfo!
 | 
			
		||||
  validator: ValidatorInfo
 | 
			
		||||
  validators: [ValidatorInfo]!
 | 
			
		||||
  num_peers: String!
 | 
			
		||||
  peers: [PeerInfo]
 | 
			
		||||
  disk_usage: String!
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# An auction bid.
 | 
			
		||||
type AuctionBid {
 | 
			
		||||
  bidderAddress: String!
 | 
			
		||||
  status: String!
 | 
			
		||||
  commitHash: String!
 | 
			
		||||
  commitTime: String!
 | 
			
		||||
  commitFee: Coin!
 | 
			
		||||
  revealTime: String!
 | 
			
		||||
  revealFee: Coin!
 | 
			
		||||
  bidAmount: Coin!
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# A sealed-bid, 2nd price auction.
 | 
			
		||||
type Auction {
 | 
			
		||||
  id: String! # Auction ID.
 | 
			
		||||
  status: String! # Auction status (commit, reveal, expired).
 | 
			
		||||
  ownerAddress: String! # Auction owner time.
 | 
			
		||||
  createTime: String! # Create time.
 | 
			
		||||
  commitsEndTime: String! # Commit phase end time.
 | 
			
		||||
  revealsEndTime: String! # Reveal phase end time.
 | 
			
		||||
  commitFee: Coin! # Fee required to bid/participate in the auction.
 | 
			
		||||
  revealFee: Coin! # Reveal fee (paid back to bidders only if they unseal/reveal the bid).
 | 
			
		||||
  minimumBid: Coin! # Minimum bid amount.
 | 
			
		||||
  winnerAddress: String! # Winner address.
 | 
			
		||||
  winnerBid: Coin! # The winning bid amount.
 | 
			
		||||
  winnerPrice: Coin! # The price that the winner actually pays (2nd highest bid).
 | 
			
		||||
  bids: [AuctionBid] # Bids make in the auction.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Record defines the basic properties of an entity in the graph database.
 | 
			
		||||
type Record {
 | 
			
		||||
  id: String! # Computed attribute: Multibase encoded content hash (https://github.com/multiformats/multibase).
 | 
			
		||||
  names: [String!] # Names pointing to this CID (reverse lookup).
 | 
			
		||||
  bondId: String! # Associated bond ID.
 | 
			
		||||
  createTime: String! # Record create time.
 | 
			
		||||
  expiryTime: String! # Record expiry time.
 | 
			
		||||
  owners: [String!] # Addresses of record owners.
 | 
			
		||||
  attributes: [Attribute!] # Record attributes.
 | 
			
		||||
  references: [Record] # Record references.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Name authority record.
 | 
			
		||||
type AuthorityRecord {
 | 
			
		||||
  ownerAddress: String! # Owner address.
 | 
			
		||||
  ownerPublicKey: String! # Owner public key.
 | 
			
		||||
  height: String! # Height at which record was created.
 | 
			
		||||
  status: String! # Status (active, auction, expired).
 | 
			
		||||
  bondId: String! # Associated bond ID.
 | 
			
		||||
  expiryTime: String! # Authority expiry time.
 | 
			
		||||
  auction: Auction # Authority auction.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Name record entry, created at a particular height.
 | 
			
		||||
type NameRecordEntry {
 | 
			
		||||
  id: String! # Target record ID.
 | 
			
		||||
  height: String! # Height at which record was created.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Name record stores the latest and historical name -> record ID mappings.
 | 
			
		||||
type NameRecord {
 | 
			
		||||
  latest: NameRecordEntry! # Latest mame record entry.
 | 
			
		||||
  history: [NameRecordEntry] # Historical name record entries.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Query {
 | 
			
		||||
  #
 | 
			
		||||
  # Status API.
 | 
			
		||||
  #
 | 
			
		||||
  getStatus: Status!
 | 
			
		||||
 | 
			
		||||
  # Get blockchain accounts.
 | 
			
		||||
  getAccounts(addresses: [String!]): [Account]
 | 
			
		||||
 | 
			
		||||
  # Get bonds by IDs.
 | 
			
		||||
  getBondsByIds(ids: [String!]): [Bond]
 | 
			
		||||
 | 
			
		||||
  # Query bonds.
 | 
			
		||||
  queryBonds(attributes: [KeyValueInput!]): [Bond]
 | 
			
		||||
 | 
			
		||||
  # Query bonds by owner.
 | 
			
		||||
  queryBondsByOwner(ownerAddresses: [String!]): [OwnerBonds]
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # GraphDB API.
 | 
			
		||||
  #
 | 
			
		||||
 | 
			
		||||
  # Get records by IDs.
 | 
			
		||||
  getRecordsByIds(ids: [String!]): [Record]
 | 
			
		||||
 | 
			
		||||
  # Query records.
 | 
			
		||||
  queryRecords(
 | 
			
		||||
    # Multiple attribute conditions are in a logical AND.
 | 
			
		||||
    attributes: [KeyValueInput!]
 | 
			
		||||
 | 
			
		||||
    # Whether to query all records, not just named ones (false by default).
 | 
			
		||||
    all: Boolean
 | 
			
		||||
  ): [Record]
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Naming API.
 | 
			
		||||
  #
 | 
			
		||||
 | 
			
		||||
  # Lookup authority information.
 | 
			
		||||
  lookupAuthorities(names: [String!]): [AuthorityRecord]!
 | 
			
		||||
 | 
			
		||||
  # Lookup name to record mapping information.
 | 
			
		||||
  lookupNames(names: [String!]): [NameRecord]!
 | 
			
		||||
 | 
			
		||||
  # Resolve names to records.
 | 
			
		||||
  resolveNames(names: [String!]): [Record]!
 | 
			
		||||
 | 
			
		||||
  #
 | 
			
		||||
  # Auctions API.
 | 
			
		||||
  #
 | 
			
		||||
 | 
			
		||||
  # Get auctions by IDs.
 | 
			
		||||
  getAuctionsByIds(ids: [String!]): [Auction]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								gql/flags.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								gql/flags.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
			
		||||
package gql
 | 
			
		||||
 | 
			
		||||
import "github.com/spf13/cobra"
 | 
			
		||||
 | 
			
		||||
// AddGQLFlags adds gql flags for
 | 
			
		||||
func AddGQLFlags(cmd *cobra.Command) *cobra.Command {
 | 
			
		||||
	// Add flags for GQL server.
 | 
			
		||||
	cmd.PersistentFlags().Bool("gql-server", false, "Start GQL server.")
 | 
			
		||||
	cmd.PersistentFlags().Bool("gql-playground", false, "Enable GQL playground.")
 | 
			
		||||
	cmd.PersistentFlags().String("gql-playground-api-base", "", "GQL API base path to use in GQL playground.")
 | 
			
		||||
	cmd.PersistentFlags().String("gql-port", "9473", "Port to use for the GQL server.")
 | 
			
		||||
	cmd.PersistentFlags().String("log-file", "", "File to tail for GQL 'getLogs' API.")
 | 
			
		||||
 | 
			
		||||
	return cmd
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11067
									
								
								gql/generated.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11067
									
								
								gql/generated.go
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										17
									
								
								gql/gqlgen.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								gql/gqlgen.yml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
# Refer to https://gqlgen.com/config/
 | 
			
		||||
# for detailed .gqlgen.yml documentation.
 | 
			
		||||
 | 
			
		||||
schema:
 | 
			
		||||
  - cerc-io/laconic2d/*.graphql
 | 
			
		||||
exec:
 | 
			
		||||
  filename: generated.go
 | 
			
		||||
model:
 | 
			
		||||
  filename: models_gen.go
 | 
			
		||||
resolver:
 | 
			
		||||
  filename: resolver.go
 | 
			
		||||
  type: Resolver
 | 
			
		||||
 | 
			
		||||
models:
 | 
			
		||||
  Link:
 | 
			
		||||
    model:
 | 
			
		||||
      - git.vdb.to/cerc-io/laconic2d/gql.Link
 | 
			
		||||
							
								
								
									
										165
									
								
								gql/graphiql.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								gql/graphiql.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,165 @@
 | 
			
		||||
package gql
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"html/template"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GraphiQL is an in-browser IDE for exploring GraphiQL APIs.
 | 
			
		||||
// This handler returns GraphiQL when requested.
 | 
			
		||||
//
 | 
			
		||||
// For more information, see https://github.com/graphql/graphiql.
 | 
			
		||||
 | 
			
		||||
func PlaygroundHandler(apiURL string) http.HandlerFunc {
 | 
			
		||||
	return func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		if r.Method != "GET" {
 | 
			
		||||
			http.Error(w, "only GET requests are supported", http.StatusMethodNotAllowed)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		w.Header().Set("Content-Type", "text/html")
 | 
			
		||||
		err := page.Execute(w, map[string]interface{}{
 | 
			
		||||
			"apiURL": apiURL,
 | 
			
		||||
		})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// https://github.com/graphql/graphiql/blob/main/examples/graphiql-cdn/index.html
 | 
			
		||||
var page = template.Must(template.New("graphiql").Parse(`
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
  <head>
 | 
			
		||||
    <title>GraphiQL</title>
 | 
			
		||||
    <style>
 | 
			
		||||
      body {
 | 
			
		||||
        height: 100%;
 | 
			
		||||
        margin: 0;
 | 
			
		||||
        width: 100%;
 | 
			
		||||
        overflow: hidden;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      #graphiql {
 | 
			
		||||
        height: 100vh;
 | 
			
		||||
      }
 | 
			
		||||
    </style>
 | 
			
		||||
 | 
			
		||||
    <!--
 | 
			
		||||
      This GraphiQL example depends on Promise and fetch, which are available in
 | 
			
		||||
      modern browsers, but can be "polyfilled" for older browsers.
 | 
			
		||||
      GraphiQL itself depends on React DOM.
 | 
			
		||||
      If you do not want to rely on a CDN, you can host these files locally or
 | 
			
		||||
      include them directly in your favored resource bundler.
 | 
			
		||||
    -->
 | 
			
		||||
    <script
 | 
			
		||||
      src="https://unpkg.com/react@17/umd/react.development.js"
 | 
			
		||||
      integrity="sha512-Vf2xGDzpqUOEIKO+X2rgTLWPY+65++WPwCHkX2nFMu9IcstumPsf/uKKRd5prX3wOu8Q0GBylRpsDB26R6ExOg=="
 | 
			
		||||
      crossorigin="anonymous"
 | 
			
		||||
    ></script>
 | 
			
		||||
    <script
 | 
			
		||||
      src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
 | 
			
		||||
      integrity="sha512-Wr9OKCTtq1anK0hq5bY3X/AvDI5EflDSAh0mE9gma+4hl+kXdTJPKZ3TwLMBcrgUeoY0s3dq9JjhCQc7vddtFg=="
 | 
			
		||||
      crossorigin="anonymous"
 | 
			
		||||
    ></script>
 | 
			
		||||
 | 
			
		||||
    <!--
 | 
			
		||||
      These two files can be found in the npm module, however you may wish to
 | 
			
		||||
      copy them directly into your environment, or perhaps include them in your
 | 
			
		||||
      favored resource bundler.
 | 
			
		||||
     -->
 | 
			
		||||
    <link rel="stylesheet" href="https://unpkg.com/graphiql/graphiql.min.css" />
 | 
			
		||||
  </head>
 | 
			
		||||
 | 
			
		||||
  <body>
 | 
			
		||||
    <div id="graphiql">Loading...</div>
 | 
			
		||||
    <script
 | 
			
		||||
      src="https://unpkg.com/graphiql/graphiql.min.js"
 | 
			
		||||
      type="application/javascript"
 | 
			
		||||
    ></script>
 | 
			
		||||
    <script>
 | 
			
		||||
      // https://github.com/graphql/graphiql/blob/main/packages/graphiql/resources/renderExample.js
 | 
			
		||||
      
 | 
			
		||||
      // Parse the search string to get url parameters.
 | 
			
		||||
      var search = window.location.search;
 | 
			
		||||
      var parameters = {};
 | 
			
		||||
      search
 | 
			
		||||
        .substr(1)
 | 
			
		||||
        .split('&')
 | 
			
		||||
        .forEach(function (entry) {
 | 
			
		||||
          var eq = entry.indexOf('=');
 | 
			
		||||
          if (eq >= 0) {
 | 
			
		||||
            parameters[decodeURIComponent(entry.slice(0, eq))] = decodeURIComponent(
 | 
			
		||||
              entry.slice(eq + 1),
 | 
			
		||||
            );
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      
 | 
			
		||||
      // When the query and variables string is edited, update the URL bar so
 | 
			
		||||
      // that it can be easily shared.
 | 
			
		||||
      function onEditQuery(newQuery) {
 | 
			
		||||
        parameters.query = newQuery;
 | 
			
		||||
        updateURL();
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      function onEditVariables(newVariables) {
 | 
			
		||||
        parameters.variables = newVariables;
 | 
			
		||||
        updateURL();
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      function onEditHeaders(newHeaders) {
 | 
			
		||||
        parameters.headers = newHeaders;
 | 
			
		||||
        updateURL();
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      function onTabChange(tabsState) {
 | 
			
		||||
        const activeTab = tabsState.tabs[tabsState.activeTabIndex];
 | 
			
		||||
        parameters.query = activeTab.query;
 | 
			
		||||
        parameters.variables = activeTab.variables;
 | 
			
		||||
        parameters.headers = activeTab.headers;
 | 
			
		||||
        updateURL();
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      function updateURL() {
 | 
			
		||||
        var newSearch =
 | 
			
		||||
          '?' +
 | 
			
		||||
          Object.keys(parameters)
 | 
			
		||||
            .filter(function (key) {
 | 
			
		||||
              return Boolean(parameters[key]);
 | 
			
		||||
            })
 | 
			
		||||
            .map(function (key) {
 | 
			
		||||
              return (
 | 
			
		||||
                encodeURIComponent(key) + '=' + encodeURIComponent(parameters[key])
 | 
			
		||||
              );
 | 
			
		||||
            })
 | 
			
		||||
            .join('&');
 | 
			
		||||
        history.replaceState(null, null, newSearch);
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      // Render <GraphiQL /> into the body.
 | 
			
		||||
      // See the README in the top level of this module to learn more about
 | 
			
		||||
      // how you can customize GraphiQL by providing different values or
 | 
			
		||||
      // additional child elements.
 | 
			
		||||
      ReactDOM.render(
 | 
			
		||||
        React.createElement(GraphiQL, {
 | 
			
		||||
          fetcher: GraphiQL.createFetcher({
 | 
			
		||||
            url: {{.apiURL}}
 | 
			
		||||
          }),
 | 
			
		||||
          query: parameters.query,
 | 
			
		||||
          variables: parameters.variables,
 | 
			
		||||
          headers: parameters.headers,
 | 
			
		||||
          defaultHeaders: parameters.defaultHeaders,
 | 
			
		||||
          onEditQuery: onEditQuery,
 | 
			
		||||
          onEditVariables: onEditVariables,
 | 
			
		||||
          onEditHeaders: onEditHeaders,
 | 
			
		||||
          defaultEditorToolsVisibility: true,
 | 
			
		||||
          isHeadersEditorEnabled: true,
 | 
			
		||||
          shouldPersistHeaders: true,
 | 
			
		||||
          onTabChange,
 | 
			
		||||
        }),
 | 
			
		||||
        document.getElementById('graphiql'),
 | 
			
		||||
      );
 | 
			
		||||
    </script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
`))
 | 
			
		||||
							
								
								
									
										193
									
								
								gql/models_gen.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								gql/models_gen.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,193 @@
 | 
			
		||||
// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
package gql
 | 
			
		||||
 | 
			
		||||
type Value interface {
 | 
			
		||||
	IsValue()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Account struct {
 | 
			
		||||
	Address  string  `json:"address"`
 | 
			
		||||
	PubKey   *string `json:"pubKey"`
 | 
			
		||||
	Number   string  `json:"number"`
 | 
			
		||||
	Sequence string  `json:"sequence"`
 | 
			
		||||
	Balance  []*Coin `json:"balance"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ArrayValue struct {
 | 
			
		||||
	Value []Value `json:"value"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ArrayValue) IsValue() {}
 | 
			
		||||
 | 
			
		||||
type Attribute struct {
 | 
			
		||||
	Key   string `json:"key"`
 | 
			
		||||
	Value Value  `json:"value"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Auction struct {
 | 
			
		||||
	ID             string        `json:"id"`
 | 
			
		||||
	Status         string        `json:"status"`
 | 
			
		||||
	OwnerAddress   string        `json:"ownerAddress"`
 | 
			
		||||
	CreateTime     string        `json:"createTime"`
 | 
			
		||||
	CommitsEndTime string        `json:"commitsEndTime"`
 | 
			
		||||
	RevealsEndTime string        `json:"revealsEndTime"`
 | 
			
		||||
	CommitFee      *Coin         `json:"commitFee"`
 | 
			
		||||
	RevealFee      *Coin         `json:"revealFee"`
 | 
			
		||||
	MinimumBid     *Coin         `json:"minimumBid"`
 | 
			
		||||
	WinnerAddress  string        `json:"winnerAddress"`
 | 
			
		||||
	WinnerBid      *Coin         `json:"winnerBid"`
 | 
			
		||||
	WinnerPrice    *Coin         `json:"winnerPrice"`
 | 
			
		||||
	Bids           []*AuctionBid `json:"bids"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type AuctionBid struct {
 | 
			
		||||
	BidderAddress string `json:"bidderAddress"`
 | 
			
		||||
	Status        string `json:"status"`
 | 
			
		||||
	CommitHash    string `json:"commitHash"`
 | 
			
		||||
	CommitTime    string `json:"commitTime"`
 | 
			
		||||
	CommitFee     *Coin  `json:"commitFee"`
 | 
			
		||||
	RevealTime    string `json:"revealTime"`
 | 
			
		||||
	RevealFee     *Coin  `json:"revealFee"`
 | 
			
		||||
	BidAmount     *Coin  `json:"bidAmount"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type AuthorityRecord struct {
 | 
			
		||||
	OwnerAddress   string   `json:"ownerAddress"`
 | 
			
		||||
	OwnerPublicKey string   `json:"ownerPublicKey"`
 | 
			
		||||
	Height         string   `json:"height"`
 | 
			
		||||
	Status         string   `json:"status"`
 | 
			
		||||
	BondID         string   `json:"bondId"`
 | 
			
		||||
	ExpiryTime     string   `json:"expiryTime"`
 | 
			
		||||
	Auction        *Auction `json:"auction"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Bond struct {
 | 
			
		||||
	ID      string  `json:"id"`
 | 
			
		||||
	Owner   string  `json:"owner"`
 | 
			
		||||
	Balance []*Coin `json:"balance"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type BooleanValue struct {
 | 
			
		||||
	Value bool `json:"value"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (BooleanValue) IsValue() {}
 | 
			
		||||
 | 
			
		||||
type BytesValue struct {
 | 
			
		||||
	Value string `json:"value"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (BytesValue) IsValue() {}
 | 
			
		||||
 | 
			
		||||
type Coin struct {
 | 
			
		||||
	Type     string `json:"type"`
 | 
			
		||||
	Quantity string `json:"quantity"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type FloatValue struct {
 | 
			
		||||
	Value float64 `json:"value"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (FloatValue) IsValue() {}
 | 
			
		||||
 | 
			
		||||
type IntValue struct {
 | 
			
		||||
	Value int `json:"value"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (IntValue) IsValue() {}
 | 
			
		||||
 | 
			
		||||
type KeyValueInput struct {
 | 
			
		||||
	Key   string      `json:"key"`
 | 
			
		||||
	Value *ValueInput `json:"value"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type LinkValue struct {
 | 
			
		||||
	Value Link `json:"value"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (LinkValue) IsValue() {}
 | 
			
		||||
 | 
			
		||||
type MapValue struct {
 | 
			
		||||
	Value []*Attribute `json:"value"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (MapValue) IsValue() {}
 | 
			
		||||
 | 
			
		||||
type NameRecord struct {
 | 
			
		||||
	Latest  *NameRecordEntry   `json:"latest"`
 | 
			
		||||
	History []*NameRecordEntry `json:"history"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type NameRecordEntry struct {
 | 
			
		||||
	ID     string `json:"id"`
 | 
			
		||||
	Height string `json:"height"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type NodeInfo struct {
 | 
			
		||||
	ID      string `json:"id"`
 | 
			
		||||
	Network string `json:"network"`
 | 
			
		||||
	Moniker string `json:"moniker"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type OwnerBonds struct {
 | 
			
		||||
	Owner string  `json:"owner"`
 | 
			
		||||
	Bonds []*Bond `json:"bonds"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type PeerInfo struct {
 | 
			
		||||
	Node       *NodeInfo `json:"node"`
 | 
			
		||||
	IsOutbound bool      `json:"is_outbound"`
 | 
			
		||||
	RemoteIP   string    `json:"remote_ip"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Record struct {
 | 
			
		||||
	ID         string       `json:"id"`
 | 
			
		||||
	Names      []string     `json:"names"`
 | 
			
		||||
	BondID     string       `json:"bondId"`
 | 
			
		||||
	CreateTime string       `json:"createTime"`
 | 
			
		||||
	ExpiryTime string       `json:"expiryTime"`
 | 
			
		||||
	Owners     []string     `json:"owners"`
 | 
			
		||||
	Attributes []*Attribute `json:"attributes"`
 | 
			
		||||
	References []*Record    `json:"references"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Status struct {
 | 
			
		||||
	Version    string           `json:"version"`
 | 
			
		||||
	Node       *NodeInfo        `json:"node"`
 | 
			
		||||
	Sync       *SyncInfo        `json:"sync"`
 | 
			
		||||
	Validator  *ValidatorInfo   `json:"validator"`
 | 
			
		||||
	Validators []*ValidatorInfo `json:"validators"`
 | 
			
		||||
	NumPeers   string           `json:"num_peers"`
 | 
			
		||||
	Peers      []*PeerInfo      `json:"peers"`
 | 
			
		||||
	DiskUsage  string           `json:"disk_usage"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type StringValue struct {
 | 
			
		||||
	Value string `json:"value"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (StringValue) IsValue() {}
 | 
			
		||||
 | 
			
		||||
type SyncInfo struct {
 | 
			
		||||
	LatestBlockHash   string `json:"latest_block_hash"`
 | 
			
		||||
	LatestBlockHeight string `json:"latest_block_height"`
 | 
			
		||||
	LatestBlockTime   string `json:"latest_block_time"`
 | 
			
		||||
	CatchingUp        bool   `json:"catching_up"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ValidatorInfo struct {
 | 
			
		||||
	Address          string  `json:"address"`
 | 
			
		||||
	VotingPower      string  `json:"voting_power"`
 | 
			
		||||
	ProposerPriority *string `json:"proposer_priority"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ValueInput struct {
 | 
			
		||||
	Int     *int             `json:"int"`
 | 
			
		||||
	Float   *float64         `json:"float"`
 | 
			
		||||
	String  *string          `json:"string"`
 | 
			
		||||
	Boolean *bool            `json:"boolean"`
 | 
			
		||||
	Link    *Link            `json:"link"`
 | 
			
		||||
	Array   []*ValueInput    `json:"array"`
 | 
			
		||||
	Map     []*KeyValueInput `json:"map"`
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										350
									
								
								gql/resolver.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										350
									
								
								gql/resolver.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,350 @@
 | 
			
		||||
package gql
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"encoding/base64"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/client"
 | 
			
		||||
	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
 | 
			
		||||
	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
 | 
			
		||||
 | 
			
		||||
	auctiontypes "git.vdb.to/cerc-io/laconic2d/x/auction"
 | 
			
		||||
	bondtypes "git.vdb.to/cerc-io/laconic2d/x/bond"
 | 
			
		||||
	registrytypes "git.vdb.to/cerc-io/laconic2d/x/registry"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DefaultLogNumLines is the number of log lines to tail by default.
 | 
			
		||||
const DefaultLogNumLines = 50
 | 
			
		||||
 | 
			
		||||
// MaxLogNumLines is the max number of log lines that can be tailed.
 | 
			
		||||
const MaxLogNumLines = 1000
 | 
			
		||||
 | 
			
		||||
type Resolver struct {
 | 
			
		||||
	ctx     client.Context
 | 
			
		||||
	logFile string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Query is the entry point to query execution.
 | 
			
		||||
func (r *Resolver) Query() QueryResolver {
 | 
			
		||||
	return &queryResolver{r}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type queryResolver struct{ *Resolver }
 | 
			
		||||
 | 
			
		||||
func (q queryResolver) LookupAuthorities(ctx context.Context, names []string) ([]*AuthorityRecord, error) {
 | 
			
		||||
	nsQueryClient := registrytypes.NewQueryClient(q.ctx)
 | 
			
		||||
	auctionQueryClient := auctiontypes.NewQueryClient(q.ctx)
 | 
			
		||||
	gqlResponse := []*AuthorityRecord{}
 | 
			
		||||
 | 
			
		||||
	for _, name := range names {
 | 
			
		||||
		res, err := nsQueryClient.Whois(context.Background(), ®istrytypes.QueryWhoisRequest{Name: name})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		nameAuthority := res.GetNameAuthority()
 | 
			
		||||
		gqlNameAuthorityRecord, err := GetGQLNameAuthorityRecord(&nameAuthority)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if nameAuthority.AuctionId != "" {
 | 
			
		||||
			auctionResp, err := auctionQueryClient.GetAuction(context.Background(), &auctiontypes.QueryAuctionRequest{Id: nameAuthority.GetAuctionId()})
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
			bidsResp, err := auctionQueryClient.GetBids(context.Background(), &auctiontypes.QueryBidsRequest{AuctionId: nameAuthority.GetAuctionId()})
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			gqlAuctionRecord, err := GetGQLAuction(auctionResp.GetAuction(), bidsResp.GetBids())
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			gqlNameAuthorityRecord.Auction = gqlAuctionRecord
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		gqlResponse = append(gqlResponse, gqlNameAuthorityRecord)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return gqlResponse, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (q queryResolver) ResolveNames(ctx context.Context, names []string) ([]*Record, error) {
 | 
			
		||||
	nsQueryClient := registrytypes.NewQueryClient(q.ctx)
 | 
			
		||||
	var gqlResponse []*Record
 | 
			
		||||
	for _, name := range names {
 | 
			
		||||
		res, err := nsQueryClient.ResolveLrn(context.Background(), ®istrytypes.QueryResolveLrnRequest{Lrn: name})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			// Return nil for record not found.
 | 
			
		||||
			gqlResponse = append(gqlResponse, nil)
 | 
			
		||||
		} else {
 | 
			
		||||
			gqlRecord, err := getGQLRecord(context.Background(), q, *res.GetRecord())
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			gqlResponse = append(gqlResponse, gqlRecord)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return gqlResponse, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (q queryResolver) LookupNames(ctx context.Context, names []string) ([]*NameRecord, error) {
 | 
			
		||||
	nsQueryClient := registrytypes.NewQueryClient(q.ctx)
 | 
			
		||||
	var gqlResponse []*NameRecord
 | 
			
		||||
 | 
			
		||||
	for _, name := range names {
 | 
			
		||||
		res, err := nsQueryClient.LookupLrn(context.Background(), ®istrytypes.QueryLookupLrnRequest{Lrn: name})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			// Return nil for name not found.
 | 
			
		||||
			gqlResponse = append(gqlResponse, nil)
 | 
			
		||||
		} else {
 | 
			
		||||
			gqlRecord, err := getGQLNameRecord(res.GetName())
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			gqlResponse = append(gqlResponse, gqlRecord)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return gqlResponse, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (q queryResolver) QueryRecords(ctx context.Context, attributes []*KeyValueInput, all *bool) ([]*Record, error) {
 | 
			
		||||
	nsQueryClient := registrytypes.NewQueryClient(q.ctx)
 | 
			
		||||
 | 
			
		||||
	res, err := nsQueryClient.Records(
 | 
			
		||||
		context.Background(),
 | 
			
		||||
		®istrytypes.QueryRecordsRequest{
 | 
			
		||||
			Attributes: toRPCAttributes(attributes),
 | 
			
		||||
			All:        (all != nil && *all),
 | 
			
		||||
		},
 | 
			
		||||
	)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	records := res.GetRecords()
 | 
			
		||||
	gqlResponse := make([]*Record, len(records))
 | 
			
		||||
 | 
			
		||||
	for i, record := range records {
 | 
			
		||||
		gqlRecord, err := getGQLRecord(context.Background(), q, record)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		gqlResponse[i] = gqlRecord
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return gqlResponse, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (q queryResolver) GetRecordsByIds(ctx context.Context, ids []string) ([]*Record, error) {
 | 
			
		||||
	nsQueryClient := registrytypes.NewQueryClient(q.ctx)
 | 
			
		||||
	gqlResponse := make([]*Record, len(ids))
 | 
			
		||||
 | 
			
		||||
	for i, id := range ids {
 | 
			
		||||
		res, err := nsQueryClient.GetRecord(context.Background(), ®istrytypes.QueryRecordByIdRequest{Id: id})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			// Return nil for record not found.
 | 
			
		||||
			gqlResponse[i] = nil
 | 
			
		||||
		} else {
 | 
			
		||||
			record, err := getGQLRecord(context.Background(), q, res.GetRecord())
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
			gqlResponse[i] = record
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return gqlResponse, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (q queryResolver) GetStatus(ctx context.Context) (*Status, error) {
 | 
			
		||||
	nodeInfo, syncInfo, validatorInfo, err := getStatusInfo(q.ctx)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	numPeers, peers, err := getNetInfo(q.ctx)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	validatorSet, err := getValidatorSet(q.ctx)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	diskUsage, err := GetDiskUsage(NodeDataPath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &Status{
 | 
			
		||||
		Version:    RegistryVersion,
 | 
			
		||||
		Node:       nodeInfo,
 | 
			
		||||
		Sync:       syncInfo,
 | 
			
		||||
		Validator:  validatorInfo,
 | 
			
		||||
		Validators: validatorSet,
 | 
			
		||||
		NumPeers:   numPeers,
 | 
			
		||||
		Peers:      peers,
 | 
			
		||||
		DiskUsage:  diskUsage,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (q queryResolver) GetAccounts(ctx context.Context, addresses []string) ([]*Account, error) {
 | 
			
		||||
	accounts := make([]*Account, len(addresses))
 | 
			
		||||
	for index, address := range addresses {
 | 
			
		||||
		account, err := q.GetAccount(ctx, address)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		accounts[index] = account
 | 
			
		||||
	}
 | 
			
		||||
	return accounts, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (q queryResolver) GetAccount(ctx context.Context, address string) (*Account, error) {
 | 
			
		||||
	authQueryClient := authtypes.NewQueryClient(q.ctx)
 | 
			
		||||
	accountResponse, err := authQueryClient.Account(ctx, &authtypes.QueryAccountRequest{Address: address})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	var account authtypes.AccountI
 | 
			
		||||
	err = q.ctx.Codec.UnpackAny(accountResponse.GetAccount(), &account)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	var pubKey *string
 | 
			
		||||
	if account.GetPubKey() != nil {
 | 
			
		||||
		pubKeyStr := base64.StdEncoding.EncodeToString(account.GetPubKey().Bytes())
 | 
			
		||||
		pubKey = &pubKeyStr
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Get the account balance
 | 
			
		||||
	bankQueryClient := banktypes.NewQueryClient(q.ctx)
 | 
			
		||||
	balance, err := bankQueryClient.AllBalances(ctx, &banktypes.QueryAllBalancesRequest{Address: address})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	accNum := strconv.FormatUint(account.GetAccountNumber(), 10)
 | 
			
		||||
	seq := strconv.FormatUint(account.GetSequence(), 10)
 | 
			
		||||
 | 
			
		||||
	return &Account{
 | 
			
		||||
		Address:  address,
 | 
			
		||||
		Number:   accNum,
 | 
			
		||||
		Sequence: seq,
 | 
			
		||||
		PubKey:   pubKey,
 | 
			
		||||
		Balance:  getGQLCoins(balance.GetBalances()),
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (q queryResolver) GetBondsByIds(ctx context.Context, ids []string) ([]*Bond, error) {
 | 
			
		||||
	bonds := make([]*Bond, len(ids))
 | 
			
		||||
	for index, id := range ids {
 | 
			
		||||
		bondObj, err := q.GetBond(ctx, id)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		bonds[index] = bondObj
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return bonds, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (q *queryResolver) GetBond(ctx context.Context, id string) (*Bond, error) {
 | 
			
		||||
	bondQueryClient := bondtypes.NewQueryClient(q.ctx)
 | 
			
		||||
	bondResp, err := bondQueryClient.GetBondById(context.Background(), &bondtypes.QueryGetBondByIdRequest{Id: id})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bond := bondResp.GetBond()
 | 
			
		||||
	if bond == nil {
 | 
			
		||||
		return nil, nil
 | 
			
		||||
	}
 | 
			
		||||
	return getGQLBond(bondResp.GetBond())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (q queryResolver) QueryBonds(ctx context.Context, attributes []*KeyValueInput) ([]*Bond, error) {
 | 
			
		||||
	bondQueryClient := bondtypes.NewQueryClient(q.ctx)
 | 
			
		||||
	bonds, err := bondQueryClient.Bonds(context.Background(), &bondtypes.QueryGetBondsRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gqlResponse := make([]*Bond, len(bonds.GetBonds()))
 | 
			
		||||
	for i, bondObj := range bonds.GetBonds() {
 | 
			
		||||
		gqlBond, err := getGQLBond(bondObj)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		gqlResponse[i] = gqlBond
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return gqlResponse, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// QueryBondsByOwner will return bonds by owner
 | 
			
		||||
func (q queryResolver) QueryBondsByOwner(ctx context.Context, ownerAddresses []string) ([]*OwnerBonds, error) {
 | 
			
		||||
	ownerBonds := make([]*OwnerBonds, len(ownerAddresses))
 | 
			
		||||
	for index, ownerAddress := range ownerAddresses {
 | 
			
		||||
		bondsObj, err := q.GetBondsByOwner(ctx, ownerAddress)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		ownerBonds[index] = bondsObj
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ownerBonds, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (q queryResolver) GetBondsByOwner(ctx context.Context, address string) (*OwnerBonds, error) {
 | 
			
		||||
	bondQueryClient := bondtypes.NewQueryClient(q.ctx)
 | 
			
		||||
	bondResp, err := bondQueryClient.GetBondsByOwner(context.Background(), &bondtypes.QueryGetBondsByOwnerRequest{Owner: address})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ownerBonds := make([]*Bond, len(bondResp.GetBonds()))
 | 
			
		||||
	for i, bond := range bondResp.GetBonds() {
 | 
			
		||||
		// #nosec G601
 | 
			
		||||
		bondObj, err := getGQLBond(&bond) //nolint: all
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		ownerBonds[i] = bondObj
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &OwnerBonds{Bonds: ownerBonds, Owner: address}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (q queryResolver) GetAuctionsByIds(ctx context.Context, ids []string) ([]*Auction, error) {
 | 
			
		||||
	auctionQueryClient := auctiontypes.NewQueryClient(q.ctx)
 | 
			
		||||
	gqlAuctionResponse := make([]*Auction, len(ids))
 | 
			
		||||
	for i, id := range ids {
 | 
			
		||||
		auctionObj, err := auctionQueryClient.GetAuction(context.Background(), &auctiontypes.QueryAuctionRequest{Id: id})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		bidsObj, err := auctionQueryClient.GetBids(context.Background(), &auctiontypes.QueryBidsRequest{AuctionId: id})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		gqlAuction, err := GetGQLAuction(auctionObj.GetAuction(), bidsObj.GetBids())
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		gqlAuctionResponse[i] = gqlAuction
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return gqlAuctionResponse, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								gql/scalar.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								gql/scalar.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
			
		||||
package gql
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Represents an IPLD link. Links are generally but not necessarily implemented as CIDs
 | 
			
		||||
type Link string
 | 
			
		||||
 | 
			
		||||
func (l Link) String() string {
 | 
			
		||||
	return string(l)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalGQLContext implements the graphql.ContextUnmarshaler interface
 | 
			
		||||
func (l *Link) UnmarshalGQLContext(_ context.Context, v interface{}) error {
 | 
			
		||||
	s, ok := v.(string)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return fmt.Errorf("Link must be a string")
 | 
			
		||||
	}
 | 
			
		||||
	*l = Link(s)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarshalGQLContext implements the graphql.ContextMarshaler interface
 | 
			
		||||
func (l Link) MarshalGQLContext(_ context.Context, w io.Writer) error {
 | 
			
		||||
	encodable := map[string]string{
 | 
			
		||||
		"/": l.String(),
 | 
			
		||||
	}
 | 
			
		||||
	return json.NewEncoder(w).Encode(encodable)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										69
									
								
								gql/server.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								gql/server.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,69 @@
 | 
			
		||||
package gql
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	"cosmossdk.io/log"
 | 
			
		||||
	"github.com/99designs/gqlgen/graphql/handler"
 | 
			
		||||
	"github.com/go-chi/chi/v5"
 | 
			
		||||
	"github.com/rs/cors"
 | 
			
		||||
	"github.com/spf13/viper"
 | 
			
		||||
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/client"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Server configures and starts the GQL server.
 | 
			
		||||
func Server(ctx context.Context, clientCtx client.Context, logger log.Logger) error {
 | 
			
		||||
	if !viper.GetBool("gql-server") {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	router := chi.NewRouter()
 | 
			
		||||
 | 
			
		||||
	// Add CORS middleware around every request
 | 
			
		||||
	// See https://github.com/rs/cors for full option listing
 | 
			
		||||
	router.Use(cors.New(cors.Options{
 | 
			
		||||
		AllowedOrigins: []string{"*"},
 | 
			
		||||
		Debug:          false,
 | 
			
		||||
	}).Handler)
 | 
			
		||||
 | 
			
		||||
	logFile := viper.GetString("log-file")
 | 
			
		||||
 | 
			
		||||
	port := viper.GetString("gql-port")
 | 
			
		||||
 | 
			
		||||
	srv := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: &Resolver{
 | 
			
		||||
		ctx:     clientCtx,
 | 
			
		||||
		logFile: logFile,
 | 
			
		||||
	}}))
 | 
			
		||||
 | 
			
		||||
	router.Handle("/", PlaygroundHandler("/api"))
 | 
			
		||||
 | 
			
		||||
	if viper.GetBool("gql-playground") {
 | 
			
		||||
		apiBase := viper.GetString("gql-playground-api-base")
 | 
			
		||||
 | 
			
		||||
		router.Handle("/webui", PlaygroundHandler(apiBase+"/api"))
 | 
			
		||||
		router.Handle("/console", PlaygroundHandler(apiBase+"/graphql"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	router.Handle("/api", srv)
 | 
			
		||||
	router.Handle("/graphql", srv)
 | 
			
		||||
 | 
			
		||||
	errCh := make(chan error)
 | 
			
		||||
 | 
			
		||||
	go func() {
 | 
			
		||||
		logger.Info(fmt.Sprintf("Connect to GraphQL playground url: http://localhost:%s", port))
 | 
			
		||||
		errCh <- http.ListenAndServe(":"+port, router)
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	select {
 | 
			
		||||
	case <-ctx.Done():
 | 
			
		||||
		// Gracefully stop the GQL server.
 | 
			
		||||
		logger.Info("Stopping GQL server...")
 | 
			
		||||
		return nil
 | 
			
		||||
	case err := <-errCh:
 | 
			
		||||
		logger.Error(fmt.Sprintf("Failed to start GQL server: %s", err))
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										104
									
								
								gql/status.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								gql/status.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,104 @@
 | 
			
		||||
package gql
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/client"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// NodeDataPath is the path to the laconicd data folder.
 | 
			
		||||
var NodeDataPath = os.ExpandEnv("$HOME/.laconicd/data")
 | 
			
		||||
 | 
			
		||||
func getStatusInfo(client client.Context) (*NodeInfo, *SyncInfo, *ValidatorInfo, error) {
 | 
			
		||||
	nodeClient, err := client.GetNode()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
	nodeStatus, err := nodeClient.Status(context.Background())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &NodeInfo{
 | 
			
		||||
			ID:      string(nodeStatus.NodeInfo.ID()),
 | 
			
		||||
			Network: nodeStatus.NodeInfo.Network,
 | 
			
		||||
			Moniker: nodeStatus.NodeInfo.Moniker,
 | 
			
		||||
		}, &SyncInfo{
 | 
			
		||||
			LatestBlockHash:   nodeStatus.SyncInfo.LatestBlockHash.String(),
 | 
			
		||||
			LatestBlockHeight: strconv.FormatInt(nodeStatus.SyncInfo.LatestBlockHeight, 10),
 | 
			
		||||
			LatestBlockTime:   nodeStatus.SyncInfo.LatestBlockTime.String(),
 | 
			
		||||
			CatchingUp:        nodeStatus.SyncInfo.CatchingUp,
 | 
			
		||||
		}, &ValidatorInfo{
 | 
			
		||||
			Address:          nodeStatus.ValidatorInfo.Address.String(),
 | 
			
		||||
			VotingPower:      strconv.FormatInt(nodeStatus.ValidatorInfo.VotingPower, 10),
 | 
			
		||||
			ProposerPriority: nil,
 | 
			
		||||
		}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getNetInfo(client client.Context) (string, []*PeerInfo, error) {
 | 
			
		||||
	// TODO: Implement
 | 
			
		||||
 | 
			
		||||
	// nodeClient, err := client.GetNode()
 | 
			
		||||
	// if err != nil {
 | 
			
		||||
	// 	return "", nil, err
 | 
			
		||||
	// }
 | 
			
		||||
	// netInfo, err := nodeClient.NetInfo(context.Background())
 | 
			
		||||
	// if err != nil {
 | 
			
		||||
	// 	return "", nil, err
 | 
			
		||||
	// }
 | 
			
		||||
 | 
			
		||||
	// peersInfo := make([]*PeerInfo, netInfo.NPeers)
 | 
			
		||||
	// // TODO: find a way to get the peer information from nodeClient
 | 
			
		||||
	// for index, peer := range netInfo.Peers {
 | 
			
		||||
	// 	peersInfo[index] = &PeerInfo{
 | 
			
		||||
	// 		Node: &NodeInfo{
 | 
			
		||||
	// 			ID: string(peer.NodeInfo.ID()),
 | 
			
		||||
	// 			// Moniker: peer.Node.Moniker,
 | 
			
		||||
	// 			// Network: peer.Node.Network,
 | 
			
		||||
	// 		},
 | 
			
		||||
	// 		// IsOutbound: peer.IsOutbound,
 | 
			
		||||
	// 		// RemoteIP:   peer.RemoteIP,
 | 
			
		||||
	// 	}
 | 
			
		||||
	// }
 | 
			
		||||
 | 
			
		||||
	// return strconv.FormatInt(int64(netInfo.NPeers), 10), peersInfo, nil
 | 
			
		||||
 | 
			
		||||
	return strconv.FormatInt(int64(0), 10), []*PeerInfo{}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getValidatorSet(client client.Context) ([]*ValidatorInfo, error) {
 | 
			
		||||
	nodeClient, err := client.GetNode()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	res, err := nodeClient.Validators(context.Background(), nil, nil, nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	validatorSet := make([]*ValidatorInfo, len(res.Validators))
 | 
			
		||||
	for index, validator := range res.Validators {
 | 
			
		||||
		proposerPriority := strconv.FormatInt(validator.ProposerPriority, 10)
 | 
			
		||||
		validatorSet[index] = &ValidatorInfo{
 | 
			
		||||
			Address:          validator.Address.String(),
 | 
			
		||||
			VotingPower:      strconv.FormatInt(validator.VotingPower, 10),
 | 
			
		||||
			ProposerPriority: &proposerPriority,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return validatorSet, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetDiskUsage returns disk usage for the given path.
 | 
			
		||||
func GetDiskUsage(dirPath string) (string, error) {
 | 
			
		||||
	out, err := exec.Command("du", "-sh", dirPath).Output() // #nosec G204
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return strings.Fields(string(out))[0], nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										305
									
								
								gql/util.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										305
									
								
								gql/util.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,305 @@
 | 
			
		||||
package gql
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt" // #nosec G702
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
			
		||||
	"github.com/ipld/go-ipld-prime"
 | 
			
		||||
	"github.com/ipld/go-ipld-prime/codec/dagjson"
 | 
			
		||||
 | 
			
		||||
	auctiontypes "git.vdb.to/cerc-io/laconic2d/x/auction"
 | 
			
		||||
	bondtypes "git.vdb.to/cerc-io/laconic2d/x/bond"
 | 
			
		||||
	registrytypes "git.vdb.to/cerc-io/laconic2d/x/registry"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// OwnerAttributeName denotes the owner attribute name for a bond.
 | 
			
		||||
const OwnerAttributeName = "owner"
 | 
			
		||||
 | 
			
		||||
// BondIDAttributeName denotes the record bond ID.
 | 
			
		||||
const BondIDAttributeName = "bondId"
 | 
			
		||||
 | 
			
		||||
// ExpiryTimeAttributeName denotes the record expiry time.
 | 
			
		||||
const ExpiryTimeAttributeName = "expiryTime"
 | 
			
		||||
 | 
			
		||||
func getGQLCoin(coin sdk.Coin) *Coin {
 | 
			
		||||
	gqlCoin := Coin{
 | 
			
		||||
		Type:     coin.Denom,
 | 
			
		||||
		Quantity: coin.Amount.BigInt().String(),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &gqlCoin
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getGQLCoins(coins sdk.Coins) []*Coin {
 | 
			
		||||
	gqlCoins := make([]*Coin, len(coins))
 | 
			
		||||
	for index, coin := range coins {
 | 
			
		||||
		gqlCoins[index] = getGQLCoin(coin)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return gqlCoins
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetGQLNameAuthorityRecord(record *registrytypes.NameAuthority) (*AuthorityRecord, error) {
 | 
			
		||||
	if record == nil {
 | 
			
		||||
		return nil, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &AuthorityRecord{
 | 
			
		||||
		OwnerAddress:   record.OwnerAddress,
 | 
			
		||||
		OwnerPublicKey: record.OwnerPublicKey,
 | 
			
		||||
		Height:         strconv.FormatUint(record.Height, 10),
 | 
			
		||||
		Status:         record.Status,
 | 
			
		||||
		BondID:         record.GetBondId(),
 | 
			
		||||
		ExpiryTime:     record.GetExpiryTime().String(),
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getGQLRecord(ctx context.Context, resolver QueryResolver, record registrytypes.Record) (*Record, error) {
 | 
			
		||||
	// Nil record.
 | 
			
		||||
	if record.Deleted {
 | 
			
		||||
		return nil, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	node, err := ipld.Decode(record.Attributes, dagjson.Decode)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if node.Kind() != ipld.Kind_Map {
 | 
			
		||||
		return nil, fmt.Errorf("invalid record attributes")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var links []string
 | 
			
		||||
	attributes, err := resolveIPLDNode(node, &links)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	references, err := resolver.GetRecordsByIds(ctx, links)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &Record{
 | 
			
		||||
		ID:         record.Id,
 | 
			
		||||
		BondID:     record.GetBondId(),
 | 
			
		||||
		CreateTime: record.GetCreateTime(),
 | 
			
		||||
		ExpiryTime: record.GetExpiryTime(),
 | 
			
		||||
		Owners:     record.GetOwners(),
 | 
			
		||||
		Names:      record.GetNames(),
 | 
			
		||||
		Attributes: attributes.(MapValue).Value,
 | 
			
		||||
		References: references,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func resolveIPLDNode(node ipld.Node, links *[]string) (Value, error) {
 | 
			
		||||
	switch node.Kind() {
 | 
			
		||||
	case ipld.Kind_Map:
 | 
			
		||||
		var entries []*Attribute
 | 
			
		||||
		for itr := node.MapIterator(); !itr.Done(); {
 | 
			
		||||
			k, v, err := itr.Next()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
			if k.Kind() != ipld.Kind_String {
 | 
			
		||||
				return nil, fmt.Errorf("invalid record attribute key type: %s", k.Kind())
 | 
			
		||||
			}
 | 
			
		||||
			s, err := k.AsString()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
			val, err := resolveIPLDNode(v, links)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
			entries = append(entries, &Attribute{
 | 
			
		||||
				Key:   s,
 | 
			
		||||
				Value: val,
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
		return MapValue{entries}, nil
 | 
			
		||||
	case ipld.Kind_List:
 | 
			
		||||
		var values []Value
 | 
			
		||||
		for itr := node.ListIterator(); !itr.Done(); {
 | 
			
		||||
			_, v, err := itr.Next()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
			val, err := resolveIPLDNode(v, links)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
			values = append(values, val)
 | 
			
		||||
		}
 | 
			
		||||
		return ArrayValue{values}, nil
 | 
			
		||||
	case ipld.Kind_Null:
 | 
			
		||||
		return nil, nil
 | 
			
		||||
	case ipld.Kind_Bool:
 | 
			
		||||
		val, err := node.AsBool()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		return BooleanValue{val}, nil
 | 
			
		||||
	case ipld.Kind_Int:
 | 
			
		||||
		val, err := node.AsInt()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		// TODO: handle bigger ints
 | 
			
		||||
		return IntValue{int(val)}, nil
 | 
			
		||||
	case ipld.Kind_Float:
 | 
			
		||||
		val, err := node.AsFloat()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		return FloatValue{val}, nil
 | 
			
		||||
	case ipld.Kind_String:
 | 
			
		||||
		val, err := node.AsString()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		return StringValue{val}, nil
 | 
			
		||||
	case ipld.Kind_Bytes:
 | 
			
		||||
		val, err := node.AsBytes()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		return BytesValue{string(val)}, nil
 | 
			
		||||
	case ipld.Kind_Link:
 | 
			
		||||
		val, err := node.AsLink()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		*links = append(*links, val.String())
 | 
			
		||||
		return LinkValue{Link(val.String())}, nil
 | 
			
		||||
	default:
 | 
			
		||||
		return nil, fmt.Errorf("invalid node kind")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getGQLNameRecord(record *registrytypes.NameRecord) (*NameRecord, error) {
 | 
			
		||||
	if record == nil {
 | 
			
		||||
		return nil, fmt.Errorf("got nil record")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	records := make([]*NameRecordEntry, len(record.History))
 | 
			
		||||
	for index, entry := range record.History {
 | 
			
		||||
		records[index] = getNameRecordEntry(entry)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &NameRecord{
 | 
			
		||||
		Latest:  getNameRecordEntry(record.Latest),
 | 
			
		||||
		History: records,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getNameRecordEntry(record *registrytypes.NameRecordEntry) *NameRecordEntry {
 | 
			
		||||
	return &NameRecordEntry{
 | 
			
		||||
		ID:     record.Id,
 | 
			
		||||
		Height: strconv.FormatUint(record.Height, 10),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getGQLBond(bondObj *bondtypes.Bond) (*Bond, error) {
 | 
			
		||||
	// Nil record.
 | 
			
		||||
	if bondObj == nil {
 | 
			
		||||
		return nil, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &Bond{
 | 
			
		||||
		ID:      bondObj.Id,
 | 
			
		||||
		Owner:   bondObj.Owner,
 | 
			
		||||
		Balance: getGQLCoins(bondObj.Balance),
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getAuctionBid(bid *auctiontypes.Bid) *AuctionBid {
 | 
			
		||||
	return &AuctionBid{
 | 
			
		||||
		BidderAddress: bid.BidderAddress,
 | 
			
		||||
		Status:        bid.Status,
 | 
			
		||||
		CommitHash:    bid.CommitHash,
 | 
			
		||||
		CommitTime:    bid.GetCommitTime(),
 | 
			
		||||
		RevealTime:    bid.GetRevealTime(),
 | 
			
		||||
		CommitFee:     getGQLCoin(bid.CommitFee),
 | 
			
		||||
		RevealFee:     getGQLCoin(bid.RevealFee),
 | 
			
		||||
		BidAmount:     getGQLCoin(bid.BidAmount),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetGQLAuction(auction *auctiontypes.Auction, bids []*auctiontypes.Bid) (*Auction, error) {
 | 
			
		||||
	if auction == nil {
 | 
			
		||||
		return nil, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gqlAuction := Auction{
 | 
			
		||||
		ID:             auction.Id,
 | 
			
		||||
		Status:         auction.Status,
 | 
			
		||||
		OwnerAddress:   auction.OwnerAddress,
 | 
			
		||||
		CreateTime:     auction.GetCreateTime(),
 | 
			
		||||
		CommitsEndTime: auction.GetCommitsEndTime(),
 | 
			
		||||
		RevealsEndTime: auction.GetRevealsEndTime(),
 | 
			
		||||
		CommitFee:      getGQLCoin(auction.CommitFee),
 | 
			
		||||
		RevealFee:      getGQLCoin(auction.RevealFee),
 | 
			
		||||
		MinimumBid:     getGQLCoin(auction.MinimumBid),
 | 
			
		||||
		WinnerAddress:  auction.WinnerAddress,
 | 
			
		||||
		WinnerBid:      getGQLCoin(auction.WinningBid),
 | 
			
		||||
		WinnerPrice:    getGQLCoin(auction.WinningPrice),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	auctionBids := make([]*AuctionBid, len(bids))
 | 
			
		||||
	for index, entry := range bids {
 | 
			
		||||
		auctionBids[index] = getAuctionBid(entry)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gqlAuction.Bids = auctionBids
 | 
			
		||||
 | 
			
		||||
	return &gqlAuction, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func toRPCValue(value *ValueInput) *registrytypes.QueryRecordsRequest_ValueInput {
 | 
			
		||||
	var rpcval registrytypes.QueryRecordsRequest_ValueInput
 | 
			
		||||
 | 
			
		||||
	switch {
 | 
			
		||||
	case value == nil:
 | 
			
		||||
		return nil
 | 
			
		||||
	case value.Int != nil:
 | 
			
		||||
		rpcval.Value = ®istrytypes.QueryRecordsRequest_ValueInput_Int{Int: int64(*value.Int)}
 | 
			
		||||
	case value.Float != nil:
 | 
			
		||||
		rpcval.Value = ®istrytypes.QueryRecordsRequest_ValueInput_Float{Float: *value.Float}
 | 
			
		||||
	case value.String != nil:
 | 
			
		||||
		rpcval.Value = ®istrytypes.QueryRecordsRequest_ValueInput_String_{String_: *value.String}
 | 
			
		||||
	case value.Boolean != nil:
 | 
			
		||||
		rpcval.Value = ®istrytypes.QueryRecordsRequest_ValueInput_Boolean{Boolean: *value.Boolean}
 | 
			
		||||
	case value.Link != nil:
 | 
			
		||||
		rpcval.Value = ®istrytypes.QueryRecordsRequest_ValueInput_Link{Link: value.Link.String()}
 | 
			
		||||
	case value.Array != nil:
 | 
			
		||||
		var contents registrytypes.QueryRecordsRequest_ArrayInput
 | 
			
		||||
		for _, val := range value.Array {
 | 
			
		||||
			contents.Values = append(contents.Values, toRPCValue(val))
 | 
			
		||||
		}
 | 
			
		||||
		rpcval.Value = ®istrytypes.QueryRecordsRequest_ValueInput_Array{Array: &contents}
 | 
			
		||||
	case value.Map != nil:
 | 
			
		||||
		var contents registrytypes.QueryRecordsRequest_MapInput
 | 
			
		||||
		for _, kv := range value.Map {
 | 
			
		||||
			contents.Values[kv.Key] = toRPCValue(kv.Value)
 | 
			
		||||
		}
 | 
			
		||||
		rpcval.Value = ®istrytypes.QueryRecordsRequest_ValueInput_Map{Map: &contents}
 | 
			
		||||
	}
 | 
			
		||||
	return &rpcval
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func toRPCAttributes(attrs []*KeyValueInput) []*registrytypes.QueryRecordsRequest_KeyValueInput {
 | 
			
		||||
	kvPairs := []*registrytypes.QueryRecordsRequest_KeyValueInput{}
 | 
			
		||||
 | 
			
		||||
	for _, value := range attrs {
 | 
			
		||||
		parsedValue := toRPCValue(value.Value)
 | 
			
		||||
		kvPair := ®istrytypes.QueryRecordsRequest_KeyValueInput{
 | 
			
		||||
			Key:   value.Key,
 | 
			
		||||
			Value: parsedValue,
 | 
			
		||||
		}
 | 
			
		||||
		kvPairs = append(kvPairs, kvPair)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return kvPairs
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								gql/version.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								gql/version.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
package gql
 | 
			
		||||
 | 
			
		||||
// RegistryVersion is the registry API version.
 | 
			
		||||
const RegistryVersion = "0.3.0"
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user