@agoric/orchestration 0.1.1-dev-1af1596.0 → 0.1.1-dev-0ca4b57.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/orchestration",
3
- "version": "0.1.1-dev-1af1596.0+1af1596",
3
+ "version": "0.1.1-dev-0ca4b57.0+0ca4b57",
4
4
  "description": "Chain abstraction for Agoric's orchestration clients",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -33,19 +33,19 @@
33
33
  },
34
34
  "homepage": "https://github.com/Agoric/agoric-sdk#readme",
35
35
  "dependencies": {
36
- "@agoric/async-flow": "0.1.1-dev-1af1596.0+1af1596",
37
- "@agoric/cosmic-proto": "0.4.1-dev-1af1596.0+1af1596",
38
- "@agoric/ertp": "0.16.3-dev-1af1596.0+1af1596",
39
- "@agoric/internal": "0.3.3-dev-1af1596.0+1af1596",
40
- "@agoric/network": "0.1.1-dev-1af1596.0+1af1596",
41
- "@agoric/notifier": "0.6.3-dev-1af1596.0+1af1596",
42
- "@agoric/store": "0.9.3-dev-1af1596.0+1af1596",
43
- "@agoric/time": "0.3.3-dev-1af1596.0+1af1596",
44
- "@agoric/vat-data": "0.5.3-dev-1af1596.0+1af1596",
45
- "@agoric/vats": "0.15.2-dev-1af1596.0+1af1596",
46
- "@agoric/vow": "0.1.1-dev-1af1596.0+1af1596",
47
- "@agoric/zoe": "0.26.3-dev-1af1596.0+1af1596",
48
- "@agoric/zone": "0.2.3-dev-1af1596.0+1af1596",
36
+ "@agoric/async-flow": "0.1.1-dev-0ca4b57.0+0ca4b57",
37
+ "@agoric/cosmic-proto": "0.4.1-dev-0ca4b57.0+0ca4b57",
38
+ "@agoric/ertp": "0.16.3-dev-0ca4b57.0+0ca4b57",
39
+ "@agoric/internal": "0.3.3-dev-0ca4b57.0+0ca4b57",
40
+ "@agoric/network": "0.1.1-dev-0ca4b57.0+0ca4b57",
41
+ "@agoric/notifier": "0.6.3-dev-0ca4b57.0+0ca4b57",
42
+ "@agoric/store": "0.9.3-dev-0ca4b57.0+0ca4b57",
43
+ "@agoric/time": "0.3.3-dev-0ca4b57.0+0ca4b57",
44
+ "@agoric/vat-data": "0.5.3-dev-0ca4b57.0+0ca4b57",
45
+ "@agoric/vats": "0.15.2-dev-0ca4b57.0+0ca4b57",
46
+ "@agoric/vow": "0.1.1-dev-0ca4b57.0+0ca4b57",
47
+ "@agoric/zoe": "0.26.3-dev-0ca4b57.0+0ca4b57",
48
+ "@agoric/zone": "0.2.3-dev-0ca4b57.0+0ca4b57",
49
49
  "@endo/base64": "^1.0.9",
50
50
  "@endo/errors": "^1.2.9",
51
51
  "@endo/far": "^1.1.10",
@@ -54,7 +54,7 @@
54
54
  "@noble/hashes": "^1.5.0"
55
55
  },
56
56
  "devDependencies": {
57
- "@agoric/swingset-liveslots": "0.10.3-dev-1af1596.0+1af1596",
57
+ "@agoric/swingset-liveslots": "0.10.3-dev-0ca4b57.0+0ca4b57",
58
58
  "@chain-registry/client": "^1.47.4",
59
59
  "@cosmjs/amino": "^0.32.3",
60
60
  "@cosmjs/proto-signing": "^0.32.3",
@@ -88,7 +88,8 @@
88
88
  "files": [
89
89
  "*.js",
90
90
  "*.ts",
91
- "src"
91
+ "src",
92
+ "tools"
92
93
  ],
93
94
  "publishConfig": {
94
95
  "access": "public"
@@ -96,5 +97,5 @@
96
97
  "typeCoverage": {
97
98
  "atLeast": 97.77
98
99
  },
99
- "gitHead": "1af1596ffa4d14c089c231825fbe5729be4b3ce3"
100
+ "gitHead": "0ca4b5765e8afd14987ff909e6bd4d5d1c453c18"
100
101
  }
@@ -0,0 +1,116 @@
1
+ /** @file Tools to support making IBC mocks */
2
+ import { type JsonSafe } from '@agoric/cosmic-proto';
3
+ import { TxBody } from '@agoric/cosmic-proto/cosmos/tx/v1beta1/tx.js';
4
+ import { Any } from '@agoric/cosmic-proto/google/protobuf/any.js';
5
+ import type { PacketSDKType } from '@agoric/cosmic-proto/ibc/core/channel/v1/channel.js';
6
+ import { RequestQuery, ResponseQuery } from '@agoric/cosmic-proto/tendermint/abci/types.js';
7
+ import type { IBCChannelID, IBCEvent, VTransferIBCEvent } from '@agoric/vats';
8
+ import type { ChainAddress } from '../src/orchestration-api.js';
9
+ interface EncoderCommon<T> {
10
+ encode: (message: T) => {
11
+ finish: () => Uint8Array;
12
+ };
13
+ fromPartial: (partial: Partial<T>) => T;
14
+ typeUrl: string;
15
+ }
16
+ /**
17
+ * Build a response "packet bytes string" we'd expect to see from a Msg
18
+ * Response
19
+ *
20
+ * XXX support multiple responses in a single message
21
+ *
22
+ * @param Encoder
23
+ * @param message
24
+ */
25
+ export declare function buildMsgResponseString<T>(Encoder: EncoderCommon<T>, message: Partial<T>): string;
26
+ /**
27
+ * Build an example error packet for a failed Tx Msg
28
+ * @param msg
29
+ */
30
+ export declare function buildMsgErrorString(msg?: string): string;
31
+ /**
32
+ * Build a response "packet bytes string" we'd expect to see from a Query
33
+ * request
34
+ *
35
+ * XXX accept multiple queries at once
36
+ *
37
+ * @param Encoder
38
+ * @param query
39
+ * @param opts
40
+ */
41
+ export declare function buildQueryResponseString<T>(Encoder: EncoderCommon<T>, query: Partial<T>, opts?: Omit<ResponseQuery, 'key'>): string;
42
+ /**
43
+ * Build a tx packet string for the mocked dibc bridge handler
44
+ * @param msgs
45
+ * @returns {string}
46
+ */
47
+ export declare function buildTxPacketString(msgs: {
48
+ value: Uint8Array;
49
+ typeUrl: string;
50
+ }[]): string;
51
+ /**
52
+ * Parse an outgoing ica tx packet. Useful for testing when inspecting
53
+ * outgoing dibc bridge messages.
54
+ *
55
+ * @param b64 base64 encoded string
56
+ */
57
+ export declare const parseOutgoingTxPacket: (b64: string) => TxBody;
58
+ /**
59
+ * Build a query packet string for the mocked dibc bridge handler
60
+ * @param msgs
61
+ * @param opts
62
+ * @returns {string}
63
+ */
64
+ export declare function buildQueryPacketString(msgs: Any[], opts?: Partial<Omit<RequestQuery, 'path' | 'data'>>): string;
65
+ type BuildVTransferEventParams = {
66
+ event?: VTransferIBCEvent['event'];
67
+ sender?: ChainAddress['value'];
68
+ receiver?: ChainAddress['value'];
69
+ target?: ChainAddress['value'];
70
+ amount?: bigint;
71
+ denom?: string;
72
+ destinationChannel?: IBCChannelID;
73
+ sourceChannel?: IBCChannelID;
74
+ sequence?: PacketSDKType['sequence'] | JsonSafe<PacketSDKType['sequence']>;
75
+ };
76
+ /**
77
+ * `buildVTransferEvent` can be used with `transferBridge` to simulate incoming
78
+ * and outgoing IBC fungible tokens transfers to a LocalChain account.
79
+ *
80
+ * It defaults to simulating incoming transfers. To simulate an outgoing one,
81
+ * ensure `sender=agoric1fakeLCAAddress` and this after LocalChainBridge
82
+ * receives the outgoing MsgTransfer,
83
+ *
84
+ * @example
85
+ * ```js
86
+ * const { mocks: { transferBridge } = await commonSetup(t);
87
+ * await E(transferBridge).fromBridge(
88
+ * buildVTransferEvent({
89
+ * receiver: 'agoric1fakeLCAAddress',
90
+ * amount: 10n,
91
+ * denom: 'uatom',
92
+ * }),
93
+ * );
94
+ * ```
95
+ *
96
+ * XXX integrate vlocalchain and vtransfer ScopedBridgeManagers
97
+ * in test supports.
98
+ *
99
+ * @param {{BuildVTransferEventParams}} args
100
+ */
101
+ export declare const buildVTransferEvent: ({ event, sender, receiver, target, amount, denom, destinationChannel, sourceChannel, sequence, }?: BuildVTransferEventParams) => VTransferIBCEvent;
102
+ export declare function createMockAckMap(mockMap: Record<string, {
103
+ msg: string;
104
+ ack: string;
105
+ }>): {};
106
+ /**
107
+ * Simulate an IBC channelCloseConfirm event. This can be used to simulate an
108
+ * ICA channel closing for an unexpected reason from a remote chain, _or
109
+ * anything besides the Connection holder calling `.close()`_. If `close()` is
110
+ * called, we'd instead expect to see a Downcall for channelCloseInit.
111
+ *
112
+ * @param {Pick<IBCEvent<'channelCloseConfirm'>, 'portID' | 'channelID'>} event
113
+ */
114
+ export declare const buildChannelCloseConfirmEvent: ({ channelID, portID, }?: Partial<IBCEvent<"channelCloseConfirm">>) => Partial<IBCEvent<"channelCloseConfirm">>;
115
+ export {};
116
+ //# sourceMappingURL=ibc-mocks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ibc-mocks.d.ts","sourceRoot":"","sources":["ibc-mocks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,262 @@
1
+ /** @file Tools to support making IBC mocks */
2
+ import { type JsonSafe, toRequestQueryJson } from '@agoric/cosmic-proto';
3
+ import { TxBody } from '@agoric/cosmic-proto/cosmos/tx/v1beta1/tx.js';
4
+ import { Any } from '@agoric/cosmic-proto/google/protobuf/any.js';
5
+ import { FungibleTokenPacketData } from '@agoric/cosmic-proto/ibc/applications/transfer/v2/packet.js';
6
+ import type { PacketSDKType } from '@agoric/cosmic-proto/ibc/core/channel/v1/channel.js';
7
+ import { CosmosResponse } from '@agoric/cosmic-proto/icq/v1/packet.js';
8
+ import {
9
+ RequestQuery,
10
+ ResponseQuery,
11
+ } from '@agoric/cosmic-proto/tendermint/abci/types.js';
12
+ import {
13
+ IBC_EVENT,
14
+ VTRANSFER_IBC_EVENT,
15
+ } from '@agoric/internal/src/action-types.js';
16
+ import type {
17
+ IBCChannelID,
18
+ IBCEvent,
19
+ IBCPacket,
20
+ VTransferIBCEvent,
21
+ } from '@agoric/vats';
22
+ import { LOCALCHAIN_DEFAULT_ADDRESS } from '@agoric/vats/tools/fake-bridge.js';
23
+ import { atob, btoa, decodeBase64, encodeBase64 } from '@endo/base64';
24
+ import type { ChainAddress } from '../src/orchestration-api.js';
25
+ import { makeQueryPacket, makeTxPacket } from '../src/utils/packet.js';
26
+
27
+ interface EncoderCommon<T> {
28
+ encode: (message: T) => {
29
+ finish: () => Uint8Array;
30
+ };
31
+ fromPartial: (partial: Partial<T>) => T;
32
+ typeUrl: string;
33
+ }
34
+
35
+ const toPacket = (obj: Record<string, any>): string =>
36
+ btoa(JSON.stringify(obj));
37
+
38
+ /**
39
+ * Build a response "packet bytes string" we'd expect to see from a Msg
40
+ * Response
41
+ *
42
+ * XXX support multiple responses in a single message
43
+ *
44
+ * @param Encoder
45
+ * @param message
46
+ */
47
+ export function buildMsgResponseString<T>(
48
+ Encoder: EncoderCommon<T>,
49
+ message: Partial<T>,
50
+ ): string {
51
+ const encodedMsg = Encoder.encode(Encoder.fromPartial(message)).finish();
52
+
53
+ // cosmos-sdk double Any encodes
54
+ const encodedAny = Any.encode(
55
+ Any.fromPartial({
56
+ value: Any.encode(
57
+ Any.fromPartial({
58
+ typeUrl: Encoder.typeUrl,
59
+ value: encodedMsg,
60
+ }),
61
+ ).finish(),
62
+ }),
63
+ ).finish();
64
+
65
+ return toPacket({
66
+ result: encodeBase64(encodedAny),
67
+ });
68
+ }
69
+
70
+ /**
71
+ * Build an example error packet for a failed Tx Msg
72
+ * @param msg
73
+ */
74
+ export function buildMsgErrorString(
75
+ msg = 'ABCI code: 5: error handling packet: see events for details',
76
+ ): string {
77
+ return toPacket({
78
+ error: msg,
79
+ });
80
+ }
81
+
82
+ /**
83
+ * Build a response "packet bytes string" we'd expect to see from a Query
84
+ * request
85
+ *
86
+ * XXX accept multiple queries at once
87
+ *
88
+ * @param Encoder
89
+ * @param query
90
+ * @param opts
91
+ */
92
+ export function buildQueryResponseString<T>(
93
+ Encoder: EncoderCommon<T>,
94
+ query: Partial<T>,
95
+ opts: Omit<ResponseQuery, 'key'> = {
96
+ value: new Uint8Array(),
97
+ height: 0n,
98
+ index: 0n,
99
+ code: 0,
100
+ log: '',
101
+ info: '',
102
+ codespace: '',
103
+ },
104
+ ): string {
105
+ const encodedResp = CosmosResponse.encode(
106
+ CosmosResponse.fromPartial({
107
+ responses: [
108
+ {
109
+ key: Encoder.encode(Encoder.fromPartial(query)).finish(),
110
+ ...opts,
111
+ },
112
+ ],
113
+ }),
114
+ ).finish();
115
+
116
+ return toPacket({
117
+ result: toPacket({ data: encodeBase64(encodedResp) }),
118
+ });
119
+ }
120
+
121
+ /**
122
+ * Build a tx packet string for the mocked dibc bridge handler
123
+ * @param msgs
124
+ * @returns {string}
125
+ */
126
+ export function buildTxPacketString(
127
+ msgs: { value: Uint8Array; typeUrl: string }[],
128
+ ): string {
129
+ return btoa(makeTxPacket(msgs.map(Any.toJSON)));
130
+ }
131
+
132
+ /**
133
+ * Parse an outgoing ica tx packet. Useful for testing when inspecting
134
+ * outgoing dibc bridge messages.
135
+ *
136
+ * @param b64 base64 encoded string
137
+ */
138
+ export const parseOutgoingTxPacket = (b64: string) => {
139
+ return TxBody.decode(decodeBase64(JSON.parse(atob(b64)).data));
140
+ };
141
+
142
+ /**
143
+ * Build a query packet string for the mocked dibc bridge handler
144
+ * @param msgs
145
+ * @param opts
146
+ * @returns {string}
147
+ */
148
+ export function buildQueryPacketString(
149
+ msgs: Any[],
150
+ opts: Partial<Omit<RequestQuery, 'path' | 'data'>> = {},
151
+ ): string {
152
+ return btoa(makeQueryPacket(msgs.map(msg => toRequestQueryJson(msg, opts))));
153
+ }
154
+
155
+ type BuildVTransferEventParams = {
156
+ event?: VTransferIBCEvent['event'];
157
+ /* defaults to cosmos1AccAddress. set to `agoric1fakeLCAAddress` to simulate an outgoing transfer event */
158
+ sender?: ChainAddress['value'];
159
+ /* defaults to agoric1fakeLCAAddress. set to a different value to simulate an outgoing transfer event */
160
+ receiver?: ChainAddress['value'];
161
+ target?: ChainAddress['value'];
162
+ amount?: bigint;
163
+ denom?: string;
164
+ destinationChannel?: IBCChannelID;
165
+ sourceChannel?: IBCChannelID;
166
+ /* support bigint and string, to facilitate bootstrap testing */
167
+ sequence?: PacketSDKType['sequence'] | JsonSafe<PacketSDKType['sequence']>;
168
+ };
169
+
170
+ /**
171
+ * `buildVTransferEvent` can be used with `transferBridge` to simulate incoming
172
+ * and outgoing IBC fungible tokens transfers to a LocalChain account.
173
+ *
174
+ * It defaults to simulating incoming transfers. To simulate an outgoing one,
175
+ * ensure `sender=agoric1fakeLCAAddress` and this after LocalChainBridge
176
+ * receives the outgoing MsgTransfer,
177
+ *
178
+ * @example
179
+ * ```js
180
+ * const { mocks: { transferBridge } = await commonSetup(t);
181
+ * await E(transferBridge).fromBridge(
182
+ * buildVTransferEvent({
183
+ * receiver: 'agoric1fakeLCAAddress',
184
+ * amount: 10n,
185
+ * denom: 'uatom',
186
+ * }),
187
+ * );
188
+ * ```
189
+ *
190
+ * XXX integrate vlocalchain and vtransfer ScopedBridgeManagers
191
+ * in test supports.
192
+ *
193
+ * @param {{BuildVTransferEventParams}} args
194
+ */
195
+ export const buildVTransferEvent = ({
196
+ event = 'acknowledgementPacket' as const,
197
+ sender = 'cosmos1AccAddress',
198
+ receiver = LOCALCHAIN_DEFAULT_ADDRESS,
199
+ target = LOCALCHAIN_DEFAULT_ADDRESS,
200
+ amount = 10n,
201
+ denom = 'uatom',
202
+ destinationChannel = 'channel-0' as IBCChannelID,
203
+ sourceChannel = 'channel-405' as IBCChannelID,
204
+ sequence = 0n,
205
+ }: BuildVTransferEventParams = {}): VTransferIBCEvent => ({
206
+ type: VTRANSFER_IBC_EVENT,
207
+ blockHeight: 0,
208
+ blockTime: 0,
209
+ event,
210
+ acknowledgement: btoa(JSON.stringify({ result: 'AQ==' })),
211
+ relayer: 'agoric123',
212
+ target,
213
+ packet: {
214
+ data: btoa(
215
+ JSON.stringify(
216
+ FungibleTokenPacketData.fromPartial({
217
+ amount: String(amount),
218
+ denom,
219
+ sender,
220
+ receiver,
221
+ }),
222
+ ),
223
+ ),
224
+ destination_channel: destinationChannel,
225
+ source_channel: sourceChannel,
226
+ destination_port: 'transfer',
227
+ source_port: 'transfer',
228
+ sequence,
229
+ } as IBCPacket,
230
+ });
231
+
232
+ export function createMockAckMap(
233
+ mockMap: Record<string, { msg: string; ack: string }>,
234
+ ) {
235
+ const res = Object.values(mockMap).reduce((acc, { msg, ack }) => {
236
+ acc[msg] = ack;
237
+ return acc;
238
+ }, {});
239
+ return res;
240
+ }
241
+
242
+ /**
243
+ * Simulate an IBC channelCloseConfirm event. This can be used to simulate an
244
+ * ICA channel closing for an unexpected reason from a remote chain, _or
245
+ * anything besides the Connection holder calling `.close()`_. If `close()` is
246
+ * called, we'd instead expect to see a Downcall for channelCloseInit.
247
+ *
248
+ * @param {Pick<IBCEvent<'channelCloseConfirm'>, 'portID' | 'channelID'>} event
249
+ */
250
+ export const buildChannelCloseConfirmEvent = ({
251
+ channelID = 'channel-0',
252
+ portID = 'icacontroller-1',
253
+ }: Partial<IBCEvent<'channelCloseConfirm'>> = {}): Partial<
254
+ IBCEvent<'channelCloseConfirm'>
255
+ > => ({
256
+ blockHeight: 0,
257
+ blockTime: 0,
258
+ channelID,
259
+ event: 'channelCloseConfirm',
260
+ portID,
261
+ type: IBC_EVENT,
262
+ });
@@ -0,0 +1,2 @@
1
+ export function makeTestAddress(index?: number, prefix?: string, byteLength?: number): string;
2
+ //# sourceMappingURL=make-test-address.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"make-test-address.d.ts","sourceRoot":"","sources":["make-test-address.js"],"names":[],"mappings":"AASO,wCALI,MAAM,WACN,MAAM,eACN,MAAM,GACJ,MAAM,CAalB"}
@@ -0,0 +1,21 @@
1
+ // eslint-disable-next-line import/no-extraneous-dependencies
2
+ import { bech32 } from 'bech32';
3
+
4
+ /**
5
+ * @param {number} index
6
+ * @param {string} prefix
7
+ * @param {number} byteLength
8
+ * @returns {string} a mock bech32 address for tests
9
+ */
10
+ export const makeTestAddress = (
11
+ index = 0,
12
+ prefix = 'agoric',
13
+ byteLength = 20,
14
+ ) => {
15
+ // create a simple 20-byte array (common address length)
16
+ const bytes = new Uint8Array(byteLength).fill(0);
17
+ // if index provided, put it in the first byte
18
+ if (index !== 0) bytes[0] = Number(index);
19
+ const words = bech32.toWords(bytes);
20
+ return bech32.encode(prefix, words);
21
+ };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Decodes a protobuf message from the given buffer.
3
+ *
4
+ * @param {Buffer} buffer
5
+ */
6
+ export function decodeProtobuf(buffer: Buffer): {
7
+ value: {};
8
+ bytesRead: number;
9
+ };
10
+ /**
11
+ * Decodes a protobuf message from the given base64-encoded data.
12
+ *
13
+ * @param {string} base64String
14
+ */
15
+ export function decodeProtobufBase64(base64String: string): {
16
+ value: {};
17
+ bytesRead: number;
18
+ };
19
+ //# sourceMappingURL=protobuf-decoder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protobuf-decoder.d.ts","sourceRoot":"","sources":["protobuf-decoder.js"],"names":[],"mappings":"AA8HA;;;;GAIG;AACH,uCAFW,MAAM;;;EAchB;AACD;;;;GAIG;AACH,mDAFW,MAAM;;;EAKhB"}
@@ -0,0 +1,153 @@
1
+ /* eslint-env node */
2
+ /* eslint-disable -- generated by Sonnet, easier to leave alone */
3
+
4
+ const WIRE_TYPES = {
5
+ VARINT: 0,
6
+ FIXED64: 1,
7
+ LENGTH_DELIMITED: 2,
8
+ START_GROUP: 3,
9
+ END_GROUP: 4,
10
+ FIXED32: 5,
11
+ };
12
+
13
+ function decodeVarint(buffer, offset) {
14
+ let result = 0n;
15
+ let shift = 0;
16
+ let byte;
17
+
18
+ do {
19
+ if (offset >= buffer.length) {
20
+ throw new Error('Buffer overflow while decoding varint');
21
+ }
22
+ byte = buffer[offset];
23
+ result |= BigInt(byte & 0x7f) << BigInt(shift);
24
+ shift += 7;
25
+ offset++;
26
+ } while (byte & 0x80);
27
+
28
+ return { value: result, bytesRead: shift / 7 };
29
+ }
30
+
31
+ function decodeFixed32(buffer, offset) {
32
+ if (offset + 4 > buffer.length) {
33
+ throw new Error('Buffer overflow while decoding fixed32');
34
+ }
35
+ return {
36
+ value: buffer.readUInt32LE(offset),
37
+ bytesRead: 4,
38
+ };
39
+ }
40
+
41
+ function decodeFixed64(buffer, offset) {
42
+ if (offset + 8 > buffer.length) {
43
+ throw new Error('Buffer overflow while decoding fixed64');
44
+ }
45
+ const low = buffer.readUInt32LE(offset);
46
+ const high = buffer.readUInt32LE(offset + 4);
47
+ return {
48
+ value: BigInt(high) * 2n ** 32n + BigInt(low),
49
+ bytesRead: 8,
50
+ };
51
+ }
52
+
53
+ function decodeString(buffer, offset, length) {
54
+ if (offset + length > buffer.length) {
55
+ throw new Error('Buffer overflow while decoding string');
56
+ }
57
+ return {
58
+ value: buffer.toString('utf8', offset, offset + length),
59
+ bytesRead: length,
60
+ };
61
+ }
62
+
63
+ function decodeField(buffer, offset) {
64
+ const tag = decodeVarint(buffer, offset);
65
+ offset += tag.bytesRead;
66
+
67
+ const fieldNumber = Number(tag.value >> 3n);
68
+ const wireType = Number(tag.value & 0x7n);
69
+
70
+ let value;
71
+ let bytesRead;
72
+
73
+ switch (wireType) {
74
+ case WIRE_TYPES.VARINT:
75
+ ({ value, bytesRead } = decodeVarint(buffer, offset));
76
+ break;
77
+ case WIRE_TYPES.FIXED64:
78
+ ({ value, bytesRead } = decodeFixed64(buffer, offset));
79
+ break;
80
+ case WIRE_TYPES.LENGTH_DELIMITED:
81
+ const length = decodeVarint(buffer, offset);
82
+ offset += length.bytesRead;
83
+ // Try to decode as a nested message first
84
+ try {
85
+ ({ value, bytesRead } = decodeProtobuf(
86
+ buffer.slice(offset, offset + Number(length.value)),
87
+ ));
88
+ } catch (e) {
89
+ // If it fails, decode as a string
90
+ ({ value, bytesRead } = decodeString(
91
+ buffer,
92
+ offset,
93
+ Number(length.value),
94
+ ));
95
+ }
96
+ bytesRead += length.bytesRead;
97
+ break;
98
+ case WIRE_TYPES.FIXED32:
99
+ ({ value, bytesRead } = decodeFixed32(buffer, offset));
100
+ break;
101
+ default:
102
+ throw new Error(`Unsupported wire type: ${wireType}`);
103
+ }
104
+
105
+ return {
106
+ fieldNumber,
107
+ wireType,
108
+ value,
109
+ bytesRead: tag.bytesRead + bytesRead,
110
+ };
111
+ }
112
+
113
+ function getFieldName(fieldNumber, wireType) {
114
+ const typePrefix =
115
+ wireType === WIRE_TYPES.LENGTH_DELIMITED
116
+ ? 'subMessage'
117
+ : wireType === WIRE_TYPES.VARINT
118
+ ? 'int'
119
+ : wireType === WIRE_TYPES.FIXED32
120
+ ? 'fixed32'
121
+ : wireType === WIRE_TYPES.FIXED64
122
+ ? 'fixed64'
123
+ : 'string';
124
+ return `${typePrefix}_${fieldNumber}`;
125
+ }
126
+
127
+ /**
128
+ * Decodes a protobuf message from the given buffer.
129
+ *
130
+ * @param {Buffer} buffer
131
+ */
132
+ export function decodeProtobuf(buffer) {
133
+ let offset = 0;
134
+ const message = {};
135
+
136
+ while (offset < buffer.length) {
137
+ const field = decodeField(buffer, offset);
138
+ const fieldName = getFieldName(field.fieldNumber, field.wireType);
139
+ message[fieldName] = field.value;
140
+ offset += field.bytesRead;
141
+ }
142
+
143
+ return { value: message, bytesRead: offset };
144
+ }
145
+ /**
146
+ * Decodes a protobuf message from the given base64-encoded data.
147
+ *
148
+ * @param {string} base64String
149
+ */
150
+ export function decodeProtobufBase64(base64String) {
151
+ const buffer = Buffer.from(base64String, 'base64');
152
+ return decodeProtobuf(buffer);
153
+ }