diff --git a/access/grpc/client.go b/access/grpc/client.go index 65de1d1c1..d68858205 100644 --- a/access/grpc/client.go +++ b/access/grpc/client.go @@ -28,6 +28,7 @@ package grpc import ( "context" + cdcjson "github.com/onflow/cadence/encoding/json" "google.golang.org/grpc" "github.com/onflow/cadence" @@ -42,15 +43,55 @@ const CanarynetHost = "access.canary.nodes.onflow.org:9000" const MainnetHost = "access.mainnet.nodes.onflow.org:9000" const PreviewnetHost = "access.previewnet.nodes.onflow.org:9000" +// ClientOption is a configuration option for the client. +type ClientOption interface { + apply(*options) +} + +type options struct { + dialOptions []grpc.DialOption + jsonOptions []cdcjson.Option +} + +type dialOption struct { + opt grpc.DialOption +} + +func (d *dialOption) apply(opts *options) { + opts.dialOptions = append(opts.dialOptions, d.opt) +} + +// WithGRPCDialOption wraps a grpc.DialOption into a ClientOption. +func WithGRPCDialOption(opt grpc.DialOption) ClientOption { + return &dialOption{opt: opt} +} + +type jsonDecoderOption struct { + opt cdcjson.Option +} + +func (j *jsonDecoderOption) apply(opts *options) { + opts.jsonOptions = append(opts.jsonOptions, j.opt) +} + +// WithJSONOption wraps a json.Option into a ClientOption. +func WithJSONOption(opt cdcjson.Option) ClientOption { + return &jsonDecoderOption{opt: opt} +} + // NewClient creates an gRPC client exposing all the common access APIs. // Client will use provided host for connection. -func NewClient(host string, opts ...grpc.DialOption) (*Client, error) { +func NewClient(host string, opts ...ClientOption) (*Client, error) { var client *BaseClient var err error if len(opts) > 0 { client, err = NewBaseClient(host, opts...) } else { - client, err = NewBaseClient(host, grpc.WithTransportCredentials(insecure.NewCredentials())) + client, err = NewBaseClient( + host, + WithGRPCDialOption(grpc.WithTransportCredentials(insecure.NewCredentials())), + WithJSONOption(cdcjson.WithAllowUnstructuredStaticTypes(false)), + ) } if err != nil { return nil, err diff --git a/access/grpc/grpc.go b/access/grpc/grpc.go index cb97ba6c0..84527e25d 100644 --- a/access/grpc/grpc.go +++ b/access/grpc/grpc.go @@ -84,8 +84,13 @@ type BaseClient struct { } // NewBaseClient creates a new gRPC handler for network communication. -func NewBaseClient(url string, opts ...grpc.DialOption) (*BaseClient, error) { - conn, err := grpc.Dial(url, opts...) +func NewBaseClient(url string, opts ...ClientOption) (*BaseClient, error) { + cfg := options{} + for _, opt := range opts { + opt.apply(&cfg) + } + + conn, err := grpc.Dial(url, cfg.dialOptions...) if err != nil { return nil, err } @@ -98,10 +103,7 @@ func NewBaseClient(url string, opts ...grpc.DialOption) (*BaseClient, error) { rpcClient: grpcClient, executionDataClient: execDataClient, close: func() error { return conn.Close() }, - jsonOptions: []json.Option{ - json.WithAllowUnstructuredStaticTypes(true), - json.WithBackwardsCompatibility(), - }, + jsonOptions: cfg.jsonOptions, }, nil }