@agoric/cosmos 0.34.2-dev-7cc5def.0 → 0.35.0-u11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -87,78 +87,6 @@ func local_request_Query_Data_0(ctx context.Context, marshaler runtime.Marshaler
87
87
 
88
88
  }
89
89
 
90
- var (
91
- filter_Query_CapData_0 = &utilities.DoubleArray{Encoding: map[string]int{"path": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
92
- )
93
-
94
- func request_Query_CapData_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
95
- var protoReq QueryCapDataRequest
96
- var metadata runtime.ServerMetadata
97
-
98
- var (
99
- val string
100
- ok bool
101
- err error
102
- _ = err
103
- )
104
-
105
- val, ok = pathParams["path"]
106
- if !ok {
107
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "path")
108
- }
109
-
110
- protoReq.Path, err = runtime.String(val)
111
-
112
- if err != nil {
113
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "path", err)
114
- }
115
-
116
- if err := req.ParseForm(); err != nil {
117
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
118
- }
119
- if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_CapData_0); err != nil {
120
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
121
- }
122
-
123
- msg, err := client.CapData(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
124
- return msg, metadata, err
125
-
126
- }
127
-
128
- func local_request_Query_CapData_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
129
- var protoReq QueryCapDataRequest
130
- var metadata runtime.ServerMetadata
131
-
132
- var (
133
- val string
134
- ok bool
135
- err error
136
- _ = err
137
- )
138
-
139
- val, ok = pathParams["path"]
140
- if !ok {
141
- return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "path")
142
- }
143
-
144
- protoReq.Path, err = runtime.String(val)
145
-
146
- if err != nil {
147
- return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "path", err)
148
- }
149
-
150
- if err := req.ParseForm(); err != nil {
151
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
152
- }
153
- if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_CapData_0); err != nil {
154
- return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
155
- }
156
-
157
- msg, err := server.CapData(ctx, &protoReq)
158
- return msg, metadata, err
159
-
160
- }
161
-
162
90
  var (
163
91
  filter_Query_Children_0 = &utilities.DoubleArray{Encoding: map[string]int{"path": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
164
92
  )
@@ -260,29 +188,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
260
188
 
261
189
  })
262
190
 
263
- mux.Handle("GET", pattern_Query_CapData_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
264
- ctx, cancel := context.WithCancel(req.Context())
265
- defer cancel()
266
- var stream runtime.ServerTransportStream
267
- ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
268
- inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
269
- rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
270
- if err != nil {
271
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
272
- return
273
- }
274
- resp, md, err := local_request_Query_CapData_0(rctx, inboundMarshaler, server, req, pathParams)
275
- md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
276
- ctx = runtime.NewServerMetadataContext(ctx, md)
277
- if err != nil {
278
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
279
- return
280
- }
281
-
282
- forward_Query_CapData_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
283
-
284
- })
285
-
286
191
  mux.Handle("GET", pattern_Query_Children_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
287
192
  ctx, cancel := context.WithCancel(req.Context())
288
193
  defer cancel()
@@ -367,26 +272,6 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
367
272
 
368
273
  })
369
274
 
370
- mux.Handle("GET", pattern_Query_CapData_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
371
- ctx, cancel := context.WithCancel(req.Context())
372
- defer cancel()
373
- inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
374
- rctx, err := runtime.AnnotateContext(ctx, mux, req)
375
- if err != nil {
376
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
377
- return
378
- }
379
- resp, md, err := request_Query_CapData_0(rctx, inboundMarshaler, client, req, pathParams)
380
- ctx = runtime.NewServerMetadataContext(ctx, md)
381
- if err != nil {
382
- runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
383
- return
384
- }
385
-
386
- forward_Query_CapData_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
387
-
388
- })
389
-
390
275
  mux.Handle("GET", pattern_Query_Children_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
391
276
  ctx, cancel := context.WithCancel(req.Context())
392
277
  defer cancel()
@@ -413,15 +298,11 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
413
298
  var (
414
299
  pattern_Query_Data_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"agoric", "vstorage", "data", "path"}, "", runtime.AssumeColonVerbOpt(false)))
415
300
 
416
- pattern_Query_CapData_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"agoric", "vstorage", "capdata", "path"}, "", runtime.AssumeColonVerbOpt(false)))
417
-
418
301
  pattern_Query_Children_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"agoric", "vstorage", "children", "path"}, "", runtime.AssumeColonVerbOpt(false)))
419
302
  )
420
303
 
421
304
  var (
422
305
  forward_Query_Data_0 = runtime.ForwardResponseMessage
423
306
 
424
- forward_Query_CapData_0 = runtime.ForwardResponseMessage
425
-
426
307
  forward_Query_Children_0 = runtime.ForwardResponseMessage
427
308
  )
@@ -1,95 +0,0 @@
1
- # Virtual Storage
2
-
3
- This module manages "[IAVL](https://github.com/cosmos/iavl)" chain storage data with a hierarchical keyspace in which each key is a "[path](./types/path_keys.go)" composed of zero or more dot-separated nonempty segments in a restricted alphabet. It exposes gRPC endpoints to arbitrary external clients for reading data, and internal read/write interfaces for use by SwingSet (which itself manages further subtree-scoped attenuation).
4
-
5
- ## Internal Go interface
6
-
7
- [Keeper](./keeper/keeper.go)
8
- * generic
9
- * GetChildren
10
- * GetEntry
11
- * HasEntry
12
- * HasStorage
13
- * SetStorage[AndNotify]
14
- * StreamCell-oriented (a StreamCell captures a block height and an array of values)
15
- * AppendStorageValue[AndNotify]
16
- * queue-oriented (a queue stores items at paths like "$prefix.$n", documenting
17
- the n for the next item to be consumed at "$prefix.head" and the n for the next
18
- next item to be pushed at "$prefix.tail" such that the queue is empty when both
19
- head and tail store the same n)
20
- * GetQueueLength
21
- * PushQueueItem
22
-
23
- ## Internal JSON interface
24
-
25
- This is used by the SwingSet "bridge".
26
-
27
- [Receive](./vstorage.go) with input `{ "method": "...", "args": [...] }`
28
- * generic
29
- * method "entries", args path
30
- * method "get"/"has", args path
31
- * method "set"/"setWithoutNotify", args [[path, value?], ...]
32
- * method "children", args path
33
- * method "values", args path (returns values for children in the same order as method "children")
34
- * method "size", args path (returns the count of children)
35
- * StreamCell-oriented
36
- * method "append", args [[path, value?], ...]
37
-
38
- ## CLI
39
-
40
- A blockchain node may be interrogated by RPC using `agd [--node $url] query vstorage $command` via [client/cli](./client/cli/query.go).
41
- * `children [--height $blockHeight] [-o {text,json}] [$path]`
42
- * `data [--height $blockHeight] [-o {text,json}] $path`
43
-
44
- Examples:
45
- ```sh
46
- $ agd --node https://main.rpc.agoric.net:443/ query vstorage children published.reserve
47
- children:
48
- - governance
49
- - metrics
50
- pagination: null
51
-
52
- $ agd --node https://main.rpc.agoric.net:443/ query vstorage children -o json published.reserve
53
- {"children":["governance","metrics"],"pagination":null}
54
-
55
- $ agd --node https://main.rpc.agoric.net:443/ query vstorage data published.reserve.metrics
56
- value: '{"blockHeight":"11030240","values":["{\"body\":\"#{\\\"allocations\\\":{\\\"Fee\\\":{\\\"brand\\\":\\\"$0.Alleged:
57
- IST brand\\\",\\\"value\\\":\\\"+20053582387\\\"}},\\\"shortfallBalance\\\":{\\\"brand\\\":\\\"$0\\\",\\\"value\\\":\\\"+0\\\"},\\\"totalFeeBurned\\\":{\\\"brand\\\":\\\"$0\\\",\\\"value\\\":\\\"+0\\\"},\\\"totalFeeMinted\\\":{\\\"brand\\\":\\\"$0\\\",\\\"value\\\":\\\"+0\\\"}}\",\"slots\":[\"board0257\"]}"]}'
58
- ```
59
-
60
- ## External protobuf interface
61
-
62
- RPC via [Querier](./keeper/grpc_query.go),
63
- and [CometBFT method "abci_query"](https://docs.cometbft.com/main/rpc/#/ABCI/abci_query)
64
- with params `path` "/agoric.vstorage.Query/..."
65
- and `data` \<serialized protobuf per [vstorage/query.proto](../../proto/agoric/vstorage/query.proto)>
66
- (also via [Querier](./keeper/grpc_query.go))
67
- * /agoric.vstorage.Query/CapData
68
- * /agoric.vstorage.Query/Children
69
- * /agoric.vstorage.Query/Data
70
-
71
- ## External JSON interface
72
-
73
- As described at [Cosmos SDK: Using the REST Endpoints](https://docs.cosmos.network/main/run-node/interact-node#using-the-rest-endpoints), a blockchain node whose [`app.toml` configuration](https://docs.cosmos.network/main/run-node/run-node#configuring-the-node-using-apptoml-and-configtoml) enables the "REST" API server uses [gRPC-Gateway](https://grpc-ecosystem.github.io/grpc-gateway/) and `google.api.http` annotations in [vstorage/query.proto](../../proto/agoric/vstorage/query.proto) to automatically translate the protobuf-based RPC endpoints into URL paths that accept query parameters and emit JSON.
74
- * /agoric/vstorage/capdata/$path?remotableValueFormat={object,string}[&mediaType=JSON%20Lines][&itemFormat=flat]
75
- * /agoric/vstorage/children/$path
76
- * /agoric/vstorage/data/$path
77
-
78
- Example:
79
- ```sh
80
- $ curl -sS 'https://main.api.agoric.net/agoric/vstorage/children/published.committees'
81
- {
82
- "children": [
83
- "Economic_Committee"
84
- ],
85
- "pagination": null
86
- }
87
- ```
88
-
89
- ## Arbitrary-response HTTP interface
90
-
91
- This depends upon appModule `LegacyQuerierHandler` functionality that is [removed from cosmos-sdk as of v0.47](https://github.com/cosmos/cosmos-sdk/blob/fa4d87ef7e6d87aaccc94c337ffd2fe90fcb7a9d/CHANGELOG.md#api-breaking-changes-3)
92
-
93
- [legacy querier](./keeper/querier.go)
94
- * /custom/vstorage/children/$path
95
- * /custom/vstorage/data/$path
@@ -1,298 +0,0 @@
1
- package capdata
2
-
3
- import (
4
- "bytes"
5
- "encoding/json"
6
- "fmt"
7
- "regexp"
8
- "strconv"
9
- "strings"
10
- )
11
-
12
- // JsonMarshal returns JSON text representing its input,
13
- // without special replacement of "<", ">", "&", U+2028, or U+2029.
14
- func JsonMarshal(val any) ([]byte, error) {
15
- buf := &bytes.Buffer{}
16
- encoder := json.NewEncoder(buf)
17
- encoder.SetEscapeHTML(false)
18
- if err := encoder.Encode(val); err != nil {
19
- return nil, err
20
- }
21
- // Return without a trailing line feed.
22
- lineTerminatedJson := buf.Bytes()
23
- return bytes.TrimSuffix(lineTerminatedJson, []byte("\n")), nil
24
- }
25
-
26
- // cf. https://github.com/endojs/endo/tree/master/packages/marshal
27
-
28
- type Capdata struct {
29
- Body string `json:"body"`
30
- Slots []interface{} `json:"slots"`
31
- }
32
-
33
- var validBigint = regexp.MustCompile(`^-?(?:0|[1-9][0-9]*)$`)
34
-
35
- type CapdataBigint struct {
36
- Normalized string
37
- }
38
-
39
- type CapdataRemotable struct {
40
- Id interface{}
41
- Iface *string
42
- Representation interface{}
43
- }
44
-
45
- func NewCapdataBigint(str string) *CapdataBigint {
46
- if !validBigint.MatchString(str) {
47
- return nil
48
- }
49
- bigint := CapdataBigint{str}
50
- return &bigint
51
- }
52
-
53
- func (r *CapdataRemotable) MarshalJSON() ([]byte, error) {
54
- return JsonMarshal(r.Representation)
55
- }
56
-
57
- type CapdataValueTransformations struct {
58
- Bigint func(*CapdataBigint) interface{}
59
- Remotable func(*CapdataRemotable) interface{}
60
- }
61
-
62
- // upsertCapdataRemotable either adds a new CapdataRemotable to `remotables` at the specified
63
- // slot index or updates the iface of the value that is already there, ensuring lack of iface name
64
- // inconsistency (iteration order is not guaranteed to correspond with JSON text like it does in
65
- // JavaScript, so we must accept encountering the "first" reference to a slot late
66
- // and must therefore also defer transformations).
67
- func upsertCapdataRemotable(remotables map[uint64]*CapdataRemotable, slotIndex uint64, id interface{}, iface *string) (*CapdataRemotable, error) {
68
- r := remotables[slotIndex]
69
- if r == nil {
70
- r = new(CapdataRemotable)
71
- r.Id = id
72
- r.Iface = iface
73
- remotables[slotIndex] = r
74
- } else if iface != nil {
75
- if r.Iface != nil && *iface != *r.Iface {
76
- return nil, fmt.Errorf("slot iface mismatch: %q", *iface)
77
- }
78
- r.Iface = iface
79
- }
80
- return r, nil
81
- }
82
-
83
- // decodeCapdataLegacyValue decodes the non-smallcaps encoding of
84
- // https://github.com/endojs/endo/blob/master/packages/marshal/src/encodeToCapData.js
85
- func decodeCapdataLegacyValue(
86
- encoded interface{},
87
- slots []interface{},
88
- remotables map[uint64]*CapdataRemotable,
89
- transformations CapdataValueTransformations,
90
- ) (interface{}, error) {
91
- if arr, ok := encoded.([]interface{}); ok {
92
- for i, v := range arr {
93
- decoded, err := decodeCapdataLegacyValue(v, slots, remotables, transformations)
94
- if err != nil {
95
- return nil, err
96
- }
97
- arr[i] = decoded
98
- }
99
- return arr, nil
100
- } else if obj, ok := encoded.(map[string]interface{}); ok {
101
- if qclassVal, ok := obj["@qclass"]; ok {
102
- qclass, ok := qclassVal.(string)
103
- if !ok {
104
- return nil, fmt.Errorf("invalid @qclass: %q", qclassVal)
105
- }
106
- switch qclass {
107
- case "bigint":
108
- var bigint *CapdataBigint
109
- digitsVal := obj["digits"]
110
- if digitsStr, ok := digitsVal.(string); ok {
111
- bigint = NewCapdataBigint(digitsStr)
112
- }
113
- if bigint == nil {
114
- return nil, fmt.Errorf("invalid bigint: %q", digitsVal)
115
- }
116
- if transformations.Bigint == nil {
117
- return nil, fmt.Errorf("untransformed bigint")
118
- }
119
- return transformations.Bigint(bigint), nil
120
- case "slot":
121
- var iface *string
122
- slotIndexVal, ifaceVal := obj["index"], obj["iface"]
123
- slotIndexNum, ok := slotIndexVal.(float64)
124
- slotIndex := uint64(slotIndexNum)
125
- if !ok || float64(slotIndex) != slotIndexNum || slotIndex >= uint64(len(slots)) {
126
- return nil, fmt.Errorf("invalid slot index: %q", slotIndexVal)
127
- }
128
- if ifaceStr, ok := ifaceVal.(string); ok {
129
- iface = &ifaceStr
130
- } else if ifaceVal != nil {
131
- return nil, fmt.Errorf("invalid slot iface: %q", ifaceVal)
132
- }
133
- return upsertCapdataRemotable(remotables, slotIndex, slots[slotIndex], iface)
134
- case "hilbert":
135
- fallthrough
136
- case "undefined":
137
- fallthrough
138
- case "NaN":
139
- fallthrough
140
- case "Infinity":
141
- fallthrough
142
- case "symbol":
143
- fallthrough
144
- case "tagged":
145
- fallthrough
146
- case "error":
147
- fallthrough
148
- case "-Infinity":
149
- return nil, fmt.Errorf("not implemented: @qclass %q", qclass)
150
- default:
151
- return nil, fmt.Errorf("unrecognized @qclass: %q", qclass)
152
- }
153
- }
154
- for k, v := range obj {
155
- decoded, err := decodeCapdataLegacyValue(v, slots, remotables, transformations)
156
- if err != nil {
157
- return nil, err
158
- }
159
- obj[k] = decoded
160
- }
161
- return obj, nil
162
- } else {
163
- return encoded, nil
164
- }
165
- }
166
-
167
- // decodeCapdataSmallcapsValue decodes the "smallcaps" encoding from
168
- // https://github.com/endojs/endo/blob/master/packages/marshal/src/encodeToSmallcaps.js
169
- func decodeCapdataSmallcapsValue(
170
- encoded interface{},
171
- slots []interface{},
172
- remotables map[uint64]*CapdataRemotable,
173
- transformations CapdataValueTransformations,
174
- ) (interface{}, error) {
175
- if arr, ok := encoded.([]interface{}); ok {
176
- for i, v := range arr {
177
- decoded, err := decodeCapdataSmallcapsValue(v, slots, remotables, transformations)
178
- if err != nil {
179
- return nil, err
180
- }
181
- arr[i] = decoded
182
- }
183
- return arr, nil
184
- } else if encodedObj, ok := encoded.(map[string]interface{}); ok {
185
- if _, ok := encodedObj["#tag"]; ok {
186
- return nil, fmt.Errorf("not implemented: #tag")
187
- }
188
- if _, ok := encodedObj["#error"]; ok {
189
- return nil, fmt.Errorf("not implemented: #error")
190
- }
191
- // We need a distinct output map to avoid reprocessing already-decoded keys.
192
- decodedObj := make(map[string]interface{}, len(encodedObj))
193
- for encodedK, v := range encodedObj {
194
- if strings.HasPrefix(encodedK, "#") {
195
- return nil, fmt.Errorf("unrecognized record type: %q", encodedK)
196
- }
197
- decodedK, err := decodeCapdataSmallcapsValue(encodedK, slots, remotables, CapdataValueTransformations{})
198
- k, ok := decodedK.(string)
199
- if err != nil || !ok {
200
- return nil, fmt.Errorf("invalid copyRecord key: %q", encodedK)
201
- }
202
- decoded, err := decodeCapdataSmallcapsValue(v, slots, remotables, transformations)
203
- if err != nil {
204
- return nil, err
205
- }
206
- decodedObj[k] = decoded
207
- }
208
- return decodedObj, nil
209
- } else if str, ok := encoded.(string); ok {
210
- if len(str) == 0 {
211
- return str, nil
212
- }
213
- switch str[0] {
214
- case '!':
215
- return str[1:], nil
216
- case '+':
217
- // Normalize to no leading "+".
218
- str = str[1:]
219
- fallthrough
220
- case '-':
221
- bigint := NewCapdataBigint(str)
222
- if bigint == nil {
223
- return nil, fmt.Errorf("invalid bigint: %q", encoded.(string))
224
- }
225
- if transformations.Bigint == nil {
226
- return nil, fmt.Errorf("untransformed bigint")
227
- }
228
- return transformations.Bigint(bigint), nil
229
- case '$':
230
- var slotIndexStr string
231
- var iface *string
232
- if dotIndex := strings.IndexByte(str, '.'); dotIndex >= 0 {
233
- slotIndexStr = str[1:dotIndex]
234
- ifaceStr := str[dotIndex+1:]
235
- iface = &ifaceStr
236
- } else {
237
- slotIndexStr = str[1:]
238
- }
239
- slotIndex, err := strconv.ParseUint(slotIndexStr, 10, 0)
240
- if err != nil || slotIndex >= uint64(len(slots)) {
241
- return nil, fmt.Errorf("invalid slot index: %q", str)
242
- }
243
- r, err := upsertCapdataRemotable(remotables, slotIndex, slots[slotIndex], iface)
244
- if err != nil {
245
- return nil, fmt.Errorf("slot iface mismatch: %q", str)
246
- }
247
- return r, nil
248
- case '#':
249
- fallthrough
250
- case '%':
251
- fallthrough
252
- case '&':
253
- return nil, fmt.Errorf("not implemented: %q", str)
254
- default:
255
- if str[0] >= '!' && str[0] <= '-' {
256
- return nil, fmt.Errorf("invalid smallcaps encoding prefix: %q", str[:1])
257
- }
258
- }
259
- return str, nil
260
- } else {
261
- return encoded, nil
262
- }
263
- }
264
-
265
- // DecodeSerializedCapdata accepts JSON text representing encoded CapData and
266
- // decodes it, applying specified transformations for values that otherwise
267
- // hinder interchange.
268
- func DecodeSerializedCapdata(
269
- serializedCapdata string,
270
- transformations CapdataValueTransformations,
271
- ) (interface{}, error) {
272
- var capdata Capdata
273
- if err := json.Unmarshal([]byte(serializedCapdata), &capdata); err != nil {
274
- return nil, err
275
- }
276
- if capdata.Body == "" || capdata.Slots == nil {
277
- return nil, fmt.Errorf("invalid CapData")
278
- }
279
- serializedBody, decodeValue := capdata.Body, decodeCapdataLegacyValue
280
- if strings.HasPrefix(serializedBody, "#") {
281
- serializedBody, decodeValue = serializedBody[1:], decodeCapdataSmallcapsValue
282
- }
283
- var encoded interface{}
284
- if err := json.Unmarshal([]byte(serializedBody), &encoded); err != nil {
285
- return nil, err
286
- }
287
- remotables := map[uint64]*CapdataRemotable{}
288
- decoded, err := decodeValue(encoded, capdata.Slots, remotables, transformations)
289
- if err == nil && len(remotables) > 0 {
290
- if transformations.Remotable == nil {
291
- return nil, fmt.Errorf("untransformed remotable")
292
- }
293
- for _, r := range remotables {
294
- r.Representation = transformations.Remotable(r)
295
- }
296
- }
297
- return decoded, err
298
- }