@sparkdreamnft/sparkdreamjs 0.0.45 → 0.0.47
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.
- package/akash/bundle.d.ts +134 -134
- package/akash/bundle.js +150 -150
- package/amino-schema.d.ts +5741 -0
- package/amino-schema.js +8 -0
- package/chain-amino.d.ts +61 -0
- package/chain-amino.js +670 -0
- package/cosmos/bundle.d.ts +160 -160
- package/cosmos/bundle.js +182 -182
- package/esm/akash/bundle.js +150 -150
- package/esm/amino-schema.js +5 -0
- package/esm/chain-amino.js +665 -0
- package/esm/cosmos/bundle.js +182 -182
- package/esm/ibc/bundle.js +116 -116
- package/esm/nested-amino.js +12 -4
- package/esm/sparkdream/artifact/v1/genesis.js +217 -3
- package/esm/sparkdream/artifact/v1/params.js +146 -2
- package/esm/sparkdream/artifact/v1/query.js +3767 -5
- package/esm/sparkdream/artifact/v1/query.lcd.js +173 -0
- package/esm/sparkdream/artifact/v1/query.rpc.Query.js +195 -1
- package/esm/sparkdream/artifact/v1/tx.amino.js +16 -158
- package/esm/sparkdream/artifact/v1/tx.js +7498 -5
- package/esm/sparkdream/artifact/v1/tx.registry.js +704 -2
- package/esm/sparkdream/artifact/v1/tx.rpc.msg.js +241 -1
- package/esm/sparkdream/artifact/v1/types.js +4312 -1120
- package/esm/sparkdream/blog/v1/tx.amino.js +15 -115
- package/esm/sparkdream/bundle.js +329 -291
- package/esm/sparkdream/client.js +5 -2
- package/esm/sparkdream/collect/v1/tx.amino.js +15 -239
- package/esm/sparkdream/commons/v1/tx.amino.js +12 -226
- package/esm/sparkdream/commons/v1/tx.js +25 -1
- package/esm/sparkdream/ecosystem/v1/tx.amino.js +15 -26
- package/esm/sparkdream/federation/v1/tx.amino.js +16 -128
- package/esm/sparkdream/forum/v1/tx.amino.js +15 -211
- package/esm/sparkdream/futarchy/v1/tx.amino.js +16 -38
- package/esm/sparkdream/guardian/v1/tx.amino.js +17 -8
- package/esm/sparkdream/lcd.js +5 -0
- package/esm/sparkdream/name/v1/tx.amino.js +16 -63
- package/esm/sparkdream/rep/v1/genesis.js +74 -1
- package/esm/sparkdream/rep/v1/member.js +110 -1
- package/esm/sparkdream/rep/v1/migration.js +957 -0
- package/esm/sparkdream/rep/v1/params.js +181 -1
- package/esm/sparkdream/rep/v1/query.js +1060 -0
- package/esm/sparkdream/rep/v1/query.lcd.js +48 -0
- package/esm/sparkdream/rep/v1/query.rpc.Query.js +65 -1
- package/esm/sparkdream/rep/v1/tx.amino.js +12 -414
- package/esm/sparkdream/rep/v1/tx.js +1741 -1
- package/esm/sparkdream/rep/v1/tx.registry.js +200 -2
- package/esm/sparkdream/rep/v1/tx.rpc.msg.js +67 -1
- package/esm/sparkdream/reveal/v1/tx.amino.js +15 -73
- package/esm/sparkdream/rpc.query.js +3 -0
- package/esm/sparkdream/rpc.tx.js +3 -0
- package/esm/sparkdream/season/v1/tx.amino.js +16 -218
- package/esm/sparkdream/service/v1/tx.amino.js +16 -78
- package/esm/sparkdream/session/v1/tx.amino.js +16 -271
- package/esm/sparkdream/session/v1/tx.js +38 -2
- package/esm/sparkdream/shield/v1/tx.amino.js +15 -80
- package/esm/sparkdream/sparkdream/v1/tx.amino.js +16 -8
- package/esm/sparkdream/split/v1/tx.amino.js +16 -8
- package/esm/sparkdream/vault/module/v1/module.js +71 -0
- package/esm/sparkdream/vault/v1/genesis.js +104 -0
- package/esm/sparkdream/vault/v1/params.js +90 -0
- package/esm/sparkdream/vault/v1/query.js +1535 -0
- package/esm/sparkdream/vault/v1/query.lcd.js +100 -0
- package/esm/sparkdream/vault/v1/query.rpc.Query.js +111 -0
- package/esm/sparkdream/vault/v1/tx.amino.js +18 -0
- package/esm/sparkdream/vault/v1/tx.js +1393 -0
- package/esm/sparkdream/vault/v1/tx.registry.js +159 -0
- package/esm/sparkdream/vault/v1/tx.rpc.msg.js +60 -0
- package/esm/sparkdream/vault/v1/vault.js +163 -0
- package/esm/sparkdream/vault/v1/vault_proposal.js +277 -0
- package/esm/sparkdream/vault/v1/vault_signer.js +85 -0
- package/esm/tendermint/bundle.js +20 -20
- package/ibc/bundle.d.ts +99 -99
- package/ibc/bundle.js +116 -116
- package/nested-amino.d.ts +7 -2
- package/nested-amino.js +13 -4
- package/package.json +1 -13
- package/sparkdream/artifact/v1/genesis.d.ts +37 -4
- package/sparkdream/artifact/v1/genesis.js +216 -2
- package/sparkdream/artifact/v1/params.d.ts +92 -0
- package/sparkdream/artifact/v1/params.js +146 -2
- package/sparkdream/artifact/v1/query.d.ts +2373 -168
- package/sparkdream/artifact/v1/query.js +3768 -5
- package/sparkdream/artifact/v1/query.lcd.d.ts +22 -1
- package/sparkdream/artifact/v1/query.lcd.js +173 -0
- package/sparkdream/artifact/v1/query.rpc.Query.d.ts +98 -1
- package/sparkdream/artifact/v1/query.rpc.Query.js +194 -0
- package/sparkdream/artifact/v1/tx.amino.d.ts +1 -158
- package/sparkdream/artifact/v1/tx.amino.js +49 -158
- package/sparkdream/artifact/v1/tx.d.ts +5188 -930
- package/sparkdream/artifact/v1/tx.js +7499 -5
- package/sparkdream/artifact/v1/tx.registry.d.ts +469 -1
- package/sparkdream/artifact/v1/tx.registry.js +703 -1
- package/sparkdream/artifact/v1/tx.rpc.msg.d.ts +136 -1
- package/sparkdream/artifact/v1/tx.rpc.msg.js +240 -0
- package/sparkdream/artifact/v1/types.d.ts +1797 -25
- package/sparkdream/artifact/v1/types.js +4322 -1121
- package/sparkdream/blog/v1/tx.amino.d.ts +1 -83
- package/sparkdream/blog/v1/tx.amino.js +50 -117
- package/sparkdream/bundle.d.ts +12983 -10912
- package/sparkdream/bundle.js +329 -291
- package/sparkdream/client.d.ts +1 -1629
- package/sparkdream/client.js +5 -2
- package/sparkdream/collect/v1/tx.amino.d.ts +1 -138
- package/sparkdream/collect/v1/tx.amino.js +50 -241
- package/sparkdream/commons/v1/tx.amino.d.ts +1 -103
- package/sparkdream/commons/v1/tx.amino.js +49 -230
- package/sparkdream/commons/v1/tx.d.ts +18 -0
- package/sparkdream/commons/v1/tx.js +25 -1
- package/sparkdream/ecosystem/v1/tx.amino.d.ts +1 -13
- package/sparkdream/ecosystem/v1/tx.amino.js +50 -28
- package/sparkdream/federation/v1/tx.amino.d.ts +1 -128
- package/sparkdream/federation/v1/tx.amino.js +49 -128
- package/sparkdream/forum/v1/tx.amino.d.ts +1 -183
- package/sparkdream/forum/v1/tx.amino.js +50 -213
- package/sparkdream/futarchy/v1/tx.amino.d.ts +1 -38
- package/sparkdream/futarchy/v1/tx.amino.js +49 -38
- package/sparkdream/guardian/v1/tx.amino.d.ts +2 -8
- package/sparkdream/guardian/v1/tx.amino.js +52 -9
- package/sparkdream/lcd.d.ts +3 -0
- package/sparkdream/lcd.js +5 -0
- package/sparkdream/name/v1/tx.amino.d.ts +1 -63
- package/sparkdream/name/v1/tx.amino.js +49 -63
- package/sparkdream/rep/v1/genesis.d.ts +19 -0
- package/sparkdream/rep/v1/genesis.js +74 -1
- package/sparkdream/rep/v1/member.d.ts +92 -0
- package/sparkdream/rep/v1/member.js +110 -1
- package/sparkdream/rep/v1/migration.d.ts +587 -0
- package/sparkdream/rep/v1/migration.js +964 -0
- package/sparkdream/rep/v1/params.d.ts +174 -0
- package/sparkdream/rep/v1/params.js +181 -1
- package/sparkdream/rep/v1/query.d.ts +679 -0
- package/sparkdream/rep/v1/query.js +1061 -1
- package/sparkdream/rep/v1/query.lcd.d.ts +8 -1
- package/sparkdream/rep/v1/query.lcd.js +48 -0
- package/sparkdream/rep/v1/query.rpc.Query.d.ts +32 -1
- package/sparkdream/rep/v1/query.rpc.Query.js +64 -0
- package/sparkdream/rep/v1/tx.amino.d.ts +1 -283
- package/sparkdream/rep/v1/tx.amino.js +47 -416
- package/sparkdream/rep/v1/tx.d.ts +1185 -0
- package/sparkdream/rep/v1/tx.js +1742 -2
- package/sparkdream/rep/v1/tx.registry.d.ts +133 -1
- package/sparkdream/rep/v1/tx.registry.js +199 -1
- package/sparkdream/rep/v1/tx.rpc.msg.d.ts +34 -1
- package/sparkdream/rep/v1/tx.rpc.msg.js +66 -0
- package/sparkdream/reveal/v1/tx.amino.d.ts +1 -53
- package/sparkdream/reveal/v1/tx.amino.js +50 -75
- package/sparkdream/rpc.query.d.ts +42 -0
- package/sparkdream/rpc.query.js +3 -0
- package/sparkdream/rpc.tx.d.ts +3 -0
- package/sparkdream/rpc.tx.js +3 -0
- package/sparkdream/season/v1/tx.amino.d.ts +1 -218
- package/sparkdream/season/v1/tx.amino.js +49 -218
- package/sparkdream/service/v1/tx.amino.d.ts +1 -78
- package/sparkdream/service/v1/tx.amino.js +49 -78
- package/sparkdream/session/v1/tx.amino.d.ts +1 -93
- package/sparkdream/session/v1/tx.amino.js +48 -270
- package/sparkdream/session/v1/tx.d.ts +30 -0
- package/sparkdream/session/v1/tx.js +38 -2
- package/sparkdream/shield/v1/tx.amino.d.ts +1 -28
- package/sparkdream/shield/v1/tx.amino.js +50 -82
- package/sparkdream/sparkdream/v1/tx.amino.d.ts +1 -8
- package/sparkdream/sparkdream/v1/tx.amino.js +49 -8
- package/sparkdream/split/v1/tx.amino.d.ts +1 -8
- package/sparkdream/split/v1/tx.amino.js +49 -8
- package/sparkdream/vault/module/v1/module.d.ts +54 -0
- package/sparkdream/vault/module/v1/module.js +74 -0
- package/sparkdream/vault/v1/genesis.d.ts +59 -0
- package/sparkdream/vault/v1/genesis.js +107 -0
- package/sparkdream/vault/v1/params.d.ts +68 -0
- package/sparkdream/vault/v1/params.js +93 -0
- package/sparkdream/vault/v1/query.d.ts +935 -0
- package/sparkdream/vault/v1/query.js +1538 -0
- package/sparkdream/vault/v1/query.lcd.d.ts +18 -0
- package/sparkdream/vault/v1/query.lcd.js +104 -0
- package/sparkdream/vault/v1/query.rpc.Query.d.ts +56 -0
- package/sparkdream/vault/v1/query.rpc.Query.js +116 -0
- package/sparkdream/vault/v1/tx.amino.d.ts +2 -0
- package/sparkdream/vault/v1/tx.amino.js +55 -0
- package/sparkdream/vault/v1/tx.d.ts +826 -0
- package/sparkdream/vault/v1/tx.js +1399 -0
- package/sparkdream/vault/v1/tx.registry.d.ts +109 -0
- package/sparkdream/vault/v1/tx.registry.js +163 -0
- package/sparkdream/vault/v1/tx.rpc.msg.d.ts +37 -0
- package/sparkdream/vault/v1/tx.rpc.msg.js +65 -0
- package/sparkdream/vault/v1/vault.d.ts +117 -0
- package/sparkdream/vault/v1/vault.js +166 -0
- package/sparkdream/vault/v1/vault_proposal.d.ts +158 -0
- package/sparkdream/vault/v1/vault_proposal.js +285 -0
- package/sparkdream/vault/v1/vault_signer.d.ts +54 -0
- package/sparkdream/vault/v1/vault_signer.js +88 -0
- package/tendermint/bundle.d.ts +844 -844
- package/tendermint/bundle.js +20 -20
- package/varint.d.ts +1 -1
|
@@ -0,0 +1,665 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Amino-JSON converters (the sign mode Keplr+Ledger use) for every sparkdream
|
|
3
|
+
* Msg, matching the chain's cosmossdk.io/x/tx@v0.14.0 signing/aminojson byte
|
|
4
|
+
* for byte.
|
|
5
|
+
*
|
|
6
|
+
* Instead of one hand-written converter per message (which drifted from the
|
|
7
|
+
* protos on every sync: missing messages, stale field sets, `[]` for empty
|
|
8
|
+
* lists, empty bytes as "", human-readable Dec strings, lost oneof wrappers),
|
|
9
|
+
* every module's AminoConverter map is built here from one schema:
|
|
10
|
+
*
|
|
11
|
+
* - toAmino encodes the message with its Telescope codec, decodes the
|
|
12
|
+
* protobuf bytes and renders them with aminojson's rules
|
|
13
|
+
* (json_marshal.go, encoder.go, any.go, time.go), as the chain does.
|
|
14
|
+
* - fromAmino is the exact inverse: amino JSON to protobuf bytes, decoded
|
|
15
|
+
* with the codec.
|
|
16
|
+
*
|
|
17
|
+
* The schema (amino-schema.ts) is exported by the chain repo
|
|
18
|
+
* (`go run ./cmd/aminogolden schema`): field names, kinds and the options
|
|
19
|
+
* aminojson acts on (dont_omitempty, cosmos_proto.scalar, amino.encoding,
|
|
20
|
+
* oneof names, gogoproto.nullable). __tests__/amino-golden.test.ts checks
|
|
21
|
+
* every Msg against the chain's own encoder.
|
|
22
|
+
*
|
|
23
|
+
* An Any whose inner type the schema does not describe (a cosmos-sdk message
|
|
24
|
+
* inside a proposal) is converted through the registry and AminoTypes given
|
|
25
|
+
* to configureNestedAminoConverter, as before.
|
|
26
|
+
*/
|
|
27
|
+
import { getNestedAminoConfig } from "./nested-amino";
|
|
28
|
+
import { aminoSchema } from "./amino-schema";
|
|
29
|
+
const schema = aminoSchema;
|
|
30
|
+
const BUILTIN = new Set(["google.protobuf.Timestamp", "google.protobuf.Duration", "google.protobuf.Any"]);
|
|
31
|
+
const byAminoName = new Map();
|
|
32
|
+
for (const [name, md] of Object.entries(schema.messages))
|
|
33
|
+
if (md.a)
|
|
34
|
+
byAminoName.set(md.a, name);
|
|
35
|
+
function readVarint(buf, pos) {
|
|
36
|
+
let result = BigInt(0);
|
|
37
|
+
let shift = BigInt(0);
|
|
38
|
+
for (;;) {
|
|
39
|
+
if (pos.i >= buf.length)
|
|
40
|
+
throw new Error("truncated varint");
|
|
41
|
+
const b = buf[pos.i++];
|
|
42
|
+
result |= BigInt(b & 0x7f) << shift;
|
|
43
|
+
if ((b & 0x80) === 0)
|
|
44
|
+
return result;
|
|
45
|
+
shift += BigInt(7);
|
|
46
|
+
if (shift > BigInt(63))
|
|
47
|
+
throw new Error("varint overflow");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function readFixed(buf, pos, size) {
|
|
51
|
+
if (pos.i + size > buf.length)
|
|
52
|
+
throw new Error("truncated fixed");
|
|
53
|
+
let v = BigInt(0);
|
|
54
|
+
for (let j = size - 1; j >= 0; j--)
|
|
55
|
+
v = (v << BigInt(8)) | BigInt(buf[pos.i + j]);
|
|
56
|
+
pos.i += size;
|
|
57
|
+
return v;
|
|
58
|
+
}
|
|
59
|
+
function parseFields(buf) {
|
|
60
|
+
const out = new Map();
|
|
61
|
+
const pos = { i: 0 };
|
|
62
|
+
while (pos.i < buf.length) {
|
|
63
|
+
const tag = Number(readVarint(buf, pos));
|
|
64
|
+
const no = tag >>> 3;
|
|
65
|
+
const wire = tag & 7;
|
|
66
|
+
let v;
|
|
67
|
+
switch (wire) {
|
|
68
|
+
case 0:
|
|
69
|
+
v = { wire, num: readVarint(buf, pos) };
|
|
70
|
+
break;
|
|
71
|
+
case 1:
|
|
72
|
+
v = { wire, num: readFixed(buf, pos, 8) };
|
|
73
|
+
break;
|
|
74
|
+
case 5:
|
|
75
|
+
v = { wire, num: readFixed(buf, pos, 4) };
|
|
76
|
+
break;
|
|
77
|
+
case 2: {
|
|
78
|
+
const len = Number(readVarint(buf, pos));
|
|
79
|
+
if (pos.i + len > buf.length)
|
|
80
|
+
throw new Error("truncated bytes");
|
|
81
|
+
v = { wire, bytes: buf.subarray(pos.i, pos.i + len) };
|
|
82
|
+
pos.i += len;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
default:
|
|
86
|
+
throw new Error(`unsupported wire type ${wire}`);
|
|
87
|
+
}
|
|
88
|
+
const list = out.get(no);
|
|
89
|
+
if (list)
|
|
90
|
+
list.push(v);
|
|
91
|
+
else
|
|
92
|
+
out.set(no, [v]);
|
|
93
|
+
}
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
const VARINT_KINDS = new Set(["int32", "int64", "uint32", "uint64", "sint32", "sint64", "bool", "enum"]);
|
|
97
|
+
const FIXED32_KINDS = new Set(["fixed32", "sfixed32", "float"]);
|
|
98
|
+
const FIXED64_KINDS = new Set(["fixed64", "sfixed64", "double"]);
|
|
99
|
+
const NUMERIC_KINDS = new Set([...VARINT_KINDS, ...FIXED32_KINDS, ...FIXED64_KINDS]);
|
|
100
|
+
/** Scalar elements of a field, unpacking packed encodings. */
|
|
101
|
+
function scalarElements(f, values) {
|
|
102
|
+
const out = [];
|
|
103
|
+
for (const v of values) {
|
|
104
|
+
if (v.wire === 2 && NUMERIC_KINDS.has(f.k)) {
|
|
105
|
+
const pos = { i: 0 };
|
|
106
|
+
const b = v.bytes;
|
|
107
|
+
while (pos.i < b.length) {
|
|
108
|
+
if (VARINT_KINDS.has(f.k))
|
|
109
|
+
out.push(readVarint(b, pos));
|
|
110
|
+
else
|
|
111
|
+
out.push(readFixed(b, pos, FIXED32_KINDS.has(f.k) ? 4 : 8));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
out.push(v.num);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return out;
|
|
119
|
+
}
|
|
120
|
+
function concatBytes(parts) {
|
|
121
|
+
if (parts.length === 1)
|
|
122
|
+
return parts[0];
|
|
123
|
+
const out = new Uint8Array(parts.reduce((n, p) => n + p.length, 0));
|
|
124
|
+
let o = 0;
|
|
125
|
+
for (const p of parts) {
|
|
126
|
+
out.set(p, o);
|
|
127
|
+
o += p.length;
|
|
128
|
+
}
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
131
|
+
// --------------------------------------------------------- wire encoding
|
|
132
|
+
class Writer {
|
|
133
|
+
parts = [];
|
|
134
|
+
varint(v) {
|
|
135
|
+
let n = BigInt.asUintN(64, v);
|
|
136
|
+
const bytes = [];
|
|
137
|
+
do {
|
|
138
|
+
let b = Number(n & BigInt(0x7f));
|
|
139
|
+
n >>= BigInt(7);
|
|
140
|
+
if (n > BigInt(0))
|
|
141
|
+
b |= 0x80;
|
|
142
|
+
bytes.push(b);
|
|
143
|
+
} while (n > BigInt(0));
|
|
144
|
+
this.parts.push(Uint8Array.from(bytes));
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
147
|
+
fixed(v, size) {
|
|
148
|
+
const out = new Uint8Array(size);
|
|
149
|
+
let n = BigInt.asUintN(size * 8, v);
|
|
150
|
+
for (let i = 0; i < size; i++) {
|
|
151
|
+
out[i] = Number(n & BigInt(0xff));
|
|
152
|
+
n >>= BigInt(8);
|
|
153
|
+
}
|
|
154
|
+
this.parts.push(out);
|
|
155
|
+
return this;
|
|
156
|
+
}
|
|
157
|
+
tag(no, wire) {
|
|
158
|
+
return this.varint(BigInt((no << 3) | wire));
|
|
159
|
+
}
|
|
160
|
+
bytes(no, b) {
|
|
161
|
+
this.tag(no, 2).varint(BigInt(b.length));
|
|
162
|
+
this.parts.push(b);
|
|
163
|
+
return this;
|
|
164
|
+
}
|
|
165
|
+
finish() {
|
|
166
|
+
return concatBytes(this.parts.length ? this.parts : [new Uint8Array()]);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// --------------------------------------------------------- value helpers
|
|
170
|
+
const utf8Decoder = new TextDecoder("utf-8", { fatal: true });
|
|
171
|
+
const utf8Encoder = new TextEncoder();
|
|
172
|
+
function base64(bytes) {
|
|
173
|
+
let s = "";
|
|
174
|
+
for (let i = 0; i < bytes.length; i++)
|
|
175
|
+
s += String.fromCharCode(bytes[i]);
|
|
176
|
+
return btoa(s);
|
|
177
|
+
}
|
|
178
|
+
function fromBase64(s) {
|
|
179
|
+
const bin = atob(s);
|
|
180
|
+
const out = new Uint8Array(bin.length);
|
|
181
|
+
for (let i = 0; i < bin.length; i++)
|
|
182
|
+
out[i] = bin.charCodeAt(i);
|
|
183
|
+
return out;
|
|
184
|
+
}
|
|
185
|
+
function zigzagDecode(u, bits) {
|
|
186
|
+
const v = BigInt.asUintN(bits, u);
|
|
187
|
+
return BigInt.asIntN(bits, (v >> BigInt(1)) ^ -(v & BigInt(1)));
|
|
188
|
+
}
|
|
189
|
+
function zigzagEncode(v, bits) {
|
|
190
|
+
const n = BigInt.asIntN(bits, v);
|
|
191
|
+
return BigInt.asUintN(bits, (n << BigInt(1)) ^ (n >> BigInt(bits - 1)));
|
|
192
|
+
}
|
|
193
|
+
function scalarJson(kind, n, bytes) {
|
|
194
|
+
const v = n ?? BigInt(0);
|
|
195
|
+
switch (kind) {
|
|
196
|
+
case "string":
|
|
197
|
+
return utf8Decoder.decode(bytes ?? new Uint8Array());
|
|
198
|
+
case "bytes":
|
|
199
|
+
// encoding/json marshals a nil []byte as null, a non-nil one as base64.
|
|
200
|
+
return bytes && bytes.length > 0 ? base64(bytes) : null;
|
|
201
|
+
case "bool":
|
|
202
|
+
return v !== BigInt(0);
|
|
203
|
+
case "int32":
|
|
204
|
+
case "enum":
|
|
205
|
+
case "sfixed32":
|
|
206
|
+
return Number(BigInt.asIntN(32, v));
|
|
207
|
+
case "uint32":
|
|
208
|
+
case "fixed32":
|
|
209
|
+
return Number(BigInt.asUintN(32, v));
|
|
210
|
+
case "sint32":
|
|
211
|
+
return Number(zigzagDecode(v, 32));
|
|
212
|
+
// 64-bit integers are quoted.
|
|
213
|
+
case "int64":
|
|
214
|
+
case "sfixed64":
|
|
215
|
+
return BigInt.asIntN(64, v).toString();
|
|
216
|
+
case "uint64":
|
|
217
|
+
case "fixed64":
|
|
218
|
+
return BigInt.asUintN(64, v).toString();
|
|
219
|
+
case "sint64":
|
|
220
|
+
return zigzagDecode(v, 64).toString();
|
|
221
|
+
}
|
|
222
|
+
// aminojson has no case for floats (marshal returns "unknown type").
|
|
223
|
+
throw new Error(`amino JSON cannot encode a ${kind} field`);
|
|
224
|
+
}
|
|
225
|
+
function isZeroScalar(kind, n, bytes) {
|
|
226
|
+
if (kind === "string" || kind === "bytes")
|
|
227
|
+
return !bytes || bytes.length === 0;
|
|
228
|
+
return (n ?? BigInt(0)) === BigInt(0);
|
|
229
|
+
}
|
|
230
|
+
/** math.LegacyDec.String() of an 18-decimal integer representation. */
|
|
231
|
+
function legacyDecString(atomics) {
|
|
232
|
+
if (!/^-?\d+$/.test(atomics))
|
|
233
|
+
throw new Error(`invalid LegacyDec ${JSON.stringify(atomics)}`);
|
|
234
|
+
const neg = atomics.startsWith("-");
|
|
235
|
+
let digits = BigInt(neg ? atomics.slice(1) : atomics).toString();
|
|
236
|
+
if (digits === "0")
|
|
237
|
+
return "0.000000000000000000";
|
|
238
|
+
digits = digits.padStart(19, "0");
|
|
239
|
+
return `${neg ? "-" : ""}${digits.slice(0, -18)}.${digits.slice(-18)}`;
|
|
240
|
+
}
|
|
241
|
+
/** Inverse of legacyDecString. */
|
|
242
|
+
function legacyDecAtomics(dec) {
|
|
243
|
+
const m = /^(-?)(\d+)(?:\.(\d{1,18}))?$/.exec(dec);
|
|
244
|
+
if (!m)
|
|
245
|
+
throw new Error(`invalid Dec ${JSON.stringify(dec)}`);
|
|
246
|
+
const atomics = BigInt(m[2] + (m[3] ?? "").padEnd(18, "0"));
|
|
247
|
+
return (m[1] && atomics !== BigInt(0) ? "-" : "") + atomics.toString();
|
|
248
|
+
}
|
|
249
|
+
function sortedJson(v) {
|
|
250
|
+
if (Array.isArray(v))
|
|
251
|
+
return v.map(sortedJson);
|
|
252
|
+
if (v && typeof v === "object") {
|
|
253
|
+
const o = v;
|
|
254
|
+
return Object.fromEntries(Object.keys(o).sort().map((k) => [k, sortedJson(o[k])]));
|
|
255
|
+
}
|
|
256
|
+
return v;
|
|
257
|
+
}
|
|
258
|
+
function rfc3339(seconds, nanos) {
|
|
259
|
+
if (nanos < 0)
|
|
260
|
+
throw new Error("nanos must be non-negative on timestamp");
|
|
261
|
+
const date = new Date(Number(seconds) * 1000);
|
|
262
|
+
if (Number.isNaN(date.getTime()))
|
|
263
|
+
throw new Error("timestamp out of range");
|
|
264
|
+
const base = date.toISOString().slice(0, 19);
|
|
265
|
+
if (nanos === 0)
|
|
266
|
+
return `${base}Z`;
|
|
267
|
+
return `${base}.${String(nanos).padStart(9, "0").replace(/0+$/, "")}Z`;
|
|
268
|
+
}
|
|
269
|
+
function parseRfc3339(s) {
|
|
270
|
+
const m = /^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(?:\.(\d{1,9}))?Z$/.exec(s);
|
|
271
|
+
if (!m)
|
|
272
|
+
throw new Error(`invalid timestamp ${JSON.stringify(s)}`);
|
|
273
|
+
const ms = Date.parse(`${m[1]}Z`);
|
|
274
|
+
return { seconds: BigInt(Math.floor(ms / 1000)), nanos: Number((m[2] ?? "").padEnd(9, "0")) };
|
|
275
|
+
}
|
|
276
|
+
// ---------------------------------------------------------------- render
|
|
277
|
+
function render(typeName, bytes, isAny) {
|
|
278
|
+
const md = schema.messages[typeName];
|
|
279
|
+
const name = isAny ? md?.a ?? `/${typeName}` : md?.a;
|
|
280
|
+
const value = renderMessage(typeName, bytes);
|
|
281
|
+
return name !== undefined ? { type: name, value } : value;
|
|
282
|
+
}
|
|
283
|
+
/** protoreflect Message.Has for a dynamic proto3 message. */
|
|
284
|
+
function fieldHas(f, values) {
|
|
285
|
+
if (values.length === 0)
|
|
286
|
+
return false;
|
|
287
|
+
if (f.k === "map")
|
|
288
|
+
return true;
|
|
289
|
+
if (f.r)
|
|
290
|
+
return NUMERIC_KINDS.has(f.k) ? scalarElements(f, values).length > 0 : true;
|
|
291
|
+
if (f.k === "message" || f.o || f.pr)
|
|
292
|
+
return true;
|
|
293
|
+
const last = values[values.length - 1];
|
|
294
|
+
return !isZeroScalar(f.k, last.num, last.bytes);
|
|
295
|
+
}
|
|
296
|
+
function renderMessage(typeName, bytes) {
|
|
297
|
+
switch (typeName) {
|
|
298
|
+
case "google.protobuf.Timestamp": {
|
|
299
|
+
const w = parseFields(bytes);
|
|
300
|
+
return rfc3339(BigInt.asIntN(64, w.get(1)?.at(-1)?.num ?? BigInt(0)), Number(BigInt.asIntN(32, w.get(2)?.at(-1)?.num ?? BigInt(0))));
|
|
301
|
+
}
|
|
302
|
+
case "google.protobuf.Duration": {
|
|
303
|
+
const w = parseFields(bytes);
|
|
304
|
+
const seconds = BigInt.asIntN(64, w.get(1)?.at(-1)?.num ?? BigInt(0));
|
|
305
|
+
const nanos = BigInt.asIntN(32, w.get(2)?.at(-1)?.num ?? BigInt(0));
|
|
306
|
+
return (nanos + seconds * BigInt(1_000_000_000)).toString();
|
|
307
|
+
}
|
|
308
|
+
case "google.protobuf.Any":
|
|
309
|
+
return renderAny(bytes);
|
|
310
|
+
}
|
|
311
|
+
const md = schema.messages[typeName];
|
|
312
|
+
if (!md)
|
|
313
|
+
throw new Error(`amino schema has no message ${typeName}`);
|
|
314
|
+
if (md.me)
|
|
315
|
+
throw new Error(`amino message_encoding ${md.me} (${typeName}) is not supported`);
|
|
316
|
+
const wire = parseFields(bytes);
|
|
317
|
+
const sortName = (f) => (f.o ? f.o[0] : f.n);
|
|
318
|
+
const fields = [...md.f].sort((a, b) => (sortName(a) < sortName(b) ? -1 : sortName(a) > sortName(b) ? 1 : 0));
|
|
319
|
+
const oneofSet = new Set(md.f.filter((f) => f.o && wire.has(f.no)).map((f) => f.o[0]));
|
|
320
|
+
const emptyOneofWritten = new Set();
|
|
321
|
+
const out = {};
|
|
322
|
+
for (const f of fields) {
|
|
323
|
+
const values = wire.get(f.no) ?? [];
|
|
324
|
+
let name = f.n;
|
|
325
|
+
let writeNil = false;
|
|
326
|
+
if (!fieldHas(f, values)) {
|
|
327
|
+
if (f.o && !oneofSet.has(f.o[0]) && !emptyOneofWritten.has(f.o[0])) {
|
|
328
|
+
name = f.o[0];
|
|
329
|
+
writeNil = true;
|
|
330
|
+
emptyOneofWritten.add(f.o[0]);
|
|
331
|
+
}
|
|
332
|
+
else if (!f.d) {
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
else if (f.k === "message" && !f.r) {
|
|
336
|
+
throw new Error(`not supported: dont_omit_empty=true on invalid (nil?) message field: ${f.n}`);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
let value;
|
|
340
|
+
const encoder = fieldEncoder(f);
|
|
341
|
+
if (encoder)
|
|
342
|
+
value = encoder(values);
|
|
343
|
+
else if (writeNil)
|
|
344
|
+
value = null;
|
|
345
|
+
else
|
|
346
|
+
value = renderValue(f, values);
|
|
347
|
+
if (f.o && !writeNil)
|
|
348
|
+
out[f.o[0]] = { type: f.o[1], value: { [name]: value } };
|
|
349
|
+
else
|
|
350
|
+
out[name] = value;
|
|
351
|
+
}
|
|
352
|
+
return out;
|
|
353
|
+
}
|
|
354
|
+
/** encoder.go getFieldEncoder: amino.encoding first, then cosmos_proto.scalar. */
|
|
355
|
+
function fieldEncoder(f) {
|
|
356
|
+
if (f.e === "legacy_coins")
|
|
357
|
+
return (values) => (values.length === 0 ? [] : renderList(f, values));
|
|
358
|
+
if (f.e === "inline_json") {
|
|
359
|
+
return (values) => sortedJson(JSON.parse(values.length ? utf8Decoder.decode(values[values.length - 1].bytes) : ""));
|
|
360
|
+
}
|
|
361
|
+
if (f.sc === "int" || f.sc === "dec") {
|
|
362
|
+
if (f.r)
|
|
363
|
+
throw new Error(`unsupported repeated ${f.sc} scalar ${f.n}`);
|
|
364
|
+
return (values) => {
|
|
365
|
+
const last = values[values.length - 1];
|
|
366
|
+
const text = last ? utf8Decoder.decode(last.bytes) : "";
|
|
367
|
+
if (text === "")
|
|
368
|
+
return "0";
|
|
369
|
+
if (f.sc === "dec")
|
|
370
|
+
return legacyDecString(text);
|
|
371
|
+
// cosmosIntEncoder: a string goes through as-is, bytes are parsed.
|
|
372
|
+
return f.k === "bytes" ? BigInt(text).toString() : text;
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
return undefined;
|
|
376
|
+
}
|
|
377
|
+
function renderValue(f, values) {
|
|
378
|
+
if (f.k === "map")
|
|
379
|
+
throw new Error("maps are not supported");
|
|
380
|
+
if (f.r)
|
|
381
|
+
return values.length === 0 ? null : renderList(f, values);
|
|
382
|
+
if (f.k === "message")
|
|
383
|
+
return renderMessage(f.t, concatBytes(values.map((v) => v.bytes)));
|
|
384
|
+
const last = values[values.length - 1];
|
|
385
|
+
// dont_omitempty on an unset scalar renders the zero value.
|
|
386
|
+
if (!last)
|
|
387
|
+
return scalarJson(f.k, BigInt(0), f.k === "string" ? new Uint8Array() : undefined);
|
|
388
|
+
return scalarJson(f.k, last.num, last.bytes);
|
|
389
|
+
}
|
|
390
|
+
function renderList(f, values) {
|
|
391
|
+
if (f.k === "message")
|
|
392
|
+
return values.map((v) => renderMessage(f.t, v.bytes));
|
|
393
|
+
if (f.k === "string" || f.k === "bytes")
|
|
394
|
+
return values.map((v) => scalarJson(f.k, undefined, v.bytes));
|
|
395
|
+
return scalarElements(f, values).map((n) => scalarJson(f.k, n, undefined));
|
|
396
|
+
}
|
|
397
|
+
function renderAny(bytes) {
|
|
398
|
+
const w = parseFields(bytes);
|
|
399
|
+
const typeUrl = utf8Decoder.decode(w.get(1)?.at(-1)?.bytes ?? new Uint8Array());
|
|
400
|
+
const value = w.get(2)?.at(-1)?.bytes ?? new Uint8Array();
|
|
401
|
+
if (!typeUrl.startsWith("/"))
|
|
402
|
+
throw new Error(`can't resolve type URL ${typeUrl}`);
|
|
403
|
+
const typeName = typeUrl.slice(1);
|
|
404
|
+
if (typeName in schema.messages)
|
|
405
|
+
return render(typeName, value, true);
|
|
406
|
+
const cfg = getNestedAminoConfig();
|
|
407
|
+
const codec = cfg?.registry.lookupType(typeUrl);
|
|
408
|
+
if (!cfg || !codec) {
|
|
409
|
+
throw new Error(`can't resolve type URL ${typeUrl}: call configureNestedAminoConverter({registry, aminoTypes}) ` +
|
|
410
|
+
"with a registry and AminoTypes that know it");
|
|
411
|
+
}
|
|
412
|
+
return cfg.aminoTypes.toAmino({ typeUrl, value: codec.decode(value) });
|
|
413
|
+
}
|
|
414
|
+
// ---------------------------------------------------------------- encode
|
|
415
|
+
/** Amino JSON of a message back to its protobuf bytes (the inverse of renderMessage). */
|
|
416
|
+
function encodeMessage(typeName, json) {
|
|
417
|
+
const w = new Writer();
|
|
418
|
+
switch (typeName) {
|
|
419
|
+
case "google.protobuf.Timestamp": {
|
|
420
|
+
const { seconds, nanos } = parseRfc3339(json);
|
|
421
|
+
if (seconds !== BigInt(0))
|
|
422
|
+
w.tag(1, 0).varint(seconds);
|
|
423
|
+
if (nanos !== 0)
|
|
424
|
+
w.tag(2, 0).varint(BigInt(nanos));
|
|
425
|
+
return w.finish();
|
|
426
|
+
}
|
|
427
|
+
case "google.protobuf.Duration": {
|
|
428
|
+
const total = BigInt(json);
|
|
429
|
+
const seconds = total / BigInt(1_000_000_000);
|
|
430
|
+
const nanos = total % BigInt(1_000_000_000);
|
|
431
|
+
if (seconds !== BigInt(0))
|
|
432
|
+
w.tag(1, 0).varint(seconds);
|
|
433
|
+
if (nanos !== BigInt(0))
|
|
434
|
+
w.tag(2, 0).varint(nanos);
|
|
435
|
+
return w.finish();
|
|
436
|
+
}
|
|
437
|
+
case "google.protobuf.Any": {
|
|
438
|
+
const { typeUrl, value } = encodeAny(json);
|
|
439
|
+
w.bytes(1, utf8Encoder.encode(typeUrl));
|
|
440
|
+
if (value.length)
|
|
441
|
+
w.bytes(2, value);
|
|
442
|
+
return w.finish();
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
const md = schema.messages[typeName];
|
|
446
|
+
if (!md)
|
|
447
|
+
throw new Error(`amino schema has no message ${typeName}`);
|
|
448
|
+
if (md.me)
|
|
449
|
+
throw new Error(`amino message_encoding ${md.me} (${typeName}) is not supported`);
|
|
450
|
+
if (json === null || typeof json !== "object")
|
|
451
|
+
throw new Error(`${typeName}: expected an object`);
|
|
452
|
+
for (const f of md.f) {
|
|
453
|
+
let value;
|
|
454
|
+
let present = false;
|
|
455
|
+
if (f.o) {
|
|
456
|
+
const wrapper = json[f.o[0]];
|
|
457
|
+
if (!wrapper || wrapper.type !== f.o[1] || !wrapper.value || !(f.n in wrapper.value))
|
|
458
|
+
continue;
|
|
459
|
+
value = wrapper.value[f.n];
|
|
460
|
+
present = true; // a set oneof member keeps its presence even at zero
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
value = json[f.n];
|
|
464
|
+
present = !!f.pr;
|
|
465
|
+
}
|
|
466
|
+
if (value === undefined || value === null)
|
|
467
|
+
continue;
|
|
468
|
+
encodeField(w, f, value, present);
|
|
469
|
+
}
|
|
470
|
+
return w.finish();
|
|
471
|
+
}
|
|
472
|
+
function encodeField(w, f, value, present) {
|
|
473
|
+
if (f.k === "map")
|
|
474
|
+
throw new Error("maps are not supported");
|
|
475
|
+
if (f.r) {
|
|
476
|
+
if (!Array.isArray(value))
|
|
477
|
+
throw new Error(`${f.n}: expected a list`);
|
|
478
|
+
if (NUMERIC_KINDS.has(f.k)) {
|
|
479
|
+
if (value.length === 0)
|
|
480
|
+
return;
|
|
481
|
+
const packed = new Writer();
|
|
482
|
+
for (const el of value)
|
|
483
|
+
writeNumeric(packed, f.k, el);
|
|
484
|
+
w.bytes(f.no, packed.finish());
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
for (const el of value) {
|
|
488
|
+
if (f.k === "message")
|
|
489
|
+
w.bytes(f.no, encodeMessage(f.t, el));
|
|
490
|
+
else
|
|
491
|
+
w.bytes(f.no, scalarBytes(f, el));
|
|
492
|
+
}
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
if (f.k === "message") {
|
|
496
|
+
w.bytes(f.no, encodeMessage(f.t, value));
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
if (f.k === "string" || f.k === "bytes") {
|
|
500
|
+
let bytes = scalarBytes(f, value);
|
|
501
|
+
if (f.sc === "dec" && value === "0")
|
|
502
|
+
bytes = new Uint8Array(); // rendered from an empty Dec
|
|
503
|
+
if (bytes.length > 0 || present)
|
|
504
|
+
w.bytes(f.no, bytes);
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
const n = numericValue(f.k, value);
|
|
508
|
+
if (n !== BigInt(0) || present) {
|
|
509
|
+
w.tag(f.no, FIXED32_KINDS.has(f.k) ? 5 : FIXED64_KINDS.has(f.k) ? 1 : 0);
|
|
510
|
+
writeNumeric(w, f.k, value);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
function scalarBytes(f, value) {
|
|
514
|
+
if (f.k === "bytes") {
|
|
515
|
+
if (f.sc === "int" || f.sc === "dec")
|
|
516
|
+
return utf8Encoder.encode(f.sc === "dec" ? legacyDecAtomics(value) : String(value));
|
|
517
|
+
return fromBase64(value);
|
|
518
|
+
}
|
|
519
|
+
if (f.sc === "dec")
|
|
520
|
+
return utf8Encoder.encode(value === "0" ? "" : legacyDecAtomics(value));
|
|
521
|
+
return utf8Encoder.encode(String(value));
|
|
522
|
+
}
|
|
523
|
+
function numericValue(kind, value) {
|
|
524
|
+
if (kind === "bool")
|
|
525
|
+
return value ? BigInt(1) : BigInt(0);
|
|
526
|
+
if (kind === "float" || kind === "double")
|
|
527
|
+
throw new Error(`amino JSON cannot encode a ${kind} field`);
|
|
528
|
+
return BigInt(value);
|
|
529
|
+
}
|
|
530
|
+
function writeNumeric(w, kind, value) {
|
|
531
|
+
const n = numericValue(kind, value);
|
|
532
|
+
switch (kind) {
|
|
533
|
+
case "sint32":
|
|
534
|
+
w.varint(zigzagEncode(n, 32));
|
|
535
|
+
return;
|
|
536
|
+
case "sint64":
|
|
537
|
+
w.varint(zigzagEncode(n, 64));
|
|
538
|
+
return;
|
|
539
|
+
case "fixed32":
|
|
540
|
+
case "sfixed32":
|
|
541
|
+
w.fixed(n, 4);
|
|
542
|
+
return;
|
|
543
|
+
case "fixed64":
|
|
544
|
+
case "sfixed64":
|
|
545
|
+
w.fixed(n, 8);
|
|
546
|
+
return;
|
|
547
|
+
default:
|
|
548
|
+
w.varint(n);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
function encodeAny(json) {
|
|
552
|
+
const type = json?.type;
|
|
553
|
+
if (!type)
|
|
554
|
+
throw new Error("Any: expected {type, value}");
|
|
555
|
+
const typeName = byAminoName.get(type) ?? (type.startsWith("/") && type.slice(1) in schema.messages ? type.slice(1) : undefined);
|
|
556
|
+
if (typeName)
|
|
557
|
+
return { typeUrl: `/${typeName}`, value: encodeMessage(typeName, json.value ?? {}) };
|
|
558
|
+
const cfg = getNestedAminoConfig();
|
|
559
|
+
if (!cfg)
|
|
560
|
+
throw new Error(`can't resolve amino type ${type}: call configureNestedAminoConverter first`);
|
|
561
|
+
const decoded = cfg.aminoTypes.fromAmino(json);
|
|
562
|
+
const codec = cfg.registry.lookupType(decoded.typeUrl);
|
|
563
|
+
if (!codec)
|
|
564
|
+
throw new Error(`No proto codec registered for inner type ${decoded.typeUrl}.`);
|
|
565
|
+
return { typeUrl: decoded.typeUrl, value: codec.encode(codec.fromPartial(decoded.value)).finish() };
|
|
566
|
+
}
|
|
567
|
+
// ------------------------------------------------------- non-nullable fill
|
|
568
|
+
/**
|
|
569
|
+
* Returns value with every dont_omitempty embedded message present (empty
|
|
570
|
+
* when left out), recursively. aminojson refuses to render an absent one, and
|
|
571
|
+
* Go clients never send one absent (they are gogoproto.nullable = false), but
|
|
572
|
+
* Telescope's fromPartial leaves them undefined.
|
|
573
|
+
* Filled on the plain value, before fromPartial, so the codec builds proper
|
|
574
|
+
* defaults; a Timestamp gets the epoch.
|
|
575
|
+
*/
|
|
576
|
+
export function fillNonNullable(typeName, value) {
|
|
577
|
+
const md = schema.messages[typeName];
|
|
578
|
+
if (!md || !value || typeof value !== "object")
|
|
579
|
+
return value;
|
|
580
|
+
const out = { ...value };
|
|
581
|
+
for (const f of md.f) {
|
|
582
|
+
if (f.k !== "message" || !f.j || !f.t)
|
|
583
|
+
continue;
|
|
584
|
+
const v = out[f.j];
|
|
585
|
+
if (f.r) {
|
|
586
|
+
if (Array.isArray(v) && !BUILTIN.has(f.t))
|
|
587
|
+
out[f.j] = v.map((el) => fillNonNullable(f.t, el));
|
|
588
|
+
continue;
|
|
589
|
+
}
|
|
590
|
+
if (v === undefined || v === null) {
|
|
591
|
+
// Only a dont_omitempty message must be present: aminojson refuses to
|
|
592
|
+
// render it absent. Others render the same either way, so stay untouched.
|
|
593
|
+
if (!f.d)
|
|
594
|
+
continue;
|
|
595
|
+
out[f.j] = f.t === "google.protobuf.Timestamp" ? new Date(0) : BUILTIN.has(f.t) ? {} : fillNonNullable(f.t, {});
|
|
596
|
+
continue;
|
|
597
|
+
}
|
|
598
|
+
if (!BUILTIN.has(f.t))
|
|
599
|
+
out[f.j] = fillNonNullable(f.t, v);
|
|
600
|
+
}
|
|
601
|
+
return out;
|
|
602
|
+
}
|
|
603
|
+
// --------------------------------------------------------- decode + prune
|
|
604
|
+
/**
|
|
605
|
+
* Telescope's decode fills every embedded message the bytes lack with a
|
|
606
|
+
* default (createBase): an empty Coin, which re-encodes as present, or
|
|
607
|
+
* `new Date()` for a Timestamp, which re-encodes as the current time. cosmjs
|
|
608
|
+
* builds the signed tx body by re-encoding fromAmino's result, so clear each
|
|
609
|
+
* embedded message the bytes did not carry, recursively: the body then
|
|
610
|
+
* encodes back to exactly these bytes.
|
|
611
|
+
*/
|
|
612
|
+
function pruneAbsent(typeName, bytes, value) {
|
|
613
|
+
const md = schema.messages[typeName];
|
|
614
|
+
if (!md || !value || typeof value !== "object")
|
|
615
|
+
return value;
|
|
616
|
+
const wire = parseFields(bytes);
|
|
617
|
+
for (const f of md.f) {
|
|
618
|
+
if (f.k !== "message" || !f.j || !f.t)
|
|
619
|
+
continue;
|
|
620
|
+
const values = wire.get(f.no) ?? [];
|
|
621
|
+
if (f.r) {
|
|
622
|
+
const list = value[f.j];
|
|
623
|
+
if (Array.isArray(list) && !BUILTIN.has(f.t)) {
|
|
624
|
+
value[f.j] = list.map((el, i) => (values[i] ? pruneAbsent(f.t, values[i].bytes, el) : el));
|
|
625
|
+
}
|
|
626
|
+
continue;
|
|
627
|
+
}
|
|
628
|
+
if (values.length === 0)
|
|
629
|
+
value[f.j] = undefined;
|
|
630
|
+
else if (!BUILTIN.has(f.t))
|
|
631
|
+
value[f.j] = pruneAbsent(f.t, concatBytes(values.map((v) => v.bytes)), value[f.j]);
|
|
632
|
+
}
|
|
633
|
+
return value;
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* The AminoConverter map for every Msg of a proto package
|
|
637
|
+
* ("sparkdream.<module>.v1"), given the module's generated tx codecs.
|
|
638
|
+
*/
|
|
639
|
+
export function chainAminoConverters(pkg, txModule) {
|
|
640
|
+
const out = {};
|
|
641
|
+
for (const typeName of schema.msgs) {
|
|
642
|
+
if (!typeName.startsWith(`${pkg}.`))
|
|
643
|
+
continue;
|
|
644
|
+
const aminoType = schema.messages[typeName]?.a;
|
|
645
|
+
const codec = txModule[typeName.slice(pkg.length + 1)];
|
|
646
|
+
if (!aminoType || !codec)
|
|
647
|
+
continue;
|
|
648
|
+
out[`/${typeName}`] = {
|
|
649
|
+
aminoType,
|
|
650
|
+
toAmino: (value) => {
|
|
651
|
+
const bytes = codec.encode(codec.fromPartial(fillNonNullable(typeName, value))).finish();
|
|
652
|
+
return render(typeName, bytes, false).value;
|
|
653
|
+
},
|
|
654
|
+
fromAmino: (value) => {
|
|
655
|
+
const bytes = encodeMessage(typeName, value ?? {});
|
|
656
|
+
return pruneAbsent(typeName, bytes, codec.decode(bytes));
|
|
657
|
+
},
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
return out;
|
|
661
|
+
}
|
|
662
|
+
/** Amino JSON ({type, value}) of any message the schema describes, rendered from its protobuf bytes. */
|
|
663
|
+
export function renderAminoJson(typeUrl, bytes) {
|
|
664
|
+
return render(typeUrl.replace(/^\//, ""), bytes, false);
|
|
665
|
+
}
|